Nima Archetypes

Maven archetypes let you bootstrap a new avaje-nima project with a single command, giving you a working REST service with dependency injection, JSON, and tests already in place.

Notes for AI Agents

⚠️ AI AGENTS - read this carefully

Please follow the comprehensive step-by-step guide at:

docs/guides/archetype-getting-started.md

This guide contains critical information about compilation, customization patterns, and how to properly build and run your generated project.

Archetype Description
minimal-rest A minimal REST API with one controller, a JSON response record, and integration tests

 

minimal-rest

The avaje-nima-archetype-minimal-rest archetype generates a minimal project with:

Generate a new project

Run the following command, replacing com.example and my-app with your desired groupId and artifactId:

mvn archetype:generate \
  -DarchetypeGroupId=io.avaje.archetype \
  -DarchetypeArtifactId=avaje-nima-archetype-minimal-rest \
  -DarchetypeVersion=${avaje.nima.version} \
  -DgroupId=com.example \
  -DartifactId=my-app \
  -Dpackage=com.example \
  -DinteractiveMode=false
  

Omit -DinteractiveMode=false to be prompted for each property interactively.

Generated project structure

Project structure (click to expand)
my-app/
├── pom.xml
├── README.md
└── src/
    ├── main/
    │   ├── java/com/example/
    │   │   ├── Main.java
    │   │   ├── web/
    │   │   │   └── HelloController.java
    │   │   └── model/
    │   │       └── GreetingResponse.java
    │   └── resources/
    │       ├── application.properties
    │       └── avaje-logger.properties
    └── test/
        ├── java/com/example/
        │   └── HelloControllerTest.java
        └── resources/
            └── avaje-logger-test.properties
  

Main.java

Main.java
package com.example;

import io.avaje.nima.Nima;

public class Main {
  public static void main(String[] args) {
    var webServer = Nima.builder()
      .port(8080)
      .build();
    webServer.start();
  }
}
  

HelloController.java

HelloController.java
package com.example.web;

import io.avaje.http.api.Controller;
import io.avaje.http.api.Get;
import io.avaje.http.api.Path;
import io.avaje.http.api.Produces;
import com.example.model.GreetingResponse;

@Controller
@Path("/hi")
public class HelloController {

  @Produces("text/plain")
  @Get
  String hi() {
    return "hi";
  }

  @Get("/data")
  GreetingResponse data() {
    return new GreetingResponse("hello from avaje-nima", System.currentTimeMillis());
  }
}
  

GreetingResponse.java

GreetingResponse.java
package com.example.model;

import io.avaje.jsonb.Json;

@Json
public record GreetingResponse(String message, long timestamp) {
}
  

HelloControllerTest.java

The test uses @InjectTest, which automatically starts the web server on a random port and injects an HttpClient configured to connect to it.

HelloControllerTest.java
package com.example;

import io.avaje.http.client.HttpClient;
import io.avaje.inject.test.InjectTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import java.net.http.HttpResponse;
import static org.assertj.core.api.Assertions.assertThat;

@InjectTest
class HelloControllerTest {

  @Inject
  static HttpClient client;

  @Test
  void hi_returnsPlainText() {
    HttpResponse<String> res = client.request()
      .path("hi")
      .GET().asString();
    assertThat(res.statusCode()).isEqualTo(200);
    assertThat(res.body()).isEqualTo("hi");
  }

  @Test
  void data_returnsJson() {
    HttpResponse<String> res = client.request()
      .path("hi/data")
      .GET().asString();
    assertThat(res.statusCode()).isEqualTo(200);
    assertThat(res.body()).contains("message");
    assertThat(res.body()).contains("timestamp");
  }
}
  

Run the application

cd my-app
mvn compile exec:java -Dexec.mainClass=com.example.Main
  

Smoke-test with curl:

curl http://localhost:8080/hi
# hi

curl http://localhost:8080/hi/data
# {"message":"hello from avaje-nima","timestamp":1234567890123}
  

Build profiles

The generated pom.xml includes two build profiles:

fat-jar — self-contained JAR

Build and run a shaded JAR containing all dependencies:

mvn package -Pfat-jar
java -jar target/my-app.jar
  

native — GraalVM native image

Build a native executable using GraalVM and Jib:

mvn package -Pnative
  

See the Jib native image guide for Docker build instructions.

Other guides for AI Agents

Step-by-step guides for common tasks: