Kickstart Your Journey: Building Your First Microservice with Spring Boot

Prashant BalePrashant Bale
6 min read

Microservices architecture is a design approach where an application is composed of small, independent services that communicate over well-defined APIs. Each microservice is focused on a specific business function and can be developed, deployed, and scaled independently.

In this blog, we will guide you through building your first microservice using Spring Boot.

Microservice architecture benefits:

  1. Scalability: Individual services can be scaled independently based on demand, improving resource utilization and performance.

  2. Flexibility: Different services can be developed using different technologies and programming languages, allowing teams to choose the best tools for each task.

  3. Resilience: The failure of one service does not necessarily bring down the entire system, as other services can continue to operate.

  4. Faster Development: Teams can work on different services simultaneously, speeding up the development process.

  5. Easier Maintenance: Smaller, focused services are easier to understand, test, and maintain compared to a monolithic application.

Architecture

Typical pattern for organizing code in a microservices architecture using Controller-Repository-Service-Entity architecture in this blog.

  1. Controller Layer

    • This layer handles incoming HTTP requests, interacts with the service layer, and returns responses.

    • Annotated with @RestController.

    • Defines endpoints using @RequestMapping

    • Validates inputs and handles exceptions.

  2. Service Layer

    • This layer contains the business logic of the application and communicates with the repository layer.

    • Annotated with @Service.

    • Calls repository methods.

  3. Repository Layer

    • This layer interacts with the database and performs CRUD operations.

    • Extends JpaRepository or other Spring Data repositories.

    • Annotated with @Repository

  4. Entity Layer

    • This layer represents the database tables as Java objects.

    • Annotated with @Entity.

    • Maps to a table in the database.

Putting it All Together

Here’s how the architecture flows:

  1. Client sends an HTTP request to an API endpoint in the Controller.

  2. The Controller processes the request and invokes the corresponding Service method.

  3. The Service contains the business logic and may perform validations or other operations.

  4. The Service calls the Repository to perform CRUD operations on the Entity.

  5. The Repository interacts with the database and returns the results to the Service.

  6. The Service returns the processed data to the Controller.

  7. The Controller returns the final response to the Client.

Setting Up Spring Boot

Step 1: Create a New Spring Boot Project

You can create a new Spring Boot project using Spring Initializr.

  1. Go to start.spring.io.

  2. Select "Maven Project" and "Java".

  3. Select Spring Boot version 3.1.1 (or the latest).

  4. Add dependencies: "Spring Web", "Spring Data JPA", "H2 Database" (for simplicity).

  5. Click "Generate" to download the project and unzip it.

Step 2: Import the Project into Your IDE

Import the unzipped project into your favorite IDE (like IntelliJ IDEA or Eclipse).

Creating the Microservice

Step 3: Define the Domain Model

Create a simple domain model for a User.

package com.example.userservice.model;

import jakarta.persistence.*;

@Entity
public class Users {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    private String email;

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

@Entity : This annotation specifies that the class is an entity and is mapped to a database table. The Users class will be mapped to a table named users (default behavior if no table name is specified).

@Id: This annotation specifies the primary key of the entity. In this case, the id field is the primary key.

@GeneratedValue(strategy = GenerationType.AUTO): This annotation provides the specification of generation strategies for the values of primary keys. GenerationType.AUTO allows the persistence provider (e.g., Hibernate) to choose an appropriate strategy for the particular database.

Step 4: Create a Repository

Create a repository interface for the Product entity.

package com.example.userservice.repository;

import com.example.userservice.model.Users;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<Users, Long> {
}

Step 5: Create a Service

Create a service to handle business logic.

package com.example.userservice.service;

import com.example.userservice.model.Users;
import com.example.userservice.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public List<Users> getAllUsers() {
        return userRepository.findAll();
    }

    public Users getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    public Users saveUser(Users users) {
        return userRepository.save(users);
    }

    public void deleteUser(Long userId) {
        userRepository.deleteById(userId);
    }

}

Step 6: Create a Controller

Create a REST controller to expose the endpoints.

package com.example.userservice.controller;

import com.example.userservice.model.Users;
import com.example.userservice.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping
    public List<Users> getAllUsers() {
        return userService.getAllUsers();
    }

    @GetMapping("/{id}")
    public Users getUserById(@PathVariable Long id) {
        return userService.getUserById(id);
    }

    @PostMapping
    public Users createUser(@RequestBody Users users) {
        return userService.saveUser(users);
    }
}

Application Class

package com.example.userservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication
@EnableJpaRepositories(basePackages = "com.example.userservice.repository")
@EntityScan(basePackages = "com.example.userservice.model")
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

application.properties file

# --- This sets name of the Spring application ---
spring.application.name=userservice

# ---  JDBC - H2 database Config ---
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.h2.console.enabled=true
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

# --- Enables logging of SQL statements ---
# --- Only for Testing Purpose - Remove for Production ---
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop

# --- Port Details ---
server.port=8080

Running the Microservice

Step 7: Run the Application

Run the Spring Boot application using your IDE or from the command line:

./mvnw spring-boot:run

Step 8: Test the Endpoints

You can test the endpoints using Postman or curl.

# Create a new user
curl -X POST http://localhost:8080/users -d '{"username":"john_doe","email":"john.doe@example.com"}' -H "Content-Type: application/json"

# Get all users
curl http://localhost:8080/users

# Get a user by ID
curl http://localhost:8080/users/1

Best Practices

  1. Use DTOs (Data Transfer Objects): Avoid exposing your entities directly in your REST API.

    1. Implement Exception Handling: Use @ControllerAdvice to handle exceptions globally.
  2. Enable CORS: Configure Cross-Origin Resource Sharing if your service will be consumed by a web application.

  3. Secure Your APIs: Implement security using Spring Security.

  4. Use Properties for Configuration: Externalize your configuration using application properties or YAML.

  5. Document Your API: Use Swagger/OpenAPI for API documentation.

  6. Log Effectively: Use a logging framework like Logback or Log4j2 to log important events and errors.

Conclusion

Building your first microservice with Spring Boot is straightforward and powerful. By following the steps outlined above, you can quickly get a microservice up and running.

Remember to follow best practices to ensure your service is secure, maintainable, and scalable.

You can find Github link for Spring Boot Microservices Application Sample here

If you enjoyed this tutorial and want to see more of my work, check out my GitHub profile. Feel free to follow me or star my repositories!

Happy coding !

0
Subscribe to my newsletter

Read articles from Prashant Bale directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Prashant Bale
Prashant Bale

With 17+ years in software development and 14+ years specializing in Android app architecture and development, I am a seasoned Lead Android Developer. My comprehensive knowledge spans all phases of mobile application development, particularly within the banking domain. I excel at transforming business needs into secure, user-friendly solutions known for their scalability and durability. As a proven leader and Mobile Architect.