Micronaut @PathVariable annotation bind segments of paths to method parameters.
For example, the api to get the employee details by id looks like below.
/employees/by-id/{employeeId}
@Get("/by-id/{employeeId}")
public Employee byId(@NonNull @PathVariable(name = "employeeId") final Integer empId) {
return employeeService.byId(empId);
}
For the url '/employees/by-id/1', the argument empId is bound to the value 1.
Find the below working application.
Step 1: Create new maven project ‘micronaut-rest-path-variable’.
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-path-variable</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;
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;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
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(Integer id) {
for (Employee emp : all()) {
if (id.equals(emp.getId())) {
return emp;
}
}
return EMP_NOT_FOUND;
}
}
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.Get;
import io.micronaut.http.annotation.PathVariable;
import jakarta.inject.Inject;
@Controller("/employees")
public class EmployeeController {
@Inject
private EmployeeService employeeService;
@Get("/by-id/{employeeId}")
public Employee byId(@NonNull @PathVariable(name = "employeeId") final Integer empId) {
return employeeService.byId(empId);
}
}
Step 6: Define EmployeeControllerTest class.
EmployeeControllerTest.java
package com.sample.app.controller;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import com.sample.app.model.Employee;
import io.micronaut.context.ApplicationContext;
import io.micronaut.http.client.HttpClient;
import io.micronaut.runtime.server.EmbeddedServer;
public class EmployeeControllerTest {
private static EmbeddedServer server;
private static HttpClient client;
@BeforeAll
public static void setupServer() {
server = ApplicationContext.run(EmbeddedServer.class);
client = server.getApplicationContext().createBean(HttpClient.class, server.getURL());
}
@AfterAll
public static void stopServer() {
if (server != null) {
server.stop();
}
if (client != null) {
client.stop();
}
}
@Test
public void testIssue() {
Employee emp = client.toBlocking().retrieve("/employees/by-id/1", Employee.class);
assertEquals(1, emp.getId());
assertEquals("Sunil", emp.getName());
assertEquals(23, emp.getAge());
}
}
Step 7: 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-path-variable-0.1.jar’ in project target folder.
$ ls ./target/
classes
generated-sources
generated-test-sources
maven-archiver
maven-status
micronaut-rest-path-variable-0.1.jar
original-micronaut-rest-path-variable-0.1.jar
surefire-reports
test-classes
Execute below command to run the application.
java -jar ./target/micronaut-rest-path-variable-0.1.jar
Open the url ‘http://localhost:8080/employees/by-id/1’ to get employee details for the id 1.
You can download this application from this link.
Below table summarizes different path matching patterns.
Template |
Description |
example |
/employees/{id} |
Simple match |
/employees/1 |
/employees/{id:2} |
A variable of two characters max |
/employees/10 |
/employees{/id} |
An optional URI variable |
/employees/10 or /employees |
/employees{/id:[a-zA-Z]+}
|
An optional URI variable with regex
|
/employees/foo
|
/employees/ {?max,offset}
|
Optional query parameters
|
/employees?max=10&offset=10
|
/employees/ {/path:.*}{.ext}
|
Regex path match with extension
|
/employees/foo/bar.xml
|
No comments:
Post a Comment