Skip to content

b. Controller

The interface of the Account microservice is defined in the account module, which contains the API definition and the data transfer objects (DTOs) for the Account microservice.

The main purpose of the section is to create the following API endpoints:

classDiagram
    namespace account {
        class AccountController {
            +create(AccountIn accountIn): AccountOut
            +delete(String id): void
            +findAll(): List<AccountOut>
            +findById(String id): AccountOut
        }
        class AccountIn {
            -String name
            -String email
            -String password
        }
        class AccountOut {
            -String id
            -String name
            -String email
        }
    }

1. Repository

  • a. At github, create a new repository for the Account interface. Example: account.

  • b. Then, clone this repository as a submodule to your local machine. To do this, run the following commands at the root of the project:

    git submodule add <repository_url> api/account
    

This will create a new directory called account inside the api directory, which will contain the code for the Account interface. The resulting directory structure will look like this:

📁 platform/
└── 📁 api/
    └── 📁 account/

2. Code

To code this interface module, we will use the Spring Boot framework, through the Spring Initializr, at [https://start.spring.io/], which is a web-based tool that allows us to generate a Spring Boot project with the necessary dependencies and configurations.

Spring Initializr
Spring Initializr

Note:

  • Project: Maven
  • Language: Java
  • Spring Boot: 4.0.3 (stable version for now)
  • Group: store (the company name, for example)
  • Artifact: account (the microservice name)
  • Package name: store.account
  • Packaging: Jar
  • Configurarion: YAML
  • Java: 25 (LTS version for now)

Additionally, we need to add the following dependencies:

  • Lombok: a Java library that helps to reduce boilerplate code by generating getters, setters, constructors, and other common methods at compile time using annotations.

  • OpenFeign: a declarative web service client that simplifies the process of making HTTP requests to other microservices. It allows us to define interfaces for our API clients and automatically generates the implementation at runtime.

Then, download the zip file and extract it to the api/account directory. The resulting directory structure will look like this:

📁 api/
└── 📁 account/
    ├── 📁 src/
       ├── 📁 main/
          └── 📁 java/
              └── 📁 store/
                  └── 📁 account/
                      └──  AccountApplication.java
       └── 📁 resources/
           └──  application.yaml
    └──  pom.xml

In this case, the AccountApplication class is useless, since this module is only for the interface, and will not be run as a standalone application. Therefore, we can delete this class and the application.yaml file. Also, we can delete the src/test directory, since we will not be writing tests for this module. Still, we do not need the src/main/resources directory, since we will not be adding any resources to this module. Therefore, we can delete this directory as well. The resulting directory structure will look like this:

Now, this time to code the interface, which consists of the AccountController class, which defines the API endpoints for the Account microservice, and the AccountIn and AccountOut classes, which are the DTOs for the input and output of the API endpoints, respectively. The resulting directory structure will look like this:

📁 api/
└── 📁 account/
    ├── 📁 src/
       └── 📁 main/
           └── 📁 java/
               └── 📁 store/
                   └── 📁 account/
                       ├──  AccountController.java
                       ├──  AccountIn.java
                       └──  AccountOut.java
    └──  pom.xml

A possible implementation of the AccountController, AccountIn, and AccountOut classes is shown below:

Source

<?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>4.0.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>store</groupId>
    <artifactId>account</artifactId>
    <version>1.0.0</version>
    <name>account</name>

    <properties>
        <java.version>25</java.version>
        <spring-cloud.version>2025.1.0</spring-cloud.version>
        <maven.compiler.proc>full</maven.compiler.proc>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </path>
                    </annotationProcessorPaths>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <release>${java.version}</release>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
AccountController.java
package store.account;

import java.util.List;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

@FeignClient(
    name="account",
    url="http://account:8080"
)
public interface AccountController {

    @PostMapping("/accounts")
    public ResponseEntity<Void> create(
        @RequestBody AccountIn in
    );

    @DeleteMapping("/accounts/{id}")
    public ResponseEntity<Void> delete(
        @PathVariable String id
    );

    @GetMapping("/accounts/health-check")
    public ResponseEntity<Void> healthCheck();

    @GetMapping("/accounts")
    public ResponseEntity<List<AccountOut>> findAll();

    @GetMapping("/accounts/{id}")
    public ResponseEntity<AccountOut> findById(
        @PathVariable String id
    );

}
AccountIn.java
package store.account;

import lombok.Builder;

@Builder
public record AccountIn(

    String name,
    String email,
    String password

) {

}
AccountOut.java
package store.account;

import lombok.Builder;

@Builder
public record AccountOut(

    String id,
    String name,
    String email

) {

}

3. Package and Install

After coding the interface, we need to install the package to the local Maven repository, so that it can be used by other modules in the project. To do this, run the following command at the root of the project:

mvn clean install

Done! The Account interface is now ready to be used by other modules in the project.

Let's move on to the next section, where we will implement the Account microservice using the interface we just created.

Service