Saturday, 1 July 2023

Micronaut: @Body: Bind the request body to a POJO

@Body annotation is applied to a method argument to indicate that the method argument is bound from the HTTP body.

 

Example

@Post
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Employee save(@Valid @Body final EmployeeRequestDto employeeRequestDto) {
	return employeeService.saveEmployee(employeeRequestDto);
}

 

Find the below working application.

 

Step 1: Create new maven project ‘micronaut-rest-bind-request-body’.

 

Step 2: Update pom.xml with maven dependencies.

 

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.sample.app</groupId>
	<artifactId>micronaut-rest-bind-request-body</artifactId>
	<version>0.1</version>
	<packaging>jar</packaging>

	<parent>
		<groupId>io.micronaut</groupId>
		<artifactId>micronaut-parent</artifactId>
		<version>3.7.4</version>
	</parent>

	<properties>
		<packaging>jar</packaging>
		<jdk.version>11</jdk.version>
		<release.version>11</release.version>
		<micronaut.version>3.7.3</micronaut.version>
		<micronaut.runtime>netty</micronaut.runtime>
		<exec.mainClass>com.sample.app.App</exec.mainClass>
	</properties>

	<repositories>
		<repository>
			<id>central</id>
			<url>https://repo.maven.apache.org/maven2</url>
		</repository>
	</repositories>

	<dependencies>
		<dependency>
			<groupId>io.micronaut</groupId>
			<artifactId>micronaut-inject</artifactId>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>io.micronaut</groupId>
			<artifactId>micronaut-validation</artifactId>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>io.micronaut</groupId>
			<artifactId>micronaut-http-client</artifactId>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>io.micronaut</groupId>
			<artifactId>micronaut-http-server-netty</artifactId>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>io.micronaut</groupId>
			<artifactId>micronaut-jackson-databind</artifactId>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>jakarta.annotation</groupId>
			<artifactId>jakarta.annotation-api</artifactId>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>io.micronaut.test</groupId>
			<artifactId>micronaut-test-junit5</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter-api</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter-engine</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>io.micronaut.build</groupId>
				<artifactId>micronaut-maven-plugin</artifactId>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<!-- Uncomment to enable incremental compilation -->
					<!-- <useIncrementalCompilation>false</useIncrementalCompilation> -->

					<annotationProcessorPaths
						combine.children="append">
						<path>
							<groupId>io.micronaut</groupId>
							<artifactId>micronaut-http-validation</artifactId>
							<version>${micronaut.version}</version>
						</path>
					</annotationProcessorPaths>

				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

 

Step 3: Define model classes.

 

EmployeeRequestDto.java

package com.sample.app.model;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Positive;

import io.micronaut.core.annotation.Introspected;
import io.micronaut.core.annotation.NonNull;

@Introspected
public final class EmployeeRequestDto {

	@NotBlank
	private String name;

	@NonNull
	@Positive
	private Integer age;

	public String getName() {
		return name;
	}

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

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

}

 

Employee.java

package com.sample.app.model;

import java.util.concurrent.atomic.AtomicInteger;

public final class Employee {

	private static final AtomicInteger UNIQUE_ID_COUNTER = new AtomicInteger(1);

	private Integer id;

	private String name;

	private Integer age;

	private Boolean lock = false;

	public Employee() {
	}

	public Employee(String name, Integer age) {
		this.id = UNIQUE_ID_COUNTER.getAndIncrement();
		this.name = name;
		this.age = age;
	}

	public Integer getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

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

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public Boolean getLock() {
		return lock;
	}

	public void setLock(Boolean lock) {
		this.lock = lock;
	}

}

Step 4: Define EmployeeService class.

 

EmployeeService.java

package com.sample.app.service;

import java.util.ArrayList;
import java.util.List;

import com.sample.app.model.Employee;
import com.sample.app.model.EmployeeRequestDto;

import jakarta.inject.Singleton;

@Singleton
public class EmployeeService {
	private static final List<Employee> emps = new ArrayList<>();
	private static final Employee EMP_NOT_FOUND = new Employee();

	static {
		final Employee emp1 = new Employee("Sunil", 23);
		final Employee emp2 = new Employee("Shetty", 31);
		final Employee emp3 = new Employee("Ram", 43);
		final Employee emp4 = new Employee("Akansha", 21);

		emps.add(emp1);
		emps.add(emp2);
		emps.add(emp3);
		emps.add(emp4);

	}

