This page gives an overview of a REST implementation, using the Atlassian REST plugin module.
Given a URL like this:
1 2http://myhost.com:port/myapp/rest/api-name/api-version/resource-name
We can break the URL into these parts:
http://myhost.com:port
/myapp
/rest
/api-name/api-version
/resource-name
Mapping each part of the URL:
The operating system directs the request to the application server (e.g. Tomcat) that handles the specified port.
Tomcat directs the request to the application myapp
.
The application's web.xml deployment descriptor file maps the URLs to the relevant servlets. So in this case, it maps /rest
to our REST servlet, which points to our REST plugin module type.
Now the REST plugin module takes over. The relevant part of the URL (api-name
and api-version
) are defined as the path
and version
in the atlassian-plugin.xml
file e.g.
1 2<rest key="helloWorldRest" path="/helloworld" version="1.0"> <description>Provides hello world services.</description> </rest>
The final part of the URL mapping (resource-name
and sub-elements) is done via annotations on the class, used to declare the URI path, the HTTP method and the media type. Jersey (based on JAX-RS) reads the @Provider
and @Path
annotations and maps them to classes and methods, so that we know which method is called for each REST resource and method. See the Jersey documentation.
JAXB converts the Java classes to XML or JSON and vice versa, making use of JAXB annotations. (Available in Java 1.5 and later.)
For example a Java User
object with JAXB annotations may look something like this:
1 2import javax.xml.bind.annotation.*; @XmlRootElement public class User { @XmlElement private String firstName; @XmlElement private String lastName; // This private constructor isn't used by any code, but JAXB requires any // representation class to have a no-args constructor. private User() { } public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } ... }
The XML response content for user John Smith would be:
1 2<user> <firstName>John</firstName> <lastName>Smith</lastName> </user>
By default, on conversion the XML element name will be the same as the object name. Alternatively, you can add the XML element name to the annotation. Something like this: @XmlRootElement(name="principal")
. There are specific annotations for arrays, etc. See JAXB's documentation for more details on this.
We have no schema or DTD.
Jersey also handles JSON based on the same JAXB objects as in the example above. The JSON for the example would be:
1 2{ "firstName":"John", "lastName":"Smith" }
A trivial REST service class with a single URL returning an instance of User
would look like this:
1 2import javax.ws.rs.*; import javax.ws.rs.core.*; @Path("/") @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public class RestHelloWorldService { @GET @Path("users") public Response getUncompletedUsers() { return Response.ok(new User("Fred","Bloggs")).build(); } }
Developing a REST Service Plugin
REST Plugin Module
Guidelines for Atlassian REST API Design
Rate this page: