Java server side API
Java™ adapters can use the IBM MobileFirst™ Platform Server Java API to perform server-related operations such as: calling other adapters, submitting push notifications, logging on to the server log, getting values of configuration properties, reporting activities to analytics, and getting the identity of the request issuer.
WLServerAPI serverApi = WLServerAPIProvider.getWLServerAPI();
The WLServerAPI interface is the parent
of all the API categories: analytics, configuration, push, adapters,
authentication. If you want to use the push API, you can write: PushAPI pushApi = serverApi.getPushAPI();
For more information on the Java API, see the com.worklight.adapters.rest.api package. Examples of the use of the API are provided in the following sections.
- Logger
- Adding a logger to the JAX-RS resource of your adapter is essential
for logging debug information, information, warnings,
and errors to the MobileFirst Server log.
In the Java adapters, you can
use the standard java.util.logging logger.
To add logger declare the following static
field:
static Logger logger = Logger.getLogger(UsersResource.class.getName());
Note: The logger is part of the new adapter template, so in most cases, there is no need to add it. - Push API
- You can extend the UsersResource described
in Implementing the JAX-RS service of the adapter to notify all
the devices of a user when the user record is
updated:
WLServerAPI serverAPI = WLServerAPIProvider.getWLServerAPI(); @PUT @Consumes(MediaType.APPLICATION_JSON) public Response updateUser(User u) { //TODO Really update the user... //Notify all devices that the user has been updated PushAPI push = serverAPI.getPushAPI(); INotification notification = push.buildNotification(); notification.getTarget().setUserIds(u.getId());//Targeted only for the updated user JSONObject payload = new JSONObject(); payload.put("user", u.getId()); notification.getSettings().getAPNS().setPayload(payload); try { push.sendMessage(notification, "myApp"); } catch (MFPSendMessageFailedException e) { e.printStackTrace(); //Ignore failure in this case, since the update succeeded. } return Response.ok().build(); }
- Security API
- The security API provides the security context object that contains
information about the identity of the request
issuer. In the following example, a new validation is
added to the user's resource: User records can be updated
only by users themselves:
WLServerAPI serverAPI = WLServerAPIProvider.getWLServerAPI(); @PUT @Consumes(MediaType.APPLICATION_JSON) publis Response updateUser(User u) { SecurityAPI security = serverAPI.getSecurityAPI(); String requestIssuerUserId = security.getSecurityContext().getUserIdentity().getId(); if (!u.getId().equals(requestIssuerUserId)){ return Response.status(Status.FORBIDDEN) .entity("The user: "+requestIssuerUserId+ " is not allowed to modify the user record of another user").build(); } //TODO Really update the user...
- Adapters API
- The adapters API makes it easy to perform requests to other adapters
in the same server.
The following example shows how to use the adapters API to call a JavaScript adapter:
@Path("/") public class JavaAdapter1Resource { static Logger logger = Logger.getLogger(JavaAdapter1Resource.class.getName()); @GET @Path("/calljs") @Produces("application/json") public JSONObject callJSAdapterExample() throws Exception{ AdaptersAPI adaptersAPI = WLServerAPIProvider.getWLServerAPI().getAdaptersAPI(); //Using helper method to create a request to the JS adapter HttpUriRequest req = adaptersAPI.createJavascriptAdapterRequest("JSAdapter", "getStories"); //Execute the request and get the response HttpResponse resp = adaptersAPI.executeAdapterRequest(req); //Convert the response to JSON since we know that JS adapters always return JSON JSONObject json = adaptersAPI.getResponseAsJSON(resp); //Return the json response as the response of the current request that is being taking care of return json; }
- Configuration API
- The configuration API enables the adapter to read server-side
configuration properties defined in the worklight.properties file
or as JNDI entries. For more information about MobileFirst configuration
properties, see CLI Commands.
For example, to get the value of the serverSessionTimeout property, write the following code:
String serverSessionTimeout = serverAPI.getConfigurationAPI().getMFPConfigurationProperty("serverSessionTimeout");
- Saving applicative state between requests in Java RESTful adapters
In versions earlier than V7.1.0, developers were able to store the applicative state in the HTTP session, by using the session object, namely request.getSession() (see WL.Server).
If you are working in session-independent mode that became available starting with IBM MobileFirst Platform Foundation V7.1.0, the applicative state of the adapter must be persisted outside the session, for example, by using a database such as Cloudant®. For more information on session-independent mode, including steps for upgrading projects that were created in earlier versions of IBM MobileFirst Platform Foundation, see Session-independent mode.
The following code snippets provide examples for migrating code from an earlier version of IBM MobileFirst Platform Foundation so that it support the changes for session-independent mode in V7.1.0.
Consider a shopping-cart app, in which users can add items to a cart, see the list of items that are already in the cart, and submit an order when satisfied with the items in it.
Before V7.1.0, this functionality might have been implemented in the following code:
Assume you are using Cloudant as the persist store over the Cloudant Java Client API and that you are implementing a Java RESTful HTTP adapter called ShoppingCartAdapter. See Figure 1: using OAuthSecurityContext.getClientId(), the adapter requests the ID that is associated with the current client from MobileFirst Serverand uses it when reading or writing applicative data to or from Cloudant.//Define the server API to be able to perform server operations WLServerAPI api = WLServerAPIProvider.getWLServerAPI(); @GET @Path("/addItemToCart") public void addItemToCart(@Context HttpServletRequest request, @HeaderParam("item") String item) { String oldItems = getItemsFromCart(request); HttpSession session = request.getSession(); session.setAttribute("items", oldItems + " " + item); } @GET @Path("/getItemsFromCart") public String getItemsFromCart(@Context HttpServletRequest request) { HttpSession session = request.getSession(); return (String) session.getAttribute("items"); }
Figure 1. Retrieving applicative data using the server-side OAuthSecurityContext.getClientId API.- If you adapt the code to work in session-independent mode under
V7.1.0, the code for MobileFirst V7.1.0 might
look as follows:
//Define the server API to be able to perform server operations WLServerAPI api = WLServerAPIProvider.getWLServerAPI(); CloudantClient client = new CloudantClient("cloudantId", "username", "password"); @GET @Path("/addItemToCart") public void addItemToCart(@HeaderParam("item") String item) { // Get the clientID from the MFP API (new in 7.1.0) String userId = api.getSecurityAPI().getSecurityContext().getClientId(); saveItemToCloudant("shoppingcartdb", userId, item); } @GET @Path("/getItemsFromCart") public String getItemsFromCart() { // Get the clientID from the MFP API (new in 7.1.0) String userId = api.getSecurityAPI().getSecurityContext().getClientId(); return (String) readItemFromCloudant("shoppingcartdb", userId).get("items"); } /** * Reads a JSONObject shopping cart item from Cloudant and returns the document * that corresponds to this _id * @param db * @param key * @return a JSONObject */ public JSONObject readItemFromCloudant(String db, String key){ Database cloudantDb = client.database(db, false); // Search for the document return cloudantDb.find(JSONObject.class, key); } /** * Saves a JSONObject shopping cart item to Cloudant * @param db - the DB to save to * @param key - the _id * @param value */ public void saveItemToCloudant(String db, String key, String value){ Database cloudantDb = client.database(db, false); // Search for the document try{ JSONObject document = cloudantDb.find(JSONObject.class, key); String listOfItems = (String) document.get("items"); // Add new shopping cart item to list listOfItems += " " + value; document.put("items", listOfItems); // Update the document cloudantDb.update(document); }catch(NoDocumentException e){ // New Document JSONObject obj = new JSONObject(); obj.put("_id", key); obj.put("items", value); // Save the object to cloudant db cloudantDb.save(obj); }