REST Server Overview
A REST resource is simply a Java class annotated with @Rest. The most common case is a class that extends BasicRestServlet, which itself is simply an extension of HttpServlet which allows it to be deployed as a servlet.
The canonical in-tree sample application is the juneau-petstore, which ships two deployments — one using Jetty/Microservice and one using Spring Boot — both running the same REST surface unchanged.
org.apache.juneau.petstore.jettyorg.apache.juneau.petstore.springbootThe Spring Boot deployment is described in more detail in the Spring Boot Overview section.
Jetty / Microservice bootstrap
The Jetty deployment's entry point locates juneau-petstore-jetty.cfg, wires Jetty via JettyConfiguration, and
mounts RootResources as the root servlet:
public class App {
public static void main(String[] args) throws Exception {
Microservice
.create()
.args(args)
.configurations(JettyConfiguration.class, AppConfig.class)
.build()
.start()
.startConsole()
.join();
}
@Configuration
public static class AppConfig {
@Bean
public Servlet rootResources() {
return new RootResources();
}
}
}
The root resources class (RootResources) is the router page that the petstore uses to attach children to, including the /console admin console (PetstoreConsoleResource):
@Rest(
title="Juneau Petstore (Jetty)",
description="Apache Juneau petstore sample application running under Jetty/Microservice.",
children={
PetstoreConsoleResource.class,
ConsoleAssetsRest.class,
PetStoreResource.class,
PetstoreUiResource.class,
ConfigResource.class,
LogsResource.class,
ShutdownResource.class
}
)
@HtmlDocConfig(
widgets={
ContentTypeMenuItem.class
},
navlinks={
"api: servlet:/api",
"stats: servlet:/stats",
"$W{ContentTypeMenuItem}",
"source: $C{Source/gitHub}/org/apache/juneau/petstore/jetty/RootResources.java"
},
aside={
"<div class='text'>",
" <p>Apache Juneau petstore sample application.</p>",
" <p>This is a 'router' page that serves as a jumping-off point to the petstore CRUD resource and",
" the microservice admin endpoints.</p>",
" <p>Click <span class='link'>API</span> for the generated swagger doc, or <span class='link'>STATS</span>",
" for runtime statistics.</p>",
"</div>"
},
asideFloat="RIGHT"
)
@SerializerConfig(
quoteChar="'"
)
public class RootResources extends BasicRestServletGroup {
private static final long serialVersionUID = 1L;
}
The ConfigResource/LogsResource/ShutdownResource admin trio comes from the juneau-microservice-examples module
(package org.apache.juneau.microservice.examples), which juneau-petstore-jetty depends on for this demo — see
Predefined Resource Classes.
In the petstore, a GET of the root path answers with a 303 redirect to the store page of the console
(/console/store), so a browser opening http://localhost:10000 lands on the console rather than on a router page.
The child resources stay reachable at their own paths, and api and stats work as navlinks from any of them. See
Juneau Petstore for a tour of the console.
Spring Boot bootstrap
The Spring Boot deployment's entry point boots an embedded servlet container and wires RootResources via
ServletRegistrationBean:
@SpringBootApplication
@Controller
public class App {
public static void main(String[] args) {
new SpringApplicationBuilder(App.class).run(args);
}
@Bean
public HelloMessageProvider helloMessageProvider() {
return new HelloMessageProvider("Hello from Spring-injected bean!");
}
@Bean
public HelloResource helloResource() {
return new HelloResource();
}
@Bean
public RootResources rootResources() {
return new RootResources();
}
@Bean
public ServletRegistrationBean<Servlet> rootServlet(RootResources rootResources) {
return new ServletRegistrationBean<>(rootResources, "/*");
}
}
The Spring Boot root router extends BasicSpringRestServletGroup so child resources resolve as Spring beans:
@Rest(
title="Juneau Petstore (Spring Boot)",
description="Apache Juneau petstore sample application running under Spring Boot.",
children={
PetstoreConsoleResource.class,
ConsoleAssetsRest.class,
PetStoreResource.class,
PetstoreUiResource.class,
HelloResource.class
}
)
public class RootResources extends BasicSpringRestServletGroup {
private static final long serialVersionUID = 1L;
}
The HelloResource child demonstrates Spring @Autowired injection of a HelloMessageProvider bean:
@Rest(
path="/hello",
title="Hello (Spring injection demo)",
description="A trivial REST resource demonstrating Spring @Autowired injection of a HelloMessageProvider bean."
)
public class HelloResource extends BasicRestResource {
@Autowired
private HelloMessageProvider messageProvider;
@RestGet(path="/*", summary="Responds with the Spring-injected message.")
public String sayHello() {
return messageProvider.get();
}
}
It doesn't get much simpler than that.
In this case, we're simply returning a string that will be converted to any of the supported languages (e.g.
JSON, XML, HTML, ...).
However, we could have returned any POJO consisting of beans, Maps, Collections, etc...
For the full petstore walkthrough — modules, resources, running the app — see juneau-petstore Overview.
Other notes
- Subclasses can use either HttpServlet.init(ServletConfig) or HttpServlet.init() for initialization just like any other servlet.
- The
X-Response-Headersrequest header can be used to pass through header values into the response.- The value should be a UON-encoded map of key-value pairs. For example, to add a
Refresh: 1header to the response to auto-refresh a page, the following request header can be specified:X-Response-Headers: (Refresh=1)
- The value should be a UON-encoded map of key-value pairs. For example, to add a