top of page
image 82.png

Create DTO, Rest Controller, and Swagger for GET/ADD/DELETE

In this section we will learn about:

​

  • Swagger

  • Model Mapper

  • DTO

  • Rest Controller

Swagger

​

A swagger is a web-based tool used for documenting the REST APIs.  Here, we can get all our APIs organized according to every controller and we don’t need to remember all URI paths for each API as all APIs are documented at the runtime of the application.

​

Steps to set up Swagger UI:

  • We need to add two dependencies and then update Maven. Note: After doing any changes in POM.xml, you always need to update maven to reflect the changes.

Screenshot 2023-05-10 110454.png
Screenshot 2023-05-10 110428.png
  •  Then create a Java class for Swagger. And annotate it with @Configuration and @EnableSwagger2.

  • The Swagger interface can be accessed via the below URL:

http://localhost:8080/swagger-ui/index.html

Configure/Customize the Swagger:

 

Add a Docket method and annotate it with @Bean.

Docket handles all the APIs, and packages that need to be shown.

Screenshot 2023-05-10 111249.png

​ApiInfo is used to customize our Swagger and provide our title, contact, description, etc.

Screenshot 2023-05-10 111456.png

Model Mapper

 

Model Mapper is a library that is used for mapping one object to another. 

 

Suppose there is a class named “Demo” and has 3 variables i.e. (int Id), (String name) & (String email). But we need to expose only the name and the email to the client and not the Id. So, we will create a DTO(Data Transfer Object) having the name and email as variables and map DTO variables to Demo class variables and vice-versa using the Model Mapper.

 

For mapping one object to another, we need to use the map function of the model mapper and provide two parameters. The first parameter will be an instance that needs to be mapped (source) and the second will be a class (not an object) in which we need to map (destination).

​

Syntax: modelMapper.map(<object1> source,<Object2.class> destination);

​

Setting up Model Mapper:

​

  • ​We need to add a model mapper dependency.

Screenshot 2023-05-10 112255.png
  • Configure the model mapper by adding a method and annotating it as a Bean in the main class.

Screenshot 2023-05-10 112449.png

Data Transfer Object (DTO)

​

  • DTOs are Data Transfer Objects used to pass the properties from the service layer to the persistence layer.

  • It is a good practice to use DTOs in Controller, as exposing our Entity class would be vulnerable and raise security issues.

  • RequestDTO” will request data from the client and “ResponseDTO” will send a response to the client.

  • These DTOs are the Entity classes with selected variables present in them to expose to clients.

Rest Controller

 

It is a Java class that is used to make REST APIs or endpoints of an application. This Java class handles all REST API requests such as GET, POST, DELETE, and PUT for fetching, sending, deleting, and updating data respectively.

 

To make a Java class a Rest Controller, we just use an annotation i.e. @RestController.

Some terms related to Rest Controller -

​

  • @RequestMapping

This is one of the basic annotations in Spring that maps HTTP requests with handler methods. The mapping can also be done at the method or class level (can be annotated above class or method).

We can use the attribute method = RequestMethod.GET or different the request method and value attribute for URI.

Writing Protocol - @RequestMapping(“/”)

*Any URI can be written after /.

​

​

  • @GetMapping, @PostMapping

GetMapping annotation is a specialized version of @RequestMapping annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.GET). 

@PostMapping is a specialized version of @RequestMapping annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.POST).

Writing Protocols of GET, POST, DELETE, PUT, and REQUEST are the same. These annotations are method-level.

​

​

  • @RequestBody

This annotation is used in the method parameter of RequstMapping for asking for data from the client as an object. This annotation uses HTTP Message converters to convert the body of HTTP requests to domain objects.

e.g. public void addUser(@RequestBody User user){}

​

​

  • @RequestParam

This annotation is used to get data from the client and is encoded.

e.g. @GetMapping(“/”)

public User getUserById(@RequestParam int id){}

 

 

  • @PathVariable 

This annotation is also used to get data from the client and is not encoded. This data is provided in the URI path.

e.g. @GetMapping(“/{id}”)

Public User getUserById(@PathVariable (“id”) int id){}

Yoga User

DTO

We will create a request and response DTO for Yoga User.

