Where to map RestTemplate ResponseEntity objects to Domain objects - spring

In my Repository, I'm calling external REST API and properly retrieve response which I wrap in ResponseEntity object as below:
ResponseEntity<ExternalModelResponse> response = restTemplate.getForEntity(baseUrl + "/api/externalObject", ExternalModelResponse.class);
However, ExternalModelResponse doesn't follow my Domain model so I want to introduce mapping of the ExternalModelResponse -> Domain model.
What would be the correct place to introduce such mapping? Should:
Repository method already return Domain object? That would imply mapping in the same method which fetched object from external REST API.
Repository method return ExternalModelResponse and let Service handle the mapping?
What is the most common place of such mapping?:
added as toDomainEntity method on ExternalModelResponse?
added as fromExternalModelResponse method on Domain Entity?
added as a method on Repository/Service ?

The service layer should use only domain objects, so I've done this mapping in the controllers.

Related

Spring Data REST - do not allow to return entities but only views (projections)

My objective is to make sure that a client can't access (retrieve) directly an entity through the Spring Data REST auto-exposed APIs, but rather only to the views (JPA's projections) of those entities.
So far I've managed to achieve it only for the APIs that return a collection of entities (such as findAll() ) by using the #RepositoryRestResource(excerptProjection = CustomerView.class) annotation on the repository.
How to configure Spring Data REST so that it does the same also for endpoints that retrieve a specific entity? such as /api/v1/customers/1
See Why is an excerpt projection not applied automatically for a Spring Data REST item resource?
If you want to apply projection to a specific entity (that is, item resource),
set the uri template variable projection to construct a url path /api/v1/customers/1?projection=customerView. The name customerView is what is set in the annotation #Projection. see the doc https://docs.spring.io/spring-data/rest/docs/current/reference/html/#projections-excerpts.projections
Edit after clarify with Macro:
Macro wants to hide some sentitive fields such as password. Then the jackson annotation #JsonIgnore should be added to the sentitive fields to hide them from response json.

Spring RequestMapping Controller annotation and create a different absolute path inside the same Controller

From the perpective of Restful Apis, its said its a good choice to design them hierarchical when your database is hierarchical too, above all because the client learns and knows the hierarchical structure of the entities. I mean, for instance, if you have bank clients and accounts, the parent entity would be the clients and the child entities would be the accounts. So :
To get the accounts from the client 1, a right URI could be something like "/clients/1/accounts"
From the perspective of Spring controllers, I should have a ClientController and a AccountController but
The AccountController should process the above request, right?
Could I specify and URI like "accounts/?clientId=1"? Its a bad design?
If I go with the option 1, how to specify this URI in the AccountsController?? If not, should I create another controller just for this and not put this URI in the Account controller?
#RequestMapping("/clients")
public class ClientsController{ }
#RequestMapping("/accounts")
public class AccountsController{
#RequestMapping("/clients/{idClient}/accounts") => **I cannot specify
an absolute path here because
its relative to the RequestMapping annotation in the Controller**
#GetMapping
public #ResponseBody List<Account> getAccounts(){}
}
Thanks!!
There's no hard bound rules it's matter of choice and use cases that decides how we structure our rest uris and using query param or path variables is for constructing meaningful and readable uris.
Suppose if you have.usecase is like to get the list of accounts needs a client ID as mandatory then construct:
GET /clients/{id}/accounts
And put it in clients controller.
But if your usecase is like client id is not mandatory to get list of accounts then construct:
GET /accounts?clientid=1
And put it in accounts controller. Now you can choose to make clientid as required=false request param.
Don't construct deeply nested APIs.. make dumb endpoints eventually you'll end up facing usecases where you'll need to create non nested uris.

Transfer an object from controller to dao

I am getting an token from request(the token is required to identify the user) to initialize user object in interceptor. Then i want to transfer this user object to controllers(i can put the user object to httprequest and get it in controller method, is this the best practice???, i am not sure) than transfer it to service and dao layer. But i don't want to add this user object as parameter to every method between controller->service->dao. What is the best practice of this?
Thanks in advance.
How about using a request-scoped bean to hold the token. You could reference the bean in your controller and set the token on it. Then in lower DAO layers could you reference the same bean to pull out the token. That would save having to pass the token down the method stack.
Alternatively you could use ThreadLocal storage directly which is effectively request scoped, but since you're using Spring, it would be cleaner and make more sense to leverage it's own request scope functionality.

How to construct DTO object from controller

I am using MVC pattern abstracted with domain layer. I could convert a domain object into its equivalent DTO and sending it across top layer (ie controller & ultimately to views). Now how to do the reverse? How & where will I construct the actual DTO object and pass it to the controller?
I have found the best way to do this is have a DTO service layer. This will be a collection of functions that the controller (or anything else) can call to retrieve and convert DTO's.
I would also recommend doing the domain object to DTO mapping (and the reverse) in this layer too, it keeps all the DTO related logic in one layer.
Below is an example of a DTO service layer function:
public CustomerDto GetCustomer(Guid customerId) {
var roService = new RoService<Customer>(new Repository<Customer>(_dbContextFactory));
return _mapper.ToCustomerDto(roService.Get(customerId));
}
This will retrieve a Customer entity by its Id. The entity is passed to a mapper object which will convert it to a CustomerDto for it to be returned.
N.B. I used AutoMapper to convert my domain objects to DTO's.

DTO in spring mvc

I'm using spring mvc.
I have created the controller, view, pojo, dao.
Now I have the need to create an object composted from multiple objects pojo, is the case of creating a DTO?
If you're looking to build a composite kind of Object for view purposes only, then there is a good argument for a DTO. If the composite is just an aggregation of the POJOs you can use org.springframework.ui.Model and just add attributes inside your Controller. If there is logic and business rules that need to be applied, it is probably best to do this in a Service layer that sits between your Controller and your DAO.
If you mean that you need to access properties of few POJOs on the client side and you want to reduce amount of calls from
client to server then yes. It is better to create a DTO object where place only necessary properties from POJOs that you will
use on client side. And return this DTO as a result of a single call from client to server.

Resources