<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-rest-server</artifactId>
<version>9.0-B1</version>
</dependency>
juneau-rest-server-9.0-B1.jar
org.apache.juneau.rest.server_9.0-B1.jar
The REST server API builds upon the SerializerGroup
and ParserGroup
classes
to provide annotated REST servlets that automatically negotiate the HTTP media types for you.
Developers simply work with requests, responses, headers, path variables, query parameters, and form data as POJOs.
It allows you to create sophisticated REST interfaces using tiny amounts of code.
The end goal is to provide simple and flexible yet sophisticated REST interfaces that allow POJOs to be automatically represented as
different content types depending on whatever the particular need:
- HTML for viewing POJOs in easy-to-read format in a browser.
- JSON for interacting through Javascript.
- XML for interacting with other applications.
- RDF for interacting with triple stores.
- URL-Encoding for interacting through HTML forms.
- MessagePack for efficiently transmitting large amounts of data.
A simple example that supports all languages:
@Rest(
path="/systemProperties",
title="System properties resource"
)
public class SystemPropertiesResource extends BasicRestServlet {
@RestMethod(name=GET, path="/")
public Map getSystemProperties(@Query("sort") boolean sort) throws Throwable {
if (sort)
return new TreeMap(System.getProperties());
return System.getProperties();
}
@RestMethod(name=GET, path="/{propertyName}")
public String getSystemProperty(@Path("propertyName") String propertyName) throws Throwable {
return System.getProperty(propertyName);
}
@RestMethod(name=PUT, path="/{propertyName}", guards=AdminGuard.class)
public String setSystemProperty(@Path("propertyName") String propertyName, @Body String value) {
System.setProperty(propertyName, value);
return "OK";
}
@RestMethod(name=POST, path="/", guards=AdminGuard.class)
public String setSystemProperties(@Body java.util.Properties newProperties) {
System.setProperties(newProperties);
return "OK";
}
@RestMethod(name=DELETE, path="/{propertyName}", guards=AdminGuard.class)
public String deleteSystemProperty(@Path("propertyName") String propertyName) {
System.clearProperty(propertyName);
return "OK";
}
}
The REST API is built on top of Servlets, making them easy to deploy in any JEE environment.
REST Java methods can return any of the following objects:
POJOs, @Response annotated objects, Readers
, InputStreams
, ZipFiles
, Redirects
, Streamables
, and Writables
.
Or add your own handlers for other types.
REST Java methods can be passed any of the following objects in any order:
- Low-level request/response objects:
HttpServletRequest
, HttpServletResponse
, RestRequest
, RestResponse
.
- Intermediate-level objects:
RequestHeaders
, RequestQuery
, RequestFormData
, RequestPathMatch
, RequestBody
.
- All RFC 2616 request header objects:
Accept
, AcceptLanguage
, AcceptEncoding
...
- Annotated parameters:
@Header, @Query, @FormData, @Path, @PathRemainder, @Body.
- Other objects:
Locale
, ResourceBundle
, MessageBundle
, InputStream
, OutputStream
, Reader
, Writer
...
- User-defined parameter types.
Automatic error handling is provided for a variety of conditions:
- Automatic 401 errors (Unauthorized) on failed guards.
- Automatic 404 errors (Not Found) on unmatched path patterns.
- Automatic 405 errors (Method Not Implemented) on unimplemented methods.
- Automatic 406 errors (Not Acceptable) when no matching serializer was found to handle the Accept header.
- Automatic 412 errors (Precondition Failed) when all matchers failed to match.
- Automatic 415 errors (Unsupported Media Type) when no matching parser was found was found to handle the Content-Type header.
- Automatic 500 errors on uncaught exceptions.
- Throw your own runtime RestException with HTTP status and response object.
Other features include:
- Extremely simple debuggability using nothing more than your browser.
- Simplified localization support.
- Configurability through external INI files.
- Client-versioned responses (and other customizable heuristic matching APIs).
- Automatic statistics gathering.
- Define and use your own HTML stylesheets.
- Lots of up-to-date documentation and examples.
- MUCH MORE!....
Navigable hierarchies of REST resources are easy to set up either programmatically or through annotations.
The following example is the RootResources
class from the REST examples showing how to construct
a grouping of resources using the children()
annotation:
@Rest(
path="/",
title="Root resources",
description="Example of a router resource page.",
children={
HelloWorldResource.class,
PetStoreResource.class,
DtoExamples.class,
ConfigResource.class,
LogsResource.class,
ShutdownResource.class
}
)
@HtmlDocConfig(
links={
"options: ?method=OPTIONS",
"$W{ContentTypeMenuItem}",
"source: $C{Source/gitHub}/org/apache/juneau/examples/rest/RootResources.java"
},
aside={
"<div style='max-width:400px' class='text'>",
" <p>This is an example of a 'router' page that serves as a jumping-off point to child resources.</p>",
" <p>Resources can be nested arbitrarily deep through router pages.</p>",
" <p>Note the options link provided that lets you see the generated swagger doc for this page.</p>",
" <p>Also note the source link on these pages to view the source code for the page.</p>",
" <p>All content on pages in the UI are serialized POJOs. In this case, it's a serialized array of beans with 2 properties, 'name' and 'description'.</p>",
" <p>Other features (such as this aside) are added through annotations.</p>",
"</div>"
},
footer="$W{PoweredByApache}",
widgets={
PoweredByApache.class,
ContentTypeMenuItem.class
}
)
public class RootResources extends BasicRestServletGroup { /* No code needed! */ }
The above resource when rendered in HTML shows how easy it is to discover and navigate to child resources using a browser:
http://localhost:10000
Resources can be nested arbitrarily deep.
The @Rest and @RestMethod annotations can be applied to any classes, not just
servlets. The only requirement is that the top-level resource be a subclass of RestServlet
as a hook into
the servlet container.
The juneau-examples-rest
project includes various other examples that highlight some of the
capabilities of the REST servlet API.
For example, the PetStoreResource
class shows some advanced features such as using POJO renders
and converters, and HTML widgets.
http://localhost:10000/petstore
The beans being serialized are shown here:
// Our bean class.
public class Pet {
@Html(link="servlet:/{id}") // Creates a hyperlink in HTML view.
@NameProperty // Links the parent key to this bean.
public int id;
public String name;
public Kind kind;
@Beanp(format="$%.2f") // Renders price in dollars.
public float price;
@Beanp(swap=DateSwap.RFC2822D.class) // Renders dates in RFC2822 format.
public Date birthDate;
public int getAge() {
Calendar calendar = new GregorianCalendar();
calendar.setTime(birthDate);
return new GregorianCalendar().get(Calendar.YEAR) - calendar.get(Calendar.YEAR);
}
}
@Html(render=KindRender.class) // Render as an icon in HTML.
public static enum Kind {
CAT, DOG, BIRD, FISH, MOUSE, RABBIT, SNAKE
}
public static class KindRender extends HtmlRender<Kind> {
@Override
public Object getContent(SerializerSession session, Kind value) {
return new Img().src("servlet:/htdocs/"+value.toString().toLowerCase()+".png");
}
@Override
public String getStyle(SerializerSession session, Kind value) {
return "background-color:#FDF2E9";
}
}
The QUERY
menu item shows the capabilities of Converters which are post-processors that
work to filter POJOs after they've been returned by your Java method.
In this case, we're using the Queryable
converter that allows us to perform search/view/sort/paging
against collections of beans:
The drop-down menu items are implemented through "widgets" which allow you to embed arbitrary HTML, Javascript,
and CSS in the HTML view of the page.
@RestMethod(
name=GET,
path="/",
summary="The complete list of pets in the store",
// Add our converter for POJO query support.
converters=Queryable.class
)
@HtmlDocConfig(
// Add our menu items in the nav links.
links={
"up: request:/..",
"options: servlet:/?method=OPTIONS",
"$W{QueryMenuItem}",
"$W{ContentTypeMenuItem}",
"$W{StyleMenuItem}",
"source: $C{Source/gitHub}/org/apache/juneau/examples/rest/PetStoreResource.java"
},
// Add 'query' and 'content-types' menu items.
widgets={
QueryMenuItem.class,
ContentTypeMenuItem.class,
StyleMenuItem.class
}
)
public Collection<Pet> getPets() {
HTML views are highly customizable with abilities such as defining your own look-and-feel and even allowing
you to define your own templates.
For example, the PetStore page above rendered in one of the other predefined stylesheets:
Swagger UI is auto-generated and self-hosted through OPTIONS requests:
http://localhost:10000/petstore?method=OPTIONS
Swagger contains auto-generated code examples for all supported languages: