Building REST API in Micronaut (Banking App Example)

Micronaut is a powerful framework for building microservices and REST APIs in Java. In this tutorial, we will be Building REST API in Micronaut for a banking application using Micronaut and Java 21. We will cover everything step-by-step so even beginners can follow along.

Project Overview

We will build a small banking API that allows us to:

  • Create a bank account
  • View account details
  • Deposit money
  • Withdraw money

Package structure: com.kscodes.banking

Prerequisites

  • Java 21 installed
  • Micronaut CLI installed (optional but recommended)
  • VS Code (or any IDE)
  • Maven

Step 1: Create a Micronaut Project

Using Micronaut CLI:


mn create-app com.kscodes.banking --java-version 21 --build maven

Or use Micronaut Launch and download the generated project with Maven as the build tool.

Open the project in VS Code.

Step 2: Define the Domain Model

Create a new file Account.java in:

src/main/java/com/kscodes/banking/model/


package com.kscodes.banking.model;

import java.math.BigDecimal;
import java.util.UUID;

public class Account {

    private UUID accountId;
    private String accountHolder;
    private BigDecimal balance;

    public Account(String accountHolder) {
        this.accountId = UUID.randomUUID();
        this.accountHolder = accountHolder;
        this.balance = BigDecimal.ZERO;
    }

    public UUID getAccountId() { return accountId; }
    public String getAccountHolder() { return accountHolder; }
    public BigDecimal getBalance() { return balance; }

    public void deposit(BigDecimal amount) {
        balance = balance.add(amount);
    }

    public void withdraw(BigDecimal amount) {
        balance = balance.subtract(amount);
    }
}

Step 3: Create a Simple Service

Create AccountService.java in:

src/main/java/com/kscodes/banking/service/


package com.kscodes.banking.service;

import com.kscodes.banking.model.Account;
import jakarta.inject.Singleton;

import java.math.BigDecimal;
import java.util.*;

@Singleton
public class AccountService {

    private final Map accounts = new HashMap<>();

    public Account createAccount(String accountHolder) {
        Account account = new Account(accountHolder);
        accounts.put(account.getAccountId(), account);
        return account;
    }

    public Optional getAccount(UUID accountId) {
        return Optional.ofNullable(accounts.get(accountId));
    }

    public Optional deposit(UUID accountId, BigDecimal amount) {
        Account account = accounts.get(accountId);
        if (account != null) {
            account.deposit(amount);
            return Optional.of(account);
        }
        return Optional.empty();
    }

    public Optional withdraw(UUID accountId, BigDecimal amount) {
        Account account = accounts.get(accountId);
        if (account != null) {
            account.withdraw(amount);
            return Optional.of(account);
        }
        return Optional.empty();
    }
}

Step 4: Create REST Controller

Create AccountController.java in:

src/main/java/com/kscodes/banking/controller/


package com.kscodes.banking.controller;

import com.kscodes.banking.model.Account;
import com.kscodes.banking.service.AccountService;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.*;

import jakarta.inject.Inject;
import java.math.BigDecimal;
import java.util.Optional;
import java.util.UUID;

@Controller("/accounts")
public class AccountController {

    @Inject
    AccountService accountService;

    @Post("/")
    public Account createAccount(@Body String accountHolder) {
        return accountService.createAccount(accountHolder);
    }

    @Get("/{accountId}")
    public HttpResponse getAccount(UUID accountId) {
        return accountService.getAccount(accountId)
                .map(HttpResponse::ok)
                .orElse(HttpResponse.notFound());
    }

    @Post("/{accountId}/deposit")
    public HttpResponse deposit(UUID accountId, @Body BigDecimal amount) {
        return accountService.deposit(accountId, amount)
                .map(HttpResponse::ok)
                .orElse(HttpResponse.notFound());
    }

    @Post("/{accountId}/withdraw")
    public HttpResponse withdraw(UUID accountId, @Body BigDecimal amount) {
        return accountService.withdraw(accountId, amount)
                .map(HttpResponse::ok)
                .orElse(HttpResponse.notFound());
    }
}

Step 5: Run and Test

Build and run the application:


mvnw mn:run
Building REST API in Micronaut (Banking App Example)

Example API calls:

  • Create Account:

curl -X POST http://localhost:8080/accounts -d "John Doe"
  • Deposit Money:

curl -X POST http://localhost:8080/accounts/{accountId}/deposit -d 500.00
  • Withdraw Money:

curl -X POST http://localhost:8080/accounts/{accountId}/withdraw -d 200.00
  • Get Account Info:

curl http://localhost:8080/accounts/{accountId}

Step 6: Using Virtual Threads (Java 21 Feature)

In application.yml, enable virtual threads:


micronaut:
  executors:
    io:
      type: virtual

This allows your Micronaut app to scale better with Java 21.

Summary

  • We created a simple banking REST API using Micronaut.
  • Implemented account creation, deposit, withdrawal, and fetching account info.
  • Used Java 21 virtual threads.
  • Simple in-memory storage (can be extended with a database).

Stay tuned for future posts where we will add database support, validations, exception handling, and more enterprise-ready features!