9

I'm designing a Web API with the usual CRUD operations on a Person entity.

The problem is that I don't know how to design the DTOs.

The entity is as follows:

public class Person 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

I have determined that the DTO should have the very same members:

public class PersonDto 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age{ get; set; }
}

That makes sense for the Update operation, but what about Create? The Id is create by the Create operation ifself, so having an Id in the DTO doesn't fit the semantics.

Should I create 2 different DTOs, one with Id and another without Id?

What's the best option? Do you have different DTOs for Create and Update?

SuperJMN
  • 10,206
  • 9
  • 66
  • 144
  • 4
    DTOs are an example of mass psychosis. Use command/response pattern instead and the problem goes away – MickyD Sep 06 '17 at 10:41
  • Could you please include some example or link to learn about the pattern? The keywords are too broad and searching for it returned a lot of results that are a bit misleading :) Thanks – SuperJMN Sep 06 '17 at 10:45
  • [Don't use DTOs problem solved.](https://stackoverflow.com/questions/1440952/why-are-data-transfer-objects-dtos-an-anti-pattern) *This duplication has a huge cost, so the architecture needs to get a huge benefit from this separation to be worth it.* I see literally no benefit to your DTO, it's identical to the other object, so why are you using it? – Liam Sep 06 '17 at 10:45
  • You already have the entity, why duplicate it to another object? Most, if not all design patterns may become anti patterns when they are abused. DTO is no exception. I remember the first time I saw an MVVM sample code for a login window. this simple everyday example that I used to write in a single class suddenly became a 5 classes beast. IMHO, the most important thing to remember when writing code is KISS. – Zohar Peled Sep 06 '17 at 10:51
  • @Liam what's the alternative way? If I want to send the data of an entity I want to create in my Web API, I need to wrap all the data into a type (the DTO). The, do you mean that you don't use DTOs or that you use the same DTO for every operation in CRUD? – SuperJMN Sep 06 '17 at 10:52
  • 1
    Simply use your entity directly.... – Zohar Peled Sep 06 '17 at 11:15
  • @ZoharPeled Using the entity directly: Every change to your entity, will break the rest api contract and every application which uses your rest service. You can't version it. When using EF Core, you will have navigation properties there which may even cause circular dependency (Customer having Navigation Property to Order and order having navigation property to customer, trying to serialize this will result in exception or seemingly "unreferenced" navigation property (if JSON.NET is set to stop when it detects a circular reference – SuperJMN Sep 06 '17 at 20:05
  • @SuperJMN as I said - KISS. write simple code and it will be easy to maintain. over using architectures and design patterns is abusing them. With all do respect to the gang of four, sometimes even a design pattern that have been used widely and successfully might not be the correct tool for the job at hand. Loose coupling is not always the best architecture. – Zohar Peled Sep 06 '17 at 20:11
  • I agree, but in the case I mentioned above, it seems that using model entities directly would cause side effects. Would you still use them even it the entities have methods? Or navigation properties? – SuperJMN Sep 06 '17 at 20:20

2 Answers2

3

You can use either ways. If you use separate DTO per operation - it's a lot of code writing (and time spending). I prefer to use one DTO for all operations and create additional if needed.

Alex Zaitsev
  • 1,682
  • 3
  • 13
  • 21
1

You do not need another DTO for create operation. You just set the default value(id=0) for creating a new object. This will help you for figuring out if the object is yet to be created in database in case you have to. Though, if you are passing your DTO with ID zero to methods meant for create operation, you would never face any problem.

tech-y
  • 1,451
  • 2
  • 12
  • 25
  • 2
    OK, that sounds good enough. However, I find quite misleading that my Web API's Create operation is accepting an Id, although it will be ignored. For instance, I'm using Swagger right now, and in the Example value for the Create operation it shows { "Id": 0, "Name" = "string", "Age" = 0 } where it should only show Name and Age. – SuperJMN Sep 06 '17 at 13:54
  • For a web api request, you don't have to send an ID with it. You should send only {"Name" = "string", "Age" = 0}. In C#, 0 will be assigned by default. This should not bother you as 0 is not a valid ID anyway. – tech-y Sep 06 '17 at 14:22
  • For a web api request, you don't have to send an ID with it. You should send only {"Name" = "string", "Age" = 0}. In C#, 0 will be assigned by default. This should not bother you as 0 is not a valid ID anyway. – tech-y Sep 06 '17 at 14:22
  • I think that's clear enough, but regarding the consumers of my API, I see this problem => please check it, since it's a new question: https://stackoverflow.com/questions/46077652/making-swagger-ignore-a-property – SuperJMN Sep 06 '17 at 14:29