We will add only those variables which we want to request from the user in RequestDTO as we only need those from the client/user. And we will add all fields that we need to show to the client in Response DTO.

​

Request

DTO:"https://gitlab.com/kulpreet.libra/btl_mastering_springboot/-/blob/master/src/main/java/com/btl/bootcamp/dto/request/YogaUserReqDTO.java"

​

Response

DTO:"https://gitlab.com/kulpreet.libra/btl_mastering_springboot/-/blob/master/src/main/java/com/btl/bootcamp/dto/response/YogaUserRespDTO.java"

Rest Controller

​

A controller class will be constructed now. And we will use @Autowired annotation to use the service bean or the service class which we would be creating next.

We autowired the corresponding service class to use the methods of the service class throughout the controller class.

Similarly, we will autowire Model-Mapper class as well. As model mapper and DTOs should be used in the Controller class to map the member variables of the DTOs and the controller.

​

a) POST mapping:

​

• We will create a method to add a user to our database. We will request “YogaUserReqDTO”, (username, password, email, and phone number) as parameters by using @RequestBody.

 

• And we will annotate the method with “@PostMapping” and “@ApiOperation”. We use post mapping to say we are posting or sending some data to the database. We will also provide a string parameter to post mapping annotation which will set a path at which we can access the API.

E.g.: @PostMapping(“/yogauser”)

​

• @ApiOperation: This annotation is of swagger and is used to describe what this API or method does (Here, for adding a yoga user).

​

• First, we will map “RequestDTO” to the Entity class then send it to a service method which will perform logic and later send it to the repository and will return the same Entity class to Controller, which is again mapped into “ResponseDTO” which contains all the fields of Response DTO.

​

​

b) GET Mapping:

​

​• We will create a method for getting a user from the database. And we will annotate the method with “@GetMethod” and “@ApiOperation”. We will also provide a path on which we can access this API. And in the path, we will also provide a path variable as “{id}”.

​

NOTE: We can’t use the same path for 2 methods unless the annotations are different. Say @PostMapping(“/yogauser”) and @GetMapping(“/yogauser”)

​

• This method will simply return a Response DTO of the yoga user.

• The method will contain a parameter as UUID id (a primary key type of Yoga User) which will be denoted by “@PathVariable”.

• We will create a method in service (we can see in the next section) and will call it in our method.

• The returned object from the service will be from the Yoga User class. So we will map it into a Response DTO and return the same.

​

​

c) DELETE Mapping:

​

• We will create a method for deleting a user from the database. And annotate it with “@DeleteMapping”. And we will give the same path as the parameter of annotation.

• The method will request the user id of the user for identifying the user and deleting it. For this purpose, we will use “@RequestParam” and the parameter will be just UUID id.

• This will be a void function because, if the user is deleted, we cannot have any use to return.

• And we will call a method made in service for deleting the user.

image 68.png

Service

 

The service layer is responsible for all the business logic for the requests and responses. It is a layer between controller and repository.

​

What is needed to be done by provided data and requests are handled here?

Requests after applying logic are sent to the repository and responses from the repository come here.

Now we will make a Service class with the same name as autowired and annotate it with @Service. This will create a Bean of service which will be used in autowiring.

 

We will auto-wire “YogaUserRepository” as it will be needed in service to send the data to the repository which will eventually save data in the database(MySQL).

​

Before moving to service, we need to create 2 functions in Yoga User Repository:

​

a) Optional<YogaUser> findByEmailAndIsDeleted(String email, int isDeleted) :

This method will be used to find a user from the database using an email and is Deleted variable. We will provide values of email and is Deleted in service and find the user. It will return an Optional yoga user.

​

​

b) Optional<YogaUser> findByUserId(UUID id) :

This method will be used to return the Optional of yoga users by their UUID.

​

Yoga User repository:

"https://gitlab.com/kulpreet.libra/btl_mastering_springboot/-/blob/master/src/main/java/com/btl/bootcamp/repository/YogaUserRepository.java"

​

NOTE: We can create several methods for finding a user without applying logic by just mentioning the return type and then findBy<variable -name-in-camel-case>(<datatype of variable> <variable name>).

​

​

We will create 3 methods for each add, get, and delete method in the controller.

These methods are:

​

a) Add Method:

​

