Tuesday, 27 June 2023

Micronaut: support non-standard HTTP methods

@CustomHttpMethod annotation support non-standard http methods, that you can provide by specifying the required method property.

 

Examples

@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);
}

 

@CustomHttpMethod annotation can be used anywhere the standard method annotations can be used, including controllers and declarative HTTP clients

 

Find the below working application.

 

Step 1: Create new maven project ‘micronaut-rest-non-standard-methods’.

 

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-non-standard-methods</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 Employee model class.

 

Employee.java

package com.sample.app.model;

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

import io.micronaut.core.annotation.NonNull;

public class Employee {

	@NonNull
	@Positive
	private Integer id;

	@NotBlank
	private String name;

	@NonNull
	@Positive
	private Integer age;

	private Boolean lock = false;

	public Employee() {
	}

	public Employee(Integer id, String name, Integer age) {
		this.id = id;
		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 jakarta.inject.Singleton;

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

	private static int counter = 4;

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

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

	}

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

	public Employee add(final Employee emp) {
		emp.setId(counter);
		counter++;

		emps.add(emp);
		return emp;
	}

	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;
	}
}

Step 5: Define EmployeeController class.

 

EmployeeController.java

package com.sample.app.controller;

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

import io.micronaut.core.annotation.NonNull;
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 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);
	}

}

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-non-standard-methods-0.1.jar’ in project target folder.

$ls ./target/
classes
generated-sources
generated-test-sources
maven-archiver
maven-status
micronaut-rest-non-standard-methods-0.1.jar
original-micronaut-rest-non-standard-methods-0.1.jar
surefire-reports
test-classes

Execute below command to run the application.


java -jar ./target/micronaut-rest-non-standard-methods-0.1.jar

 

Execute below commands to confirm the functionality.

curl --location --request GET 'http://localhost:8080/employees/1'
curl --location --request LOCK 'http://localhost:8080/employees/lock-employee/1'
curl --location --request GET 'http://localhost:8080/employees/1'
curl --location --request UNLOCK 'http://localhost:8080/employees/unlock-employee/1'
curl --location --request GET 'http://localhost:8080/employees/1'

$curl --location --request GET 'http://localhost:8080/employees/1'
{"id":1,"name":"Sunil","age":23,"lock":false}%                                                                           $
$
$curl --location --request LOCK 'http://localhost:8080/employees/lock-employee/1'
{"id":1,"name":"Sunil","age":23,"lock":true}%                                                                            $
$
$curl --location --request GET 'http://localhost:8080/employees/1'               
{"id":1,"name":"Sunil","age":23,"lock":true}%                                                                            $
$
$curl --location --request UNLOCK 'http://localhost:8080/employees/unlock-employee/1'
{"id":1,"name":"Sunil","age":23,"lock":false}%                                                                           $
$curl --location --request GET 'http://localhost:8080/employees/1'                   
{"id":1,"name":"Sunil","age":23,"lock":false}%

You can download this application from this link.







 

 

 

 

Previous                                                    Next                                                    Home

No comments:

Post a Comment