I am bulding a REST API in Spring. So until now I have only reading services (GET). For this I used Spring HATEOAS to add links that referring to child elements.
Now I want to add some writing REST-Services. Usually DTOs are used in REST-Services and those are then mapped to the domain model.
So my question is: Can we just use resources from Spring HATEOAS as in the example below and do without DTOs? Or are resources intended for something else and I still need DTOs?
@PostMapping
public ResponseEntity<String> saveProduct(@RequestBody ProductResource product) {
...
}
I would say that Spring HATEOAS doesn't replace DTOs: it builds on top of DTOs. So you can make your DTO class extend ResourceSupport
or wrap it with Resource<T>
.
Since Spring HATEOAS 1.0.0, released in late September 2019, ResourceSupport
and Resource<T>
have been renamed to RepresentationModel
and EntityModel<T>
respectively. Quoting the documentation:
Representation models
The
ResourceSupport
/Resource
/Resources
/PagedResources
group of classes never really felt appropriately named. After all, these types do not actually manifest resources but rather representation models that can be enriched with hypermedia information and affordances. Here’s how new names map to the old ones:
ResourceSupport
is nowRepresentationModel
Resource
is nowEntityModel
Resources
is nowCollectionModel
PagedResources
is nowPagedModel
What's important, however, is to keep the domain model decoupled from the API model.
The models that represent the domain of your application and the models that represent the data handled by your API are (or at least should be) different concerns. You don’t want to break your API clients when you add, remove or rename a field from the application domain model.
While your service layer operates over the domain/persistence models, your API controllers should operate over a different set of models. As your domain/persistence models evolve to support new business requirements, for example, you may want to create new versions of the API models to support these changes. You also may want to deprecate the old versions of your API as new versions are released. And it’s perfectly possible to achieve when the things are decoupled.
To minimize the boilerplate code of converting the domain model to the API model (and vice versa), you could rely on frameworks such as MapStruct. And you also could consider using Lombok to generate getters, setters, equals()
, hashcode()
and toString()
methods for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With