	public List<Employee> all() {
		return emps;
	}

	public Employee byId(final Integer id) {
		for (Employee emp : all()) {
			if (id.equals(emp.getId())) {
				return emp;
			}
		}
		return EMP_NOT_FOUND;
	}

	public Employee lockEmployee(final Integer id) {
		Employee emp = byId(id);
		emp.setLock(true);
		return emp;
	}

	public Employee unlockEmployee(final Integer id) {
		Employee emp = byId(id);
		emp.setLock(false);
		return emp;
	}

	public Employee saveEmployee(final EmployeeRequestDto employee) {
		final Employee emp = new Employee(employee.getName(), employee.getAge());
		emps.add(emp);
		return emp;
	}
}

Step 5: Define EmployeeController class.

 

EmployeeController.java

package com.sample.app.controller;

import javax.validation.Valid;

import com.sample.app.model.Employee;
import com.sample.app.model.EmployeeRequestDto;
import com.sample.app.service.EmployeeService;

import io.micronaut.core.annotation.NonNull;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Consumes;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.CustomHttpMethod;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.PathVariable;
import io.micronaut.http.annotation.Post;
import io.micronaut.http.annotation.Produces;
import jakarta.inject.Inject;

@Controller("/employees")
public class EmployeeController {

	@Inject
	private EmployeeService employeeService;

	@CustomHttpMethod(method = "LOCK", value = "/lock-employee/{employeeId}")
	public Employee lockEmployee(@NonNull @PathVariable(name = "employeeId") final Integer empId) {
		return employeeService.lockEmployee(empId);
	}

	@CustomHttpMethod(method = "UNLOCK", value = "/unlock-employee/{employeeId}")
	public Employee unlockEmployee(@NonNull @PathVariable(name = "employeeId") final Integer empId) {
		return employeeService.unlockEmployee(empId);
	}

	@Get("/{employeeId}")
	public Employee byId(@NonNull @PathVariable(name = "employeeId") final Integer empId) {
		return employeeService.byId(empId);
	}

	@Post
	@Consumes(MediaType.APPLICATION_JSON)
	@Produces(MediaType.APPLICATION_JSON)
	public Employee save(@Valid @Body final EmployeeRequestDto employeeRequestDto) {
		return employeeService.saveEmployee(employeeRequestDto);
	}

}

Step 6: Define main application class.

 

App.java

package com.sample.app;

import io.micronaut.runtime.Micronaut;

public class App {

	public static void main(String[] args) {
		Micronaut.run(App.class);
		
		// Use this if you want the beans to be initialized eagerly
		/*Micronaut.build(args)
        .eagerInitSingletons(true) 
        .mainClass(App.class)
        .start();*/
	}
}

Total project structure looks like below.




Build the project using mvn package command.

Navigate to the folder where pom.xml is located and execute the command ‘mvn package’.

 

Upon command successful execution, you can see the jar file ‘micronaut-rest-bind-request-body-0.1.jar’ in project target folder.

$ls ./target/
classes
generated-sources
generated-test-sources
maven-archiver
maven-status
micronaut-rest-bind-request-body-0.1.jar
original-micronaut-rest-bind-request-body-0.1.jar
test-classes

Execute below command to run the application.

java -jar ./target/micronaut-rest-bind-request-body-0.1.jar

 

Execute below command to create new employee.

curl --location --request POST 'http://localhost:8080/employees' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "Chamu",
    "age" : 32
}'

$curl --location --request POST 'http://localhost:8080/employees' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "Chamu",
    "age" : 32
}'
{"id":5,"name":"Chamu","age":32,"lock":false}

Execute below command to get the employee details.

curl --location --request GET 'http://localhost:8080/employees/5'
$curl --location --request GET 'http://localhost:8080/employees/5'
{"id":5,"name":"Chamu","age":32,"lock":false}

By default, response code 200 is set on success, but on new object creation, we should set the response code as 201. We can use HttpResponse class to handle this.

@Post
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public HttpResponse<Employee> save(@Valid @Body final EmployeeRequestDto employeeRequestDto) {
	final Employee emp = employeeService.saveEmployee(employeeRequestDto);
	return HttpResponse.status(HttpStatus.CREATED).body(emp);
}

You can download this application from this link.


 

Previous                                                    Next                                                    Home

No comments:

Post a Comment