Skip to main content

3. Your First REST App

A Juneau REST resource is a plain class annotated with @Rest. Methods annotated with @RestGet, @RestPost, and friends become endpoints, and return values are serialized according to the client's Accept header.

See the guide: Build a REST API on Spring Boot

Create src/main/java/com/example/demo/PetResource.java. Pet is the bean from the previous page.

package com.example.demo;

import org.apache.juneau.http.*;
import org.apache.juneau.rest.server.*;
import org.apache.juneau.rest.server.servlet.*;

@Rest(path="/pets", title="Pet service")
public class PetResource extends BasicRestServlet {

@RestGet("/{id}")
public Pet getPet(@Path("id") int id) {
return new Pet(id, "Fido");
}
}

The same method answers Accept: application/json, text/xml, text/html (a browsable page), and the other formats registered on the resource, with no extra code.

Servlet or Resource?​

tip

BasicRestServlet is an HttpServlet, so it can be a top-level resource in any servlet container or in the Jetty microservice. BasicRestResource is the same resource without the servlet base class: use it for child resources (@Rest(children=...)) and for Spring Boot beans. See REST Children and Spring Boot REST API.

Run it​

The Jetty microservice bundle in your pom.xml includes an embedded Jetty server. Create src/main/java/com/example/demo/App.java to start it with PetResource as the root resource:

package com.example.demo;

import org.apache.juneau.microservice.jetty.*;

public class App {
public static void main(String[] args) throws Exception {
JettyMicroservice.run(args, new PetResource(), false).join();
}
}

The server writes its request log to a logs directory in the working directory, creating it if needed. Start the app:

mvn compile exec:java -Dexec.mainClass=com.example.demo.App

When it is up (the first build downloads Jetty, so allow a minute), call it from a second terminal:

curl -H "Accept: application/json" http://localhost:10000/pets/1
# {"id":1,"name":"Fido"}

curl -H "Accept: text/xml" http://localhost:10000/pets/1
# <?xml version="1.0" encoding="UTF-8"?><object><id>1</id><name>Fido</name></object>

You can also open http://localhost:10000/pets/1 in a browser to see the HTML view. Leave the server running for the next page, and press Ctrl+C when you are done. The walkthrough assumes the default port, 10000, so stop anything else that is using it first. If port 10000 is taken, the curl commands and the client on the next page can hit the wrong process and return a 404.

Prefer a ready-made project? The starter projects package the same idea with Jetty, Spring Boot, or Tomcat. You do not need one for this walkthrough.

Test it without a server​

juneau-rest-mock dispatches requests to your resource in-process, so there is nothing to start:

import org.apache.juneau.rest.mock.*;

try (MockRestClient mock = MockRestClient.create(PetResource.class);
var resp = mock.get("/1").run()) {
resp.assertThat().isOk().body().contains("Fido");
}

The mock client mounts the resource at its @Rest(path), so the request path is relative to /pets. Put the snippet in a main method (or a unit test) to run it; the juneau-rest-mock dependency is already in your pom.xml.

See NG Mock REST Client for more.

Learn more​

  • juneau-rest-server: annotations, content negotiation, Swagger, and the rest.
  • Petstore: a complete REST application, including HTML views and a UI.

Next​

Your first client