RE presentational State Transfer (REST) is a set of principles, introduced in 2000 by Roy Fielding (http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm), that define a communication protocol used when constructing a web application. REST exploits the power and openness of HTTP using simple and clean calling conventions. It is easy to look at a REST statement and discover the method for data access. Its simplicity also makes it easy to use in basic scripting. Typically, REST references today describe a web service that uses the HTTP protocol in conjunction with a custom application programming interface (API) and XML or JSON (JavaScript Object Notation) to alter or query the state of a remote resource.
Beginning with IBM Lotus Notes Domino 8.5.3, a REST service provides a way of having a non-Domino server accessing Domino data without installed software and without using Corba. The Domino REST services conform to JsonRestStore’s expectations for data structure and let the developer quickly wire an application to data components such as a Dojo Data Grid, iNotes List, iNotes Calendar, or a conventional XPages view container like a view panel, which render these REST services directly in an XPage.
The REST services are customizable by use of properties and parameters. These parameters allow the user fine-grained control over the data and the output. If the existing services cannot satisfy a specific use case, a developer can modify the source code available on OpenNTF to generate the desired implementation and output. The XPages Extension Library also includes Apache Wink for REST services. This allows the developer a way to produce custom REST service without exposing the underlying physical document model.
REST is important to the new Web 2.0 programming model. New technologies like OpenSocial and Android are embracing REST services to allow remote clients access to server-side data. The XPages Extension Library has RESTful services in place, opening a whole range of exciting data-handling options for the XPages developer.
The basic REST service design establishes a mapping between Create, Read, Update, and Delete (CRUD) operations to a protocol. Although HTTP is not required, most REST services are, in fact, implemented using the HTTP methods POST
, GET
, PUT
, and DELETE
, as in Table 11.1.
The XPages Extension Library now includes a new set of RESTful, which follow the first principles of REST, services collectively called Domino REST services. These REST services allow developers access to the following Domino objects in JSON format (see Table 11.2).
There are two ways to consume Domino REST services: access them from an XPages REST Service control, or access them as a built-in service. When you access them as a built-in service, they are called the Domino Data Service. Because the same service is being accessed, the user can expect consistent output regardless of how the service is accessed. The services provided by the REST Service control are known as extensions to the REST service. The REST Service control also provides the ability to use additional services that are not included with the Domino Data Service.
Each of these REST services has a unique set of properties or parameters you can set to customize the service’s behavior. It is important to note that the same parameters are exposed as properties of the REST Service control that can be set in the Designer user interface (UI), as shown in Figure 11.1. The properties of the REST Service control change depending on the service or resource selected. For example, a developer can search a view using the search parameter or set the search property exposed through the REST Service control. The parameters and output available for each service listed in Table 11.2 are described in detail near the end of this chapter in the section called “Accessing Data Services from Domino as a Built-In Service.”
In most cases, a developer would want to use a REST Service control in an XPage application and use the built-in standalone service in an application that does not use XPages. A Dojo application is not an XPage application, but it may use the standalone service to access Domino data.
In addition to the services described, there is a way for Java developers to create custom REST services. This may be required if the REST services provided with the XPage Extension Library do not meet the particular needs of a developer. The developer can create a custom REST service using the REST Service control or by creating a custom servlet or by using the DAS. More details on developing a custom REST service will be described later in this chapter.
Many of the examples in this chapter are referencing content from the XPages Extension Library Demo database (XPagesExt.nsf) that is part of the download from OpenNTF. It includes a REST tab that has several samples that demonstrate the REST Data Service in action. These samples are highlighted further along in this chapter.
One easy way to make the REST services available is to use the predefined XPages REST Service control (xe:restService
). The data from the REST services extensions is exposed to other controls on the page that directly reference the REST Service control. For example, a Dojo Data Grid can reference a REST Service control on the same page. The service also becomes available outside the page through a well-known URL.
The REST Service control is a generic one that handles the communication with the runtime layer. But the actual service is provided via a complex type added as a property to the control. There is one complex type implementation per service implementation. You can access the Domino REST services resources from the XPages REST Service control. The REST Service control provides a common development UI and means of accessing the selected REST services extensions.
The REST Service control has two roles. It generates markup at design time, and it acts as a server at runtime. The markup generated at design time is a fragment of JavaScript that creates a Dojo store connecting to the service. At runtime, the Dojo store can be accessed via the REST Service control in a few ways.
In the context of an XPage, at runtime, the REST Service control looks for other components bound to it. If the control finds those components, it delegates the entire request to the other components. Incidentally, it does the same if the request contains a $$axtarget
parameter in the query string. If this parameter refers to a JSF client ID, the component is invoked within its full context.
You can use the pathInfo property to access the Dojo store directly without XPages context. The pathInfo property will be explained in more detail later in the chapter.
From the REST Service control, the developer can select one of the many REST services extension types listed in Table 11.3. These services are described in detail in later sections of this chapter.
The data is exposed to other controls using the id property of the REST Service control.
The REST service data is exposed to an HTTP request using the pathInfo property of the REST Service control. When a pathInfo is used, the REST service is not executed in any particular context. It is more efficient to access the REST data without a context if the context is not relevant to the application. The following is an example of using the pathInfo in an HTTP request URL:
http://{host}/{database}/{xpage}/{pathInfo}?{optional parameters}
When the REST control is accessed in the context of an XPage, there is additional overhead base on its relationship with the other controls on the page. For example, if the REST control is used as the datasource of the Repeat control, then the repeat will be handled. Although it is unlikely, a developer can access the REST control in the context of the page by using the $$axtarget
parameter in the query string. In most instances, a developer will use the pathInfo to access the REST control data without the overhead of the XPage.
Note
Using pathInfo is faster than $$axtarget
from a runtime perspective, because it doesn’t require a particular context. It is also the only reliable way to expose the service to other pages. Use the pathInfo property when accessing data outside the context of an XPage.
The REST Service control exposes a subset of the properties in Designer that can be set from HTTP as parameters. You can ignore the HTTP parameters by setting the REST Service control property ignoreRequestParams to true
.
You can use the REST Service control property preventDojoStore to prevent the Dojo store from being generated as part of the page markup.
Note
The Dojo store class depends on the service that is being selected.
Depending on the REST Service control selected, the developer receives additional properties that map to the parameter that service supports. For example, the view service supports setting the form field on new documents. It can be set as a URL parameter form or as a REST Service control property formName. In most cases, the name of the service property matches the parameter.
This section walks through the steps of how to build and reference an XPage that uses the REST Service control to access a Domino REST service. You will access the View Service (xe:viewJsonService
) using the pathInfo property of the REST Service control. You can use the same steps to access any of the other REST data services.
From Domino Designer, add the REST Service control to a new XPage called MyXPage. Then enter myPathInfo for the pathInfo property of the REST Service control. The pathInfo is used in the URL to access the REST service from an HTTP request. Next, select the REST service by selecting xe:viewJsonService
for the service property of the REST Service control. When the service is selected, the properties available for the REST service change based on the service selected. Enter AllContacts for the ViewName property. Now set the property defaultColumns to true
; the default is false
. Only the system columns are included in the output. Setting this property to true
outputs all the columns. You can view the generated XPage markup in the Source tab; see Listing 11.1.
<xe:restService
id="restService1"
pathInfo="myPathInfo">
<xe:this.service>
<xe:viewJsonService
viewName="AllContacts"
defaultColumns="true">
</xe:viewJsonService>
</xe:this.service>
</xe:restService>
To initiate an HTTP GET request using the pathInfo property, enter the following URL from a browser:
http://myDominoServer/XPagesExt.nsf/MyXPage.xsp/myPathInfo
You use the pathInfo property (myPathInfo) to access the REST service from an HTTP request; otherwise, the XPage is displayed. The response in JSON is a list of entries in the AllContacts view in JSON format. The content looks similar to the response described in the “View JSON Service” section later in this chapter.
You can use the XPages REST Service control to create computed columns. Computed columns allow you to use JavaScript to do two things: create an additional column that does not exist in the view, and access data and formula values. The XPages Extension Library sample REST_DojoGridJsonRest.xsp contains a computed column called ShortName. Here a short name is computed by getting the text left of the @ from an existing column value Email.
Now you’ll learn how to build the computed column that looks up the state name in a different table from the state abbreviation. Start by setting the var property of the service (xe:viewJsonService
) to entry, which represents the view entry. Then add a column (xe:restViewColumn
) to the columns (xe:this.columns
) property of the REST Service control. Set the name property to StateName, and set the value property to a computed value using the script editor. This sample exploits the function @DbLookup, which looks in the specified view (or folder) and finds all documents containing the key value in the first sorted column within the view. Specifically, you need to sort the first column (Key) in the AllState view in the XPage Extension Library sample database so the lookup will work. You can view the generated XPage markup in the Source tab (see Listing 11.2).
<xe:restService
id="restService1">
<xe:this.service>
<xe:viewJsonService
viewName="AllContacts"
defaultColumns="true"
var="entry">
<xe:this.columns>
<xe:restViewColumn
name="StateName">
<xe:this.value><![CDATA[#{javascript:
var state = entry.getColumnValue("State")
if(state) {
return @DbLookup("", "AllStates", state, "Name")
}
return ""
}]]></xe:this.value>
</xe:restViewColumn>
</xe:this.columns>
</xe:viewJsonService>
</xe:this.service>
</xe:restService>
This section explains how to bind a Dojo Data Grid (xe:djxDataGrid
) control to the REST Service control. Place the Dojo Data Grid on the XPage and set the storeComponentId
to restService1. Next, add Dojo Data Grid Column (xe:djxDataGridColumn
), and set the field property for each column displayed in the grid. For example, to display the Email column, set the field property of the column to Email. You can also display the computed column created previously. Simply adding another column and setting the field property of the column to StateName displays the computed column. The pathInfo property of the REST Service control is not relevant when binding to a control like a grid. You can view the generated XPage markup in the Source tab (see Listing 11.3).
<xe:djxDataGrid
id="djxDataGrid1"
storeComponentId="restService1">
<xe:djxDataGridColumn
id="djxDataGridColumn1"
field="EMail">
</xe:djxDataGridColumn>
<xe:djxDataGridColumn
id="djxDataGridColumn2"
field=" StateName">
</xe:djxDataGridColumn>
</xe:djxDataGrid>
As mentioned previously, a good resource for using Domino REST services from XPages is the sample database XPagesExt.nsf, which is included with the XPages Extension Library download. This sample application includes a REST tab that has several samples demonstrating the REST Data Service, as shown in Figure 11.2. You can open the samples in a browser and in Designer. They will inspire you to use them your own applications.
The Data Service page contains an example that demonstrates each of the services included with the Domino Data REST service. A button launches a URL that references each service from a REST Service control, as shown in Figure 11.3. To execute the sample, click its button, and the JSON output of the associated service is displayed. You can use the sample output to aid developers who intend to parse the JSON to create RESTful applications.
When you click the Database Collection button, it emits the JSON output from the Database Collection JSON Service. Specifically, this is a JSON representation of the databases on the server. Clicking the View Collection button results in JSON output for views and folders in the sample database. To get the content of a view (from View Collection JSON Service) or the design of a view, select the view in the drop-down and click View Entries Collection or View Design Collection, respectively. Similarly, you can get content of a document in JSON by selecting a document UNID from the drop-down and clicking the Document button. You can use the Document Collection JSON Service to execute a full text search of the database by entering a query string in the text field and clicking the Document Collection button.
The Data Services—Contacts and All Types pages contain examples of custom and legacy services. Like the Data Service example, a button launches a URL that references the service described. Click the button for the sample, and the JSON or XML output of the associated service is displayed. These examples are targeted to both legacy application developers and custom application developers.
XML output for views has been a feature of Domino for more than a decade. Several years ago, the feature was enhanced to support JSON output. The buttons for Legacy ReadViewEntries demonstrate how to call the existing ReadViewEntries with XML and JSON format. In addition, new implementations for these legacy services, called viewXmlLegacyService and viewJsonLegacyService, are provided in Java. They emulate ReadViewEntries as XML and JSON, respectively. Applications that depend on ReadViewEntries continue to work, and now even more options are available. In fact, if the Java implementation of ReadViewEntries does not suit a developer’s needs, the Java code can be modified.
In rare instances, some of the Data Services provided may not suit a developer’s needs. In this case, a developer with Java experience can choose to create a Custom Database Servlet or a Custom Wink Servlet. A Custom Database Servlet is a Java class that can be added to a database design. The servlet typically handles incoming HTTP requests by delegating to one of the REST service classes in the extension library. A Custom Wink Servlet is the most advanced type of REST service. The open source Apache Wink project defines a service. The servlet is contained in a plug in that is deployed directly to Domino’s OSGi framework.
The Dojo Grid Using JSON Rest page contains an example that demonstrates a Dojo Data Grid referencing a REST Service control on the same page (see Figure 11.4). The REST Service control uses xe:viewJsonService
to access the AllContacts view. The data from the REST services is exposed to grid control using the id property of the REST Service control. Specifically, the storeComponentId of the xe:djxDataGrid
is set to the id (restService1) of the REST Service control. The contents of the AllContacts view are then displayed in the grid.
You can update the data in the grid and then save it to the database. Because you are accessing a view, you can update only the columns that reference items. This page also shows a pure Dojo dialog (from the New Item button) that is only loaded once and keeps the Server-Side components after it is closed. You can use JavaScript to create a new item in the database using Dojo REST Store. The View JSON Service is shown in Listing 11.4.
var firstName = dijit.byId('#{id:dlgFirstName}').getValue();
var lastName = dijit.byId('#{id:dlgLastName}').getValue();
var email = dijit.byId('#{id:dlgEMail}').getValue();
var city = dijit.byId('#{id:dlgCity}').getValue();
var newItem = {
"FirstName":firstName,
"LastName":lastName,
"Email":email,
"City":city
};
var grid = dijit.byId('#{id:djxDataGrid1}'),
var store = grid.store;
store.newItem(newItem);
store.save();
store.close();
grid._refresh();
The Dojo NotesPeek page contains an example that demonstrates using the built-in Domino Data REST services as a Dojo Application. A button launches a URL that references the DojoNotesPeek application, as shown in Figure 11.5. The built-in service requires the data service to be enabled for each server, database, and view. Therefore, DojoNotesPeek can access only data service–enabled applications. Accessing a database or view that has not been enabled results in the error Sorry, an error occurred
. The steps to enable this service per element are described in the later section “Accessing Data Services from Domino as a Built-In Service.”
The application consists of three Dojo grids (dojox.grid.DataGrid
) connected to three Dojo stores (dojox.data.JsonRestStore)
. The stores reference the Database Collection JSON Service, View Collection JSON Service, and View JSON Service. The three grids render a list of databases, a list of views corresponding to the selected database, and the contents of the view (see Figure 11.6). Selecting and clicking on a row from the view opens a new window that renders HTML of the JSON document.
The XPages Extension Library Demo app includes an iNotes tab that has several samples demonstrating the REST Data Service consuming service data with other controls, such as the iNotes List View and iNotes Calendar.
The iNotes List View (xe:listView
) is a powerful control that renders the output of xe:viewJsonService
as it would be displayed in the Notes Client. The JSON output from a categorized view appears categorized with collapsible sections, as shown in Figure 11.7. Columns defined as icons appear as icons instead of the number that defines them.
The iNotes List View control works like the Dojo grid—xe:djxDataGrid
—in the way it uses xe:viewJsonService
to access the JSON output of a view. The data from the REST services is exposed to iNotes List View control by setting the storeComponentId of the xe:listView
to the ID (restService1) of the REST Service control. The result is the content of the view displayed in the list.
The iNotes Calendar—xe:calendarView
—is another powerful control that behaves like the calendar in the Notes Client, as shown in Figure 11.8. It can show the calendar layout as one day, two days, five days, one week, two weeks, a month, or a year by setting the type. The data from the REST services is exposed to the iNotes List Calendar control by setting the storeComponentId of the xe:calendarView
to the ID (restService2) of the REST Service control. You can view the generated XPage markup in the Source tab (see Listing 11.5).
<xe:restService
id="restService2"
pathInfo="/inoteslegacyjson"
preventDojoStore="false">
<xe:this.service>
<xe:calendarJsonLegacyService
viewName="TestCalendar"
var="entry"
contentType="text/plain"
colCalendarDate="$134"
colEntryIcon="$149"
colStartTime="$144"
colEndTime="$146"
colSubject="$147"
colEntryType="$152"
colChair="$153"
colConfidential="$154"
colStatus="$160"
colCustomData="$UserData"
colAltSubject="$151">
<xe:this.compact>
<![CDATA[#{javascript:sessionScope.CompactJson2=="true"}]]>
</xe:this.compact>
</xe:calendarJsonLegacyService>
</xe:this.service>
</xe:restService>
<xe:calendarView
id="calendarView1"
jsId="cview1"
summarize="false"
type="#{javascript: null == viewScope.calendarType? 'M' :
viewScope.calendarType }
"
storeComponentId="restService2">
</xe:calendarView>
The XPages Extension Library Demo includes a sample that demonstrates how to make a JSON-RPC to the Domino server. JSON-RPC is a stateless, lightweight remote procedure call (RPC) protocol. It is an important part of the REST service because OpenSocial defines REST and RPC protocols to give remote clients access to Server-Side data. Clients in Android applications also take advantage of JSON-RPC in applications.
Shindig and JSON-RPC allow multiple methods to be called at once, thus minimizing the number of requests to the server. This can be a huge saving in connections and resources, which can increase performance and scalability. This feature is not currently supported at the time of this writing, but it is being investigated for a future release of the Extension Library.
Remote Services—xe:jsonRpcService
—is a versatile control that allows RPCs to the Domino server using JSON-RPC. JSON-RPC is a protocol that enables a procedure to execute in another process or on another computer (in this case, a Domino server). The value of JavaScript is set on the server, and the client uses dojo.rpc. The markup to support this is generated in the XPage (see Figure 11.9). Also, note that each control can have one or many remote methods.
Listing 11.6 demonstrates that JSON-RPC can be used to call @Functions on the Domino server. The function @DbLookup looks up a user’s email from the AllNames view. This listing also shows how an argument (xe:remoteMethodArg
) known as userName defined in the method (xe:remoteMethod
) can be passed to @DbLookup.
<xe:jsonRpcService
id="jsonRpcService1"
serviceName="userinfo">
<xe:this.methods>
<xe:remoteMethod
name="dblookup">
<xe:this.script><![CDATA[
return (@DbLookup("", "AllNames", userName, "Email"));
]]>
</xe:this.script>
<xe:this.arguments>
<xe:remoteMethodArg
name="userName">
</xe:remoteMethodArg>
</xe:this.arguments>
</xe:remoteMethod>
</xe:this.methods>
</xe:jsonRpcService>
You can place the script to call in a button. In a real application, the argument is from a drop-down or edit control, but here we just pass a hard-coded value ("Linda Lane")
to the dblookup
method, as shown in Listing 11.7.
<xp:button
value="Lookup User Email"
id="button1">
<xp:eventHandler
event="onclick"
submit="false">
<xp:this.script><![CDATA[
var deferred = userinfo.dblookup("Linda Lane")
deferred.addCallback(function(result) {
alert(result)
});]]>
</xp:this.script>
</xp:eventHandler>
</xp:button>
According to Google, OpenSocial is a set of common APIs for building social applications across many websites. It consists of both JavaScript APIs and REST/RPC protocols for server-to-server interactions. In general, OpenSocial gadgets are XML files similar to the Dojo NotesPeek application that reference the OpenSocial API. Based on this definition, using the Domino REST services to build OpenSocial gadgets seems like a perfect fit. Google provides a plethora of information on OpenSocial. The XML markup to create a simple gadget using Domino REST service is shown in Listing 11.8. Figure 11.10 shows this simple OpenSocial gadget accessing the View JSON Service.
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs
title="Simple Data Service Gadget"
height="500">
<Require
feature="osapi" />
<Require
feature="minimessage" />
<Optional
feature="dynamic-height" />
</ModulePrefs>
<Content
type="html">
<![CDATA[
<div id="content_div"></div>
<script type="text/javascript">
var g_msg = new gadgets.MiniMessage(__MODULE_ID__);
function getAllDocuments(context) {
var url =
"http://xyz.comexample.com/XPagesExt.nsf/api/data/collections/name/AllT
ypes?ps=100";
osapi.http.get({ "href": url, "format": "json",
"refreshInterval": 0,
"headers":
{"Authorization": ["Basic YWRtaW46YXRsYW50aWM="]}
}).execute(getAllDocumentsResponse);
}
function getAllDocumentsResponse(data) {
var documents = null;
var html = "<font color=grey size=2>";
if ( data != null && data.content != null ) {
documents = data.content;
for (var i = 0; documents != undefined && i < documents.length; i++)
{
html += "UNID: " + documents[i]['@unid'] + "<br>";
html += "Form: " + documents[i]['@form'] + "<br>";
html += "NoteID: " + documents[i]['@noteid'] + "<br>";
html += "<right>";
var jsonLink = "<a href="" + documents[i]['@link'].href + "">" +
"JSON" + "</a>";
html += jsonLink + "<br>";
html += "</right>";
html += "<hr/>";
}
}
else {
html = "No documents.";
}
html += "</font>";
document.getElementById('content_div').innerHTML = html;
gadgets.window.adjustHeight();
}
gadgets.util.registerOnLoadHandler(getAllDocuments);
</script>
]]>
</Content>
</Module>
You can access a subset of the Domino REST services as a built-in service. These services are collectively called the Domino Data Service when they’re accessed as a built-in service, and individual components are called resources. An administrator typically doesn’t want the data service to handle requests on every Domino server because it could expose details of applications not easily visible in the UI.
The data service is disabled by default. Domino Data Service uses a three-tiered approach for limiting access. The administrator needs to specifically enable the data service for each server, database, and view. The following sections describe how to enable the data service. For more information, please see the Domino Data Service User Guide (Extension Library REST Services.pdf) and Domino Data Service Reference (DominoDataServiceDoc.zip), which is included with the XPage Extension Library download from OpenNTF.
Once enabled, the data service starts along with the HTTP task. Because the data service is a built-in service, the developer can use it without creating an XPage or adding Java code to the Domino server. The built-in data service requires Domino 8.5.3 (or greater).
The data service is loaded whenever the Domino HTTP task is started. However, an administrator typically doesn’t want the data service to handle requests on every Domino server. The administrator needs to deliberately enable the data service in the appropriate Internet Site document on each server. To enable the data services, add the Data keyword to the Enabled Services field on the Internet Site document for the server (see Figure 11.11). A restart of the server is required for the changes to take place.
Note
The preceding instructions assume the server is configured using Internet Site documents. If the server is not configured this way, enable the data service in the server document. See the Domino Data Service User Guide available in the XPage Extension Library download on OpenNTF for more information:
By default, the data service does not have access to each database. Just as the administrator needed to enable the data service for a server, the data service for a database needs to be deliberately enabled. To enable the data services for a database, use the Notes Client to open the Application properties for the database. Then change the field labeled Allow Domino Data Service on the bottom of the Advanced tab to Views and Documents, as in Figure 11.12.
Tip
Administration of the data service requires Notes 8.5.3 (or later).
You can also set this property from Domino Designer, as shown in Figure 11.13. Close the database or close the project for the change to take effect.
By default, the data service does not have access to each view in a database. The data service for a view or folder needs to be deliberately enabled. To enable the data service for a view or folder, use the Domino Designer to open the View Properties for the view or folder. Then select the check box labeled Allow Domino Data Service Operations on the Advanced tab of the View properties box (see Figure 11.14).
This section describes each resource of the Domino Data Service and how to call each as a built-in service from HTTP. The same implementation of the Domino RESTful API is described as a resource when it’s called as a built-in service and described as a service when it’s used in the context of the REST Service control. Because this book is primarily about XPages, the term service is used. However, the same implementation can be referred to as a resource in other documentation that is focused on the built-in service and in the context of the Domino Data Service.
The REST Service control can also access each resource of the Domino Data Services. To change the resource, simply select a different service type in the design properties. To reference the service from HTTP, use a URL with the database, XPage, and pathInfo property, as described in the previous section “Standard Attributes for REST Service Control.” Where possible, the JSON format output by the REST service is consumable by the Dojo data store JsonRestStore.
The Database JSON Collection Service supports the HTTP method GET
.
To get the list of databases on a server, send an HTTP GET
request to the database collection resource uniform resource identifier (URI):
http://{host}/api/data
The data service returns a response in JSON format, like what’s shown in Listing 11.9.
[
{
"@title":"Administration Requests",
"@filepath":"admin4.nsf",
"@replicaid":"852555510361A2F4",
"@template":"StdR4AdminRequests",
"@href":"http://example.com/admin4.nsf/api/data/collections"
},
...
{
"@title":"XPages Extension Library Demo",
"@filepath":"XPagesExt.nsf",
"@replicaid":"8525786555581FD3",
"@template":"",
"@href":"http://example.com/XPagesExt.nsf/api/data/collections"
}
]
The View JSON Collection Service supports the HTTP method GET
.
To get the list of views and folders in a database, send an HTTP GET
request to the view collection resource URI:
http://{host}/{database}/api/data/collections
The data service returns a response in JSON format, like what is shown in Listing 11.10.
[
{
"@title":"TestCalendarOutline",
"@folder":false,
"@private":false,
"@modified":"2011-04-29T13:02:20Z",
"@unid":"F598C2D31E4E12F68525786500660B7E",
"@href":"http://example.com/XPagesExt.nsf/api/data/collections
/unid/F598C2D31E4E12F68525786500660B7E"
},
...
{
"@title":"AllContacts",
"@folder":false,
"@private":false,
"@modified":"2011-04-29T13:02:20Z",
"@unid":"CD40A953ABDE036A8525786500660C27",
"@href":"http://example.com/XPagesExt.nsf/api/data/collections
/unid/CD40A953ABDE036A8525786500660C27"
},
...
]
The View JSON Service supports the HTTP methods GET
, PUT
, PATCH,
POST
, and DELETE
.
To get a list of entries in a view or folder, send an HTTP GET
request to the view entry collection resource URI:
http://{host}/{database}/api/data/collections/unid/{unid}?{parameters}
http://{host}/{database}/api/data/collections/name/{name or alias}?
{parameters}
Table 11.4 lists parameters that are available to use in a GET request.
For example, the following URI corresponds to the AllContacts view in the XPage Extension Library sample database:
http://example.com/XPagesExt.nsf/api/data/collections/name/AllContacts
The data service returns a response in JSON format, like what is shown in Listing 11.11.
[
"@href":"http://example.com/XPagesExt.nsf/api/data/collections
/name/AllContacts/unid/AAE5C9A07AF9C1A7852578760048C0D6",
"@link":
{
"rel":"document",
"href":"http://example.com/XPagesExt.nsf/api/data/documents/unid
/AAE5C9A07AF9C1A7852578760048C0D6"
},
"@entryid":"1-AAE5C9A07AF9C1A7852578760048C0D6",
"@unid":"AAE5C9A07AF9C1A7852578760048C0D6",
"@noteid":"9AA",
"@position":"1",
"@read":true,
"@siblings":200,
"@form":"Contact",
"Id":"CN=Adela Rojas/O=renovations",
"FirstName":"Adela",
"LastName":"Rojas",
"EMail":"[email protected]",
"City":"Paterson",
"State":"NJ",
"created":"2011-04-18T13:14:39Z",
"$10":"Adela Rojas"
},
...
]
When view entries are retrieved, the response also includes a Content-Range header indicating how many entries are included. For example:
Content-Range: items 0-9/201
This header indicates that the data service returned entries 0 through 9 from a total of 201 entries. To get the next 10 entries, you must send a GET
request with additional URL parameters:
http://example.com/xpagesext.nsf/api/data/collections/
name/AllContacts?ps=10&page=1
In this example, the ps
parameter specifies the page size, and the page
parameter specifies which page to get. In this case, get the second page. (Page numbers are zero-based.) The data service returns the second page of data and a new Content-Range
header like this:
Content-Range: items 10-19/201
This replaces (completely updates) a document in a view or folder. You can only update columns that map directly to fields. The supported parameters are listed in Table 11.5. The parentid
, form
, and computewithform
parameters are described in more detail later in this chapter in the section “Document JSON Service” under HTTP method PUT
.
http://{host}/{database}/api/data/collections/unid/{unid}/unid/{unid}?
{parameters}
http://{host}/{database}/api/data/collections/name/{name}/unid/{unid}?
{parameters}
This is used to partially update a document in a view or folder. Only columns that map directly to fields can be updated. The supported parameters are listed in Table 11.5.
http://{host}/{database}/api/data/collections/unid/{unid}/unid/{unid}?
{parameters}
http://{host}/{database}/api/data/collections/name/{name}/unid/{unid}?
{parameters}
This creates a document in a view or folder. Only columns that map directly to fields can be created. The supported parameters are listed in Table 11.5.
http://{host}/{database}/api/data/collections/unid/{unid}?{parameters}
http://{host}/{database}/api/data/collections/name/{name}?{parameters}
To delete a document, an HTTP DELETE
request is sent to the URI. If the data service deletes the document without errors, it returns an HTTP status code of 200.
http://{host}/{database}/api/data/collections/unid/{unid}/unid/{unid}
http://{host}/{database}/api/data/collections/name/{name}/unid/{unid}
The View Design JSON Service supports the HTTP method GET
.
To read the design of a view or folder, send an HTTP GET
request to the view designresource URI:
http://{host}/{database}/api/data/collections/unid/{unid}/design
http://{host}/{database}/api/data/collections/name/{name or alias}/design
For example, the following URI corresponds to the AllContacts view in the XPages Extension Library sample database:
http://example.com/XPagesExt.nsf/api/data/collections/name/AllContacts/
design
The data service returns a response in JSON format, like what’s shown in Listing 11.12.
[
... {
"@columnNumber":3,
"@name":"FirstName",
"@title":"First Name",
"@width":10,
"@alignment":0,
"@hidden":false,
"@response":false,
"@twistie":false,
"@field":true,
"@category":false
},
{
"@columnNumber":4,
"@name":"LastName",
"@title":"Last Name",
"@width":12,
"@alignment":0,
"@hidden":false,
"@response":false,
"@twistie":false,
"@field":true,
"@category":false
},
...
]
The Document Collection JSON Service supports the HTTP method GET
.
You can use the HTTP GET request to list all the documents in the database. You can use the since
and search
parameters to filter the list as described further in Table 11.6.
http://{host}/{database}/api/data/documents?{parameters}
For example, you can use the following URI to search for all documents that contain Tempe
in the XPage Extension Library sample database:
http://example.com/XPagesExt.nsf/api/data/documents?search=Tempe
The data service returns a response in JSON format, like what is shown in Listing 11.13.
[
{
"@modified":"2011-04-18T13:14:41Z",
"@unid":"08F7227475F21A2C852578760048C131",
"@href":"http://example.com/XPagesExt.nsf/api/data/documents
/unid/08F7227475F21A2C852578760048C131"
}
]
The Document JSON Service supports the HTTP methods GET
, PUT
, PATCH
, POST
, and DELETE
.
You can use the HTTP GET
request to obtain a document in the database. The supported parameters are listed in Table 11.7.
http://{host}/{database}/api/data/documents/unid/{unid}?{parameters}
Attachments are supported as a URI reference to the resource. For example, you can use the following URI to obtain a document from the XPage Extension Library sample database:
http://example.com/XPagesExt.nsf/api/data/documents/unid/B08E87F21FE84FAB492
57826004FEB5E
The data service returns a response in JSON format, like what is shown in Listing 11.14.
{
"@href":"http://example.com/XPagesExt.nsf/api/data/documents
/unid/B08E87F21FE84FAB49257826004FEB5E",
"@unid":"B08E87F21FE84FAB49257826004FEB5E",
"@noteid":"38CA",
"@created":"2011-01-28T14:32:55Z",
"@modified":"2011-03-24T19:34:07Z",
"@authors":"CN=Admin/O=Peaks",
"@form":"AllTypes",
"$UpdatedBy":"CN=Admin/O=Peaks",
"$Revisions":"01/28/2011 09:32:56 AM;02/08/2011 03:31:22 PM ",
"fldText":"One",
"fldNumber":1,
"fldDate":"2010-01-01",
"fldTime":"01:00:00",
"fldDateTime":"2010-01-01T06:00:00Z",
"fldDialogList":"c1",
"fldText2":
["One","Two","Three"
],
"fldNumber2":
[1,2,3
],
"fldDate2":
["2010-01-01","2010-01-02","2010-01-03"
],
"fldTime2":
["01:00:00","02:00:00","03:00:00"
],
"fldDateTime2":
["2010-01-01T06:00:00Z","2010-01-02T07:00:00Z","2010-01-
03T08:00:00Z"
],
"fldDialogList2":
["c1","c2","c3"
],
"fldRichText":
{
"contentType":"text/html",
"data":"<br />
<font color="#FF0000">This is
red.</font><br />
<font color="#008000">This is
green.</font><br />
<font color="#0000FF">This is
blue.</font><br />
<br />
<a class="domino-attachment-link"
style="display: inline-block; text-align: center"
href="http://example.com/XPagesExt.nsf/0/b08e87f21fe84fab49257826
004feb5e/$FILE/Picture.JPG" title="Picture.JPG"><img
src="http://example.com/XPagesExt.nsf/0/b08e87f21fe84fab49257826
004feb5e/fldRichText/0.158?OpenElement&FieldElemFormat=gif"
width="72" height="34" alt="Picture.JPG" border="0" /><span
class="domino-caption" style="display:
block">Picture.JPG</span></a>",
"attachments":
[
{
"@href":"http://example.com/XPagesExt.nsf/0/b08e87f21fe84fab492578
26004feb5e/$FILE/Picture.JPG"
},
{
"@href":"http://example.com/XPagesExt.nsf/0/b08e87f21fe84fab492578
26004feb5e/fldRichText/0.158?OpenElement&FieldElemFormat=gif"
}
],
"type":"richtext"
}
}
To replace (completely update) a document, send a PUT
request to document resource URI. The supported parameters are listed in Table 11.5.
http://{host}/{database}/api/data/documents/unid/{unid}?{parameters}
When sending a PUT
request, include a Content-Type header, as shown in Listing 11.15.
Content-Type: application/json
{
"Id":"CN=Adela Rojas/O=renovations",
"FirstName":"Adela",
"LastName":"Rojas",
"City":"Newark",
"State":"NJ",
"EMail":"[email protected]"
}
The preceding request changes Adela Rojas’s city from Paterson to Newark. If the data service completes the request without errors, it returns an HTTP status code of 200
without a response body.
Tip
When sending a PUT
request, don’t include any @ properties like @unid
and @href
. These properties are considered metadata. The data service ignores any attempt to update metadata.
Usually when a document is to be updated, the business logic contained in a specific form must be executed. To do this, send a PUT
request with additional URL parameters:
http://example.com/xpagesext.nsf/api/data/documents/unid/AAE5C9A07AF9C1A7852
578760048C0D6?form=Contact&computewithform=true
In this example, the form parameter specifies the Contact form. The computewithform
parameter is true
, instructing the data service to execute the Contact form’s business logic.
To partially update a document, send a PATCH
request to document resource URI with the available parameters shown in Table 11.5.
http://{host}/{database}/api/data/documents/unid/{unid}?{parameters}
To create a document, send an HTTP POST
. The available parameters are shown in Table 11.5.
http://{host}/{database}/api/data/documents?{parameters}
When sending a POST
request, you must send a Content-Type header, as shown in Listing 11.16.
Content-Type: application/json
{
"FirstName":"Stephen",
"LastName":"Auriemma",
"City":"Littleton",
"State":"MA",
"EMail":"[email protected]"
}
If the data service is able to create the document without errors, it returns an HTTP status code of 201
. The response also includes a Location header identifying the URI of the new document resource:
Location:
http://example.com/.../api/data/documents/unid/3249435909DCD22F852578A70063E
8E5
Usually when a new document is created, the business logic contained in a specific form needs to be run. To do so, send a POST request with additional URL parameters. For example:
http://example.com/xpagesext.nsf/api/data/
documents?form=Contact&computewithform
The form and computewithform parameters are described in the preceding section “Document JSON Service” under the HTTP method PUT
.
A user may want to create a document that is a response to another document. Doing this involves sending a POST
request with a parentid
parameter. For example:
http://example.com/xpagesext.nsf/api/data/
documents?form=Discussion&computewithform =true&parentid=
440FA99B2F0F839E852578760048C1AD
If the POST
request succeeds, the data service creates a response to the document with a UNID of 440FA99B2F0F839E852578760048C1AD
the parent.
To delete a document, send an HTTP DELETE
request to the document resource URI. If the data service deletes the document without errors, it returns an HTTP status code of 200
.
http://{host}/{database}/api/data/documents/unid/{unid}
You can use the XPages REST control to create computed items. This feature is similar to computed columns mentioned previously. It’s a powerful feature that allows the developer to create additional items that do not exist in the document using JavaScript and access data and formula values. In the following example, a short name is computed by getting the text left of the @ from an existing item value Email.
Here’s how to create a computed item in an XPage:
1. Add a REST Service control to the page and set the service property to xe:documentJsonService
.
2. Start by setting the var property of the service (xe:documentJsonService
) to document, which represents the Notes document.
3. Add an item (xe:restDocumentItem
) to the items (xe:this.item
) property of the REST Service control.
4. Set the name property to ShortName.
5. Set the value property to a computed value using the script editor.
6. Type the following script into the script editor, as in Listing 11.17.
var e = document.getItemValue("EMail")
if(e) {
var p = @UpperCase(@Left(e,"@"))
return p
}
return ""
To see the results, access the service from a browser by entering the following URL, but replace the UNID B53EE32CCC6B79218525790300512A36
with the UNID of an actual existing document:
http://myDominoServer/XPagesExt.nsf/MyXPage.xsp/myPathInfo/B53EE32CCC6B79218
525790300512A36
The data service returns a response in JSON format, like what is shown in Listing 11.18.
{
"@unid":"B53EE32CCC6B79218525790300512A36",
"@noteid":"1A22",
"@created":"2011-09-06T14:46:32Z",
"@modified":"2011-09-06T14:46:32Z",
"@authors":"Anonymous",
"@form":"Contact",
"$UpdatedBy":"Anonymous",
"State":"MA",
"LastName":"Auriemma",
"City":"Littleton",
"FirstName":"Stephen",
"EMail":"[email protected]",
"shortname":"SAURIEMMA"
}
For the most part, this chapter has discussed consuming existing services provided by the XPage Extension Library. In addition to consuming REST services, the XPages Extension Library includes a framework to develop a custom a REST service that meets a particular need. This section introduces another way to develop a custom a REST service and compares their capabilities. Knowledge of Java and REST services is required.
Developing Custom REST Services:
The Custom XPages REST Service Control Extension is a service that you can select from a REST Service control. You can modify the code provided on OpenNTF for the XPages Extension Library and customize one of the existing services of the implementation to generate the desired implementation and output.
A Custom Database Servlet is a Java class that you can add to a database design. The servlet typically handles incoming HTTP requests to one of the REST service classes in the extension library. This type of REST service requires detailed knowledge of the Java programming language, but you have complete control over the definition of the service.
A Custom Wink Servlet is the most advanced type of REST service. The Java developer can use the open source Apache Wink project to define the service. The developer’s servlet needs to be contained in a plugin deployed directly to Domino’s OSGi framework. The service is not tied to a single database; it can access any data chosen and represent it in any format.
The XPages Extension Library has a variety of RESTful services and controls for accessing Domino data. At the heart is the REST Service control that provides one interface for developing applications that consume REST services. There are several XPage UI controls, including the iNotes List and iNotes Calendar, that can consume and render these REST services directly in an XPage. An XPage application is not required to consume REST services using the XPage Extension Library. For example, a Dojo application can consume as a standalone REST service without any reference to an XPage. In addition to consuming REST services, the XPages Extension Library includes a framework for producing a custom REST service.
18.218.48.62