For up-to-date product documentation, see the IBM MobileFirst Foundation Developer Center.
Implementing the JAX-RS service of the adapter
To implement the JAX-RS service of the adapter, we must first implement the JAX-RS application class, then implement the JAX-RS resources classes.
Parent topic: Develop Java adapter code
Implementing the JAX-RS application class
The JAX-RS application class tells the JAX-RS framework which resources are included in the application. Any resource can have a separate set of URLs. Traditionally the application class should extend javax.ws.rs.core.Application and implement the method getClasses or getSingletons that will be called by the JAX-RS framework to get information about this application.
In the following example, a JAX-RS application defines three resources: Resource1, UsersResource, and MyResourceSingleton. The first two are provided by the getClasses method, while the last is provided by getSingletons.
import java.util.HashSet; import java.util.Set; import javax.ws.rs.core.Application; public class MyApplication extends Application{ @Override public Set<Class<?>> getClasses() { HashSet<Class<?>> classes = new HashSet<Class<?>>(); classes.add(Resource1.class); classes.add(UsersResource.class); return classes; } @Override public Set<Object> getSingletons() { Set<Object> singletons = new HashSet<Object>(); singletons.add(MyResourceSingleton.getInstance()); return singletons; } }
Note: The example demonstrates how to write a pure JAX-RS application using getClasses and getSingletons. A quicker alternative is to use extends MFPJAXRSApplication. The MFPJAXRSApplication class scans the package for JAX-RS 2.0 resources and automatically creates a list. Additionally, its init method is called by MobileFirst Server as soon as the adapter is deployed, before it starts serving, and when the MobileFirst runtime starts up.
Implementing a JAX-RS resource
A JAX-RS resource is a POJO (plain old Java object) which is mapped to a root URL and has Java methods for serving requests to this root URL and its sub-URLs. For example:
import java.util.ArrayList; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; @Path("/users") //This is the root URL of the resource ("/users") public class UsersResource { //Instead of this static field, it could be a users DAO that works with Database or cloud storage static ArrayList<User> users = new ArrayList<User>(); @GET @Produces(MediaType.APPLICATION_JSON) //This will serve: GET /users public ArrayList<User> getUsers(){ return users; } @Path("/{userId}") @Produces(MediaType.APPLICATION_JSON) //This will serve: GET /users/{userId} public User getUser(@PathParam("userId") String userId){ return findUserById(userId); } @POST @Consumes(MediaType.APPLICATION_JSON) //This will serve: POST /users public void addUser(User u) { users.add(u); } @PUT @Consumes(MediaType.APPLICATION_JSON) //This will serve: PUT /users public Response updateUser(User u) { User user = findUserById(u.getId()); if (user == null){ return Response.status(Status.NOT_FOUND) .entity("User with ID: "+u.getId()+" not found") .build(); } users.remove(user); users.add(u); return Response.ok().build(); } @DELETE @Path("/{userId}") //This will serve: DELETE /users/{userId} public void deleteUser(@PathParam("userId") String userId){ User user = findUserById(userId); users.remove(user); } private User findUserById(String userId) { //TODO implement... return null; } }The resource just shown is mapped to the URL /users and serves the following requests:
Table 1. Resource requests Request Description GET /users Gets all users list POST /user Adds a new user GET /users/{userId} Gets a specific user with id userId PUT /users Updates an existing user DELETE /users/{userId} Deletes a user with id userId The JAX-RS framework does the mapping from the simple Java object User to a JSON object and conversely, thereby making it easier for the service developer to use without taking care of repeating conversion-related code. The implementation also helps in extracting parameter values from the URL and from the query string without having to parse it manually.
Configure protection of JAX-RS resources
A JAX-RS adapter resource is protected by default by the MobileFirst security framework, meaning that access to the resource requires a valid access token. See OAuth resource protection. We can configure the resource protection by using the @OAuthSecurity annotation to assign a custom security scope, or to disable resource protection. For a complete reference, see Interface OAuthSecurity. For detailed configuration instructions, see Configure protection of Java API for RESTful Web Services (JAX-RS) resources.