ShowTable of Contents
Introduction to DAS
Domino Access Services (DAS) is a framework for adding REST services to Domino. A DAS service is implemented in Java and deployed as an OSGi plug-in. It handles HTTP requests to a URL in one of the following formats:
-
/api/{servicepath}/{resource}
-
/{database}/api/{servicepath}/{resource}
A DAS service is not tied to a specific Notes database. When handling a URL of the second form above, with a {database} segment, the service uses the specified database context, but it can be any database on the server.
Consider the Domino data and calendar services which are both included in Domino 9.0.1. Both services are implemented using the DAS framework. The data service handles requests to URLs matching:
-
/api/data
-
/{database}/api/data/{resource}
On the other hand, the calendar service handles requests to URLs matching:
-
/api/calendar
-
/{database}/api/calendar/{resource}
In other words, data is the {servicepath} segment for the data service and calendar is the {servicepath} segment for the calendar service. Both services can handle requests for a specific database indicated by the {database} segment in the URL.
A DAS service is defined with the Apache Wink framework. Apache Wink is itself an implementation of the JAX-RS specification. Both Apache Wink and JAX-RS are included in Domino 9.0.1, but this article does not discuss either one in great detail. To learn more about Apache Wink and JAX-RS, please see the references at the end of this article.
A DAS service uses the com.ibm.domino.das.service extension point to define its {servicepath} segment. This effectively adds the service to the list of REST services running on the Domino server. The com.ibm.domino.das.service extension point is not part of Apache Wink. It is unique to DAS. To learn more about the extension point, see section 3.3.
A DAS service usually consists of multiple resources. For example, a directory service might contain four types of resources: 1) a contact list, 2) a contact, 3) a group list, and 4) a group. By convention, the directory service would include a separate Java class for each resource type. Each resource class can handle one or more HTTP methods. For example, the contact class might support GET, PUT and DELETE, while the contact list class might support only GET and POST. You use JAX-RS annotations to define resource classes and the methods they support.
The sample REST service on OpenNTF
The extension library on OpenNTF includes a sample DAS service called com.ibm.domino.services.sample. You can download an extension library release from http://extlib.openntf.org/. As of this article's original publish date, the most recent release of the extension library is version 7 for Domino 9.0.1, but please be sure to get the latest release.
Once you have downloaded the extension library ZIP file, you can find the sample service plug-in is in an update site called updateSiteOpenNTFSamples.zip. You can install the sample service on your Domino server by unzipping the contents of this update site into the domino\workspace\applications\eclipse folder of your Domino data directory. Alternatively, you can use NSF-based update site deployment. See section 4 for more details.
The sample service defines two resources. The “root resource” handles a GET request to: /api/sample. The service returns a response in JSON format like this:
{
"links":[
{
"rel":"contacts",
"href":"\/xpagesext.nsf\/api\/sample\/contacts"
}
]
}
In other words, the response includes a link to the contacts resource – a list of contacts in the xpagesext.nsf database. If the service defined other resource types, the response would include more elements in the links array.
The contacts resource handles a GET request to: /xpagesext.nsf/api/sample/contacts. This returns a response in JSON format like this:
[
{
"firstName":"Addie",
"lastName":"Pate",
"emailAddress":"addie_pate@renovations.com",
"city":"Dayton",
"state":"OH",
"href":"\/xpagesext.nsf\/api\/sample\/contacts\/F89EC6B0B37686A5852578FC005E4061"
},
{
"firstName":"Adrienne",
"lastName":"Middleton",
"emailAddress":"adrienne_middleton@renovations.com",
"city":"Palm Bay",
"state":"DL",
"href":"\/xpagesext.nsf\/api\/sample\/contacts\/C27592F4FEDA5929852578FC005E3FBC"
},
{
"firstName":"Albert",
"lastName":"Wiley",
"emailAddress":"albert_wiley@renovations.com",
"city":"Lafayette",
"state":"LA",
"href":"\/api\/sample\/contacts\/C2E3338C09947B3E852578FC005E4042"
},
…
]
In other words, the response includes summary information about each contact in the AllContacts view of xpagesext.nsf. Each contact object has properties for first name, last name, email address, etc.
Obviously, the sample service is not complete. For example, a real service would include the ability to create new contacts. A real service would let you read, update and delete existing contacts. A real service might also include more resource types. However, the sample service does demonstrate the minimum work required to create your own DAS service. The following sections describe how to develop, deploy and manage a DAS service. As you read these sections, please refer to the sample service code. See srcOpenNTFSamples.zip in the extension library ZIP file.
NOTE: Before you can use the sample service on your own Domino server, you need to enable the service. See section 5 for more on enabling DAS services.
Create your REST service
A DAS service is implemented as an OSGi plug-in. The plug-in includes one or more JAX-RS resources and implements an extension that causes the resources to be registered with the Domino DAS servlet.
The DAS servlet listens for HTTP requests to any URL starting with either of the following:
When you implement a DAS extension, you effectively add a unique {servicepath} segment to the DAS servlet:
-
/api/{servicepath}
-
/{database}/api/{servicepath)
All of your service resources have a unique URL, but each will have the same {servicepath} in common.
NOTE: You can also create a Wink service in a separate OSGi servlet. Such a service would not be an extension to DAS and its URLs would not include /api in the path. This document does not describe how to build your on servlet. It is much easier to build a service that extends DAS.
The following sections describe more details on developing a DAS service.
Define service resources
Your DAS service must include one or more resource classes. A resource class is usually tied to a particular URL path, as indicated by the @Path annotation. Each resource class should have at least one method annotated with @GET, @POST, @PUT or @DELETE. As an example, consider the following excerpt from com.ibm.domino.services.sample.resources.RootResource.
@Path("sample")
public class RootResource {
...
@GET
public Response getLinks(@Context UriInfo uriInfo) {
SAMPLE_SERVICE_LOGGER.traceEntry(this, "getLinks"); // $NON-NLS-1$
String jsonEntity = null;
try {
jsonEntity = getResponseEntity();
}
catch (IOException e) {
throw new WebApplicationException(SampleService.createErrorResponse(e));
}
catch (JsonException e) {
throw new WebApplicationException(SampleService.createErrorResponse(e));
}
ResponseBuilder builder = Response.ok();
builder.type(MediaType.APPLICATION_JSON_TYPE).entity(jsonEntity);
Response response = builder.build();
SAMPLE_SERVICE_LOGGER.traceExit(this, "getLinks", response);
return response;
}
...
}
This class defines a resource that handles GET requests to /api/sample. Usually, a service contains many resource classes including some that handle multiple HTTP request methods. For more information on JAX-RS resource classes and annotations, please see the references section at the end of this article.
Create a subclass of RestService
Now that your plug-in contains resource classes, you need to create a subclass of com.ibm.domino.das.service.RestService. For example, consider this excerpt from com.ibm.domino.services.sample.SampleService.
public class SampleService extends RestService {
...
public Set< Class<?> > getClasses() {
Set< Class<?> > classes = new HashSet< Class<?> >();
SAMPLE_SERVICE_LOGGER.getLogger().fine("Adding sample service resources.");
classes.add(RootResource.class);
classes.add(ContactsListResource.class);
return classes;
}
}
Your subclass must override the getClasses method, which returns a set of all the resource classes in your service.
NOTE: As you enhance your service, you will probably add new resource classes. When you do so, remember: You also have to modify the getClasses method. The set returned by getClasses must include all your resource classes.
Implement the com.ibm.domino.das.service extension
When the DAS servlet loads, it looks for all extensions of the com.ibm.domino.das.service extension point. Each extension registers its RestService subclass among other properties. For example, consider the sample service’s plugin.xml.
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
<extension point="com.ibm.domino.das.service">
<serviceResources
class="com.ibm.domino.services.sample.service.SampleService"
name="OpenNtfSample"
path="sample"
version="9.0.1">
</serviceResources>
</extension>
</plugin>
It defines the name of the RestService subclass (com.ibm.domino.services.sample.service.SampleService), the name of the service itself (OpenNtfSample), the service path, and the version.
You can use the above template as a guide for your own DAS service. Once you have implemented your own extension, the DAS servlet will call your implementation of RestService.getClasses() whenever the servlet loads. Each of your resources will then be registered with the Wink runtime.
Deploy your REST service
The easiest way to deploy a DAS service is to copy your plug-in files to the Domino OSGi framework. The OSGi framework is distributed across multiple folders in the Domino program and data directories. The recommended location for your plug-in is the workspace\applications\eclipse\plugins folder in the Domino data directory.
Once you have deployed your plug-in files, you must restart the Domino HTTP task. This causes the OSGi framework to restart and load the new plug-in.
Enable your REST service
After you install a DAS service, the service is loaded whenever the Domino HTTP task is started. However, it cannot handle requests until you enable it. You need to deliberately enable the service in the appropriate Internet Site document.
To enable the service:
-
Use a Notes client to open the server’s public address book.
-
In the Domino Directory navigator, select Configuration – Web – Internet Sites.
-
Open the Internet Site document for your server.
-
Click the Edit Web Site action.
-
Select the Configuration tab.
-
At the bottom of the form, look for a section labeled Domino Access Services.
-
In the Enabled services field, add the name of your service. For example, Figure 1 shows three services enabled – the data service, the calendar service, and the sample service:
-
Save your changes and restart the HTTP task.
Figure 1. Enabled services
NOTE: The above instructions assume you are using Internet Sites. If you are not using Internet Sites, you can enable the service in the server document. Look for the Enabled services field on the Internet Protocols -- Domino Web Engine tab of the server document.
Conclusion
This article presents a broad overview of creating a REST service with DAS. It provides some details you won't find anywhere else, including how to:
-
Create a subclass of com.ibm.domino.das.service.RestService.
-
Implement the com.ibm.domino.das.service extension.
-
Deploy and enable your REST service.
But this article assumes you already know (or are willing to learn) about other topics like JAX-RS and developing OSGi plugins for Domino. If you want to build your own DAS service, we recommend you start with the sample service from the extension library on OpenNTF. As you modify and extend the sample service, use the references below to answer questions about JAX-RS, Apache Wink or OSGi. And last but not least, reach out to the Domino application development community with specific questions. You can get help in the extension library discussion forum on OpenNTF or by posting a question to StackOverflow. When posting a question to StackOverflow, please use the lotus-domino tag.
References