DTO Organization in vNext API's

So lets face it, projects are getting more complicated, with more and more objects to keep track of.  If you follow any type of agile process you're often creating an object per operation with the hopes that your technical debt will allow you to reactor the dupes later.  If you're following a DRY principle or a seperation of concerns it can open add layers of abstraction that confuse your object graph even more.

I've faced this often in my projects, especially API projects.  I was recently working on a prototype project using ASP.NET vNext (MVC 6) where Controllers for API and MVC Views are all first class now and share a base class, this makes Object DTO's a little blurry.  In this project I've also incorporated Entity Framework 7, so all of my "model" classes are my true authority to my backing persistance layer.

Models
Data
Foo.cs
Bar.cs
Widget.cs
ViewModel
FooView.cs
BarView.cs
Widget.cs
ApiModel
FooPost.cs
FooPut.cs
FooDelete.cs
Bar..
...etc

So you get the point above.  You can imagine what it's like to go back and add a required property later and have to go find every dependant view model and update it to add that property.

While I dont think this is revolutionary by any means, I think we often forget about sub classing objects to allow inheritance to work, and organization to naturally flow.

 public class ForumSection
    {
        [Key]
        public int ForumSectionId { get; set; }
        public string SectionName { get; set; }

        //Navigation Properties
        public List<ForumGroup> ForumGroups { get; set; }

        // API Models
        public class CreateModel
        {
            public string SectionName { get; set; }
        }
        public class UpdateModel
        {
            public int ForumSectionId { get; set; }
            public string SectionName { get; set; }
        }
        public class DeleteModel
        {
            public int ForumSectionId { get; set; }
        }
    }

Here's a real world object that I'm building, and using SubClassing to store the relevant view models,  This also makes it extreemly clear inside the API model binding what I'm trying to accomplish.

 // GET: api/values
        [HttpGet]
        public IEnumerable<ForumSection> Get()
        {
            return _context.ForumSections;
        }
        // GET api/values/5
        [HttpGet("{id}")]
        public ForumSection Get(int id)
        {
            return _context.ForumSections.Find(id);
        }
        // POST api/values
        [HttpPost]
        public void Post([FromBody]ForumSection.CreateModel value)
        {
...//TODO: DO YOUR CLASS WORK HERE
}


I'd be interested in feedback on this, it's kind of a new concept I'm attempting to make inclusion or removal updates much more clear across related but not coupled types.

3 Comments

  • Ahhhhh... I've never been a fan of tightly-coupling protocol-specific nomenclature in with the code constructs. The design should be independent from implementation. Do you create your database properties with IdGuid or NameString? When I see "Http" in any class name/member that is what I think.

    No one has really challenged this, and has really seemed to have "gone with the flow" and embraced this new tech/toy without much thought. But that's just my perspective. :D

  • I don't mind longer file names, so my view models for the API are named like this:

    GET /accounts - AccountIndexResponseResource

    GET /accounts/{id} - AccoundShowResponseResource

    POST /account - AccountCreateRequestResource, AccountCreateResponseResource, AccountUpdateRequestResource, AccountUpdateResponseResource

    Using such notation I can use different types to represent request and response resources.

  • Hi Bryan,

    I donated $700 to the Rebirth Vanilla project. I would like my money refunded. I would also love to know why you would scam/steal 13k from all those people? Just because you could? or were you broke? Is there a good reason? Please email me or answer here.

Comments have been disabled for this content.