In this repository will demostrate how to build REST API's in Java as programming language and Spring Boot as a framework.
This repository is using:
- Java Version 11
- Spring Boot 2.7
- Lombok library
- JPA Data
- Docker
As a first step. I have to create the Resources class which are the representation of each database table. By building the entities of each table.
Below it is a small sample of the database table of orders. The code here creates the Class Order into Java code and on top of that there is the @Table
annotation with the name of the database table on the schema part.
@Table(name = "orders")
public class Order implements Serializable
In this part the code builds the primary key and the entity or the product name of the database table into Java environment.
@Id
@Column(name = "order_id", updatable = false, nullable = false)
private Integer orderId;
@NotNull
@Column(name = "product_name")
private String productName;
In order to have an entry point of the URL. It is needed to have a REST Controller class. In the case I develop and URL of http://localhost:8081/api/v1/
then main path.
@RestController
@RequestMapping("/api/v1/")
@RequiredArgsConstructor
public class OrderController
The following code is adding then specification of the URL path and indicates what the REST Api wants to retrieve. The full URL is :
http://localhost:8081/api/v1/orders
. In this case the URL indicates the retrieve all orser that are in the database.
@GetMapping(value = "orders")
@ResponseStatus(HttpStatus.OK)
public List<OrderDTO> getAllOrders() {
return orderServiceImpl.getOrders();
}
In this section, I add another midlle layer which is called Service or it is called Business layer. In this layer the data are been transformed into another format. Or coverign the need of the response to then end user.
@Service
public class OrderServiceImpl implements OrderService
In this part. The method getOrders() transform the data from Order Entity object into OrderDTO object.
public List<OrderDTO> getOrders() {
return orderRepository.findAll().stream().map(OrderMapper::convertEntityToDTO).collect(Collectors.toList());
}
This part is needed to tranform the Entity into DTO class.
@Service
public class OrderMapper {
public static OrderDTO convertEntityToDTO(Order order) {
ModelMapper modelMapper = new ModelMapper();
return modelMapper.map(order, OrderDTO.class);
}
}
This part creates an object that will return to the end user. Therefore it is needed to be build with the specification(entities) that is needed.
@Getter
@Setter
@Builder
@RequiredArgsConstructor
@AllArgsConstructor
public class OrderDTO {
private Integer orderId;
private String productName;
private String orderType;
private Integer quantity;
private Integer price;
private String category;
}
This layer is rensposible to apply the query to the database. In the below example. There is extention of the JpaRepository which means can be able to apply queries into the database. The most valueable info here that, it is impotant to indicates the actual type of the database table and then the primary key type. In our case, the primary key is Integer type.
@Repository
public interface OrderRepository extends JpaRepository<Order, Integer> {
}
Lombok is an additional library. The (project) Lombok is an annotation-based Java library that allows you to reduce boilerplate code. Lombok offers various annotations aimed at replacing Java code that is well known for being boilerplate, repetitive, or tedious to write.
For example. Some annotations help to avoid to write code that is needed to return values from the class. The first annotation is used to return all values of the class.
@Getter
The second annotation sets the given value to each entity.
@Setter
Lastly, this annotation builds an object. The @Builder annotation lets you automatically produce the code required to have your class be instantiable with code.
@Builder
The first annotation will generate a constructor with no parameters. Where the second annotation, generates a constructor with 1 parameter for each field in your class.
@NoArgsConstructor
@AllArgsConstructor
In order to test/check the RestApi it is needed to use Postman application. On the postman I added the URL in order to receive the sesponse data from the database.
http://localhost:8081/api/v1/clients
And the response from the image shows what the response has.
The second response comes also form the image below.
In order to run the application. It is possible to run the application on Docker. By using Docker, can use your own environment. For example, the first line of this Dockerfile, shows the JDK that will use. The second line, indicates in which port will be exposed.
FROM openjdk:11.0.15-slim
EXPOSE 8081
ADD target/spring-boot-application-docker.jar spring-boot-application-docker.jar
ENTRYPOINT ["java", "-jar", "/spring-boot-application-docker.jar"]
FIrst of all need to build the image. With this command you can build the docker image with a specific (Docker) image name.
docker build -t spring_application .
The second command need to type, is to execute the image into docker container.
docker run -p 8081:8081 spring_application
When you want to join one or more tables. Then need to indicate the table with the correct annotation.
For example:
In this case, each Client entity may has many Orders. Therefore, adding a foreign key of client_id.
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "oc_fk", referencedColumnName = "client_id")
private List<Order> orders;
This image has the result of the one-to-many
In this cas, Many Clients have many (difference) Orders. Hence, adding the pivot table in order to make the matching between the entities of Order and Client.
@JsonIgnore
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "client_orders",
joinColumns = @JoinColumn(name = "client_id"),
inverseJoinColumns = @JoinColumn(name = "order_id"))
private List<Order> ordersByClients;