• We will use the findByEmailAndIsDeleted() method of the repository to find the user.

We will get the user’s email from what we got in the parameter (“yogaUser.getEmail()”) and predefined the final keyword NOT_DELETED with the value 0. So, if any user exists with the email provided and is not deleted then we will throw an exception.

​

• If the user is not present then we will set the current date and time at which the user will be added for the variable “lastUpdatedDate”, as this column should not be null (constraint provided in entity class).

​

• And then, we will use a predefined “JpaRepository” method called save(). This will save our entity in the database. And return the same.

​

• This method will return a yoga user to the corresponding controller class, which will then be mapped with the Response DTO.

​

b) Get Method:

​

• We will use the findByUserId()  method to find a user by the UUID provided. If the user is not found, we will throw an exception.

​

• If the user is found then we will return the user by “yogaUser.get()” method, as the returned object from the repository is of ‘Optional’ type. We have to use the get() method to get the entity object.

​

c) Delete Method:

​

• Here, the steps will be similar to the get method, but here we do not have to return anything.

​

• We will find userd by the UUID provided using the findByUserId() method and if it does not exist,s then we will throw an exception. If it exists, then we will use a predefined method of JPA repository “.delete()” and delete the user from the database.

image 69.png

Now, we will run our application and open the swagger-UI ( http://localhost:8080/swagger-ui/index.html#/) for testing your API.

In order to add a user, provide the details of your choice and hit the “Execute” button. We will be returned with a Response body having our auto-generated ID, and other details.

image 70.png

Fig: Filling the request details.

image 71.png

Fig: Getting the returned response.

image 72.png

Fig: Users stored in the database.

Yoga Member

Creating a controller, service, and repository is similar to yoga users.

​

The only change we made is in the delete method. Earlier we just used the inbuilt delete method of the repository which removes the user from the database. But what if we want that even if a user/member is deleted, their details stay in the database?

​

Then “isDeleted” variables come into play.

​

  • We will pass a member Id from controller to service. Both methods would be void.

  • And then do a null check on members by finding the member by member id (as done earlier in yoga service).

  • Then we will set the value of “isDeleted” to 1 on the same member we found by member Id. And then save the member by using the save function. This will eventually update the member as deleted.

​

​

Yoga Member Controller:

"https://gitlab.com/kulpreet.libra/btl_mastering_springboot/-/blob/master/src/main/java/com/btl/bootcamp/controller/YogaMemberController.java"

​

Yoga Member Service:

"https://gitlab.com/kulpreet.libra/btl_mastering_springboot/-/blob/master/src/main/java/com/btl/bootcamp/service/YogaMemberService.java"

Yoga Events

Similarly, we will create a controller, service, and repository for Yoga Event.

The only new thing added is getting all the events instead of getting by id.

​

  • We don’t need to send any parameter to the controller, or to the service. As we will retrieve all the events.

  • We will use “.findAll()” to return the list of Yoga Events.

  • And then in the controller, we will use the lambda expression to map the whole list of Event to Response DTO.

​

​

Yoga Event Controller:

"https://gitlab.com/kulpreet.libra/btl_mastering_springboot/-/blob/master/src/main/java/com/btl/bootcamp/controller/EventController.java"

​

Yoga Event Service:

"https://gitlab.com/kulpreet.libra/btl_mastering_springboot/-/blob/master/src/main/java/com/btl/bootcamp/service/EventService.java"

Yoga Event Booking

Controller:

​

​

​

Service:

  • We will create 2 methods to find Event and Yoga Members by their id by autowiring their respective repositories. We also need to make a method in repositories to find by their id. We have an inbuilt method to find by id but it takes “long” as the parameter. So we will make a new which will accept String and return our object.

  • Then we will create a method to add event booking.

  • Here, we need the event id and member id to find Event and Yoga members by their id. So, we will use the 2 methods created above to find the objects.

  • And then we will add those objects to the event booking object we received by using the setter method of the event booking. This way the Event and Yoga Member will be associated with the booking.

  • Then we will save the event booking by using the save method.

  • "https://gitlab.com/kulpreet.libra/btl_mastering_springboot/-/blob/master/src/main/java/com/btl/bootcamp/service/EventBookingService.java"

bottom of page