Hi everyone! As in the previous post, we are going to implement a complete microservice architecture and as the first step, we have created a microservice which is called Department Service and for the sake of complexity which can handle with the architecture, we need one more service which has a call to the Department Service within it. So, here in this post, we will try to implement another service called User Service. we will quickly go into the implementation details.
This image is recreated by agnasarp.com and used only for information purposes. This does not have any bind with any real-world products or services. Image source: pixabay.com
Step 2 - User Microservice
Here we will quickly go to the technology stack that we are going to use in our implementation.
Initialization details
Spring Initialzr - User Service
- Project build tool: Maven
- Language: Java
- Spring boot: 2.4.2
- Project Metadata
- Group: com.agnasarp
- Artifact: agnasarp-user-microservice
- Name: agnasarp-user-microservice
- Description: Agnasarp User Microservice
- Package name: com.agnasarp.user
- Packaging: Jar
- Java version: 8
- Dependencies:
- Spring Web: Build web, including RESTful, applications using Spring MVC. Uses Apache Tomcat as the default embedded container.
- Spring Data JPA: Persist data in SQL stores with Java Persistence API using Spring Data and Hibernate.
- H2 Database: Provides a fast in-memory database that supports JDBC API and R2DBC access, with a small (2mb) footprint. Supports embedded and server modes as well as a browser based console application.
- Lomok: Java annotation library which helps to reduce boilerplate code.
Then, we will import the project into IntelliJ Idea.
Project structure
Project structure of user service in IntelliJ Idea
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.agnasarp</groupId>
<artifactId>agnasarp-user-microservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>agnasarp-user-microservice</name>
<description>Agnasarp User Microservice</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
server: port: 8380
AgnasarpUserMicroserviceApplication.java
package com.agnasarp.user; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication public class AgnasarpUserMicroserviceApplication { public static void main(String[] args) { SpringApplication.run(AgnasarpUserMicroserviceApplication.class, args); } @Bean RestTemplate restTemplate() { return new RestTemplate(); } }
UserController.java
package com.agnasarp.user.controller; import com.agnasarp.user.entity.User; import com.agnasarp.user.service.UserService; import com.agnasarp.user.vo.ResponseTemplateVo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/users") public class UserController { private static final Logger log = LoggerFactory.getLogger(UserController.class); @Autowired private UserService userService; @PostMapping("/") public User saveUser(@RequestBody User user) { log.info("Inside saveUser method of UserController"); return userService.saveUser(user); } @GetMapping("/{id}") public ResponseTemplateVo getUserById(@PathVariable("id") Long userId) { log.info("Inside getUserById method of UserController"); return userService.getUserWithDepartment(userId); } }
UserService.java
package com.agnasarp.user.service; import com.agnasarp.user.entity.User; import com.agnasarp.user.repository.UserRepository; import com.agnasarp.user.vo.Department; import com.agnasarp.user.vo.ResponseTemplateVo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @Service public class UserService { private static final Logger log = LoggerFactory.getLogger(UserService.class); @Autowired private UserRepository userRepository; @Autowired private RestTemplate restTemplate; public User saveUser(User user) { log.info("Inside saveUser method of UserService"); return userRepository.save(user); } public ResponseTemplateVo getUserWithDepartment(Long userId) { log.info("Inside getUserWithDepartment method of UserService"); ResponseTemplateVo responseTemplateVo = new ResponseTemplateVo(); User user = userRepository.getUserByUserId(userId); Department department = restTemplate.getForObject("http://localhost:8280/" + "departments/" + userId, Department.class); responseTemplateVo.setUser(user); responseTemplateVo.setDepartment(department); return responseTemplateVo; } }
UserRepository.java
package com.agnasarp.user.repository; import com.agnasarp.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository<User, Long> { User getUserByUserId(Long userId); }
User.java
package com.agnasarp.user.entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity @Data @NoArgsConstructor @AllArgsConstructor public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long userId; private String firstName; private String lastName; private Long departmentId; }
View Objects
We need the attached department details of the user, therefore we have to create a Department view object here in the user microservice. And we need to show user details and department details collectively in the response, for that we have to create ResponseTemplateVo.
Department.java
package com.agnasarp.user.vo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class Department { private Long departmentId; private String departmentName; private String departmentAddress; private String departmentCode; }
ResponseTemplateVo.java
package com.agnasarp.user.vo; import com.agnasarp.user.entity.User; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class ResponseTemplateVo { private User user; private Department department; public void setUser(User user) { this.user = user; } public void setDepartment(Department department) { this.department = department; } }
Service call
Create user scenario
cURL
curl --location --request POST 'http://localhost:8380/users/' \ --header 'Content-Type: application/json' \ --data-raw '{ "firstName":"John", "lastName":"Smith", "departmentId":"1" }'
Postman call
Get user scenario: As we have designed to get user details with the assigned department, we have to create a department first with the save department service as in the previous post. Otherwise, the department object will be null.
cURL
curl --location --request GET 'http://localhost:8380/users/1'
Postman call
Now we have created the User Microservice successfully as same as the Department Service in the previous post. As the next step, we will create a service registry which is another important component in the microservice architecture. You can download the complete source code from GitHub with the below link.
Post a Comment