Microservices Restful API - DTOs or not?

so-random-dude :

REST API - DTOs or not?

I would like to re-ask this question in Microservices' context. Here is the quote from original question.

I am currently creating a REST-API for a project and have been reading article upon article about best practices. Many seem to be against DTOs and simply just expose the domain model, while others seem to think DTOs (or User Models or whatever you want to call it) are bad practice. Personally, I thought that this article made a lot of sense.

However, I also understand the drawbacks of DTOs with all the extra mapping code, domain models that might be 100% identical to their DTO-counterpart and so on.

Now, My question

I am more aligned towards using one Object through all the layers of my application (In other words, just expose Domain Object rather than creating DTO and manually copying over each fields). And the differences in my contract vs code can be addressed using Jackson annotations like @JsonIgnore or @JsonProperty(access = Access.WRITE_ONLY) or @JsonView etc). Or if there is one or two fields that needs a transformation which cannot be done using Jackson Annotation, then I will write custom logic to handle just that (Trust me, I haven't come across this scenario not even once in my 5+ years long journey in Rest services)

I would like to know if I am missing any real bad effects for not copying the Domain to DTO

so-random-dude :

The Pros of Just exposing Domain Objects

  1. The less code you write, the less bugs you produce.
    • despite of having extensive (arguable) test cases in our code base, I have came across bugs due to missed/wrong copying of fields from domain to DTO or viceversa.
  2. Maintainability - Less boiler plate code.
    • If I have to add a new attribute, I don't have to add in Domain, DTO, Mapper and the testcases, of course. Don't tell me that this can be achieved using a reflection beanCopy utils, it defeats the whole purpose.
    • Lombok, Groovy, Kotlin I know, but it will save me only getter setter headache.
  3. DRY
  4. Performance
    • I know this falls under the category of "premature performance optimization is the root of all evil". But still this will save some CPU cycles for not having to create (and later garbage collect) one more Object (at the very least) per request

Cons

  1. DTOs will give you more flexibility in the long run
    • If only I ever need that flexibility. At least, whatever I came across so far are CRUD operations over http which I can manage using couple of @JsonIgnores. Or if there is one or two fields that needs a transformation which cannot be done using Jackson Annotation, As I said earlier, I can write custom logic to handle just that.
  2. Domain Objects getting bloated with Annotations.
    • This is a valid concern. If I use JPA or MyBatis as my persistent framework, domain object might have those annotations, then there will be Jackson annotations too. In my case, this is not much applicable though, I am using Spring boot and I can get away by using application-wide properties like mybatis.configuration.map-underscore-to-camel-case: true , spring.jackson.property-naming-strategy: SNAKE_CASE

Short story, at least in my case, cons doesn't outweigh the pros, so it doesn't make any sense to repeat myself by having a new POJO as DTO. Less code, less chances of bugs. So, going ahead with exposing the Domain object and not having a separate "view" object.

Disclaimer: This may or may not be applicable in your use case. This observation is per my usecase (basically a CRUD api having 15ish endpoints)

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=429802&siteId=1