Oracle® Fusion Middleware Developer's Guide for Oracle WebCenter 11g Release 1 (11.1.1.4.0) E10148-12 |
|
![]() Previous |
![]() Next |
Oracle WebCenter provides a set of REST APIs for retrieving and modifying server data. This chapter discusses the WebCenter REST APIs.
This chapter includes the following sections:
Section 51.2, "Before You Begin: Performing Required Configurations"
Section 51.3, "Understanding the Username-Based Security Token Encryption"
Section 51.9, "Security Considerations for WebCenter REST APIs"
This chapter includes some examples that demonstrate how to use WebCenter REST APIs. For more examples, see the Oracle WebCenter Demonstrations and Samples page on the Oracle Technology Network (OTN) at:
http://www.oracle.com/technology/products/webcenter/release11_demos.html
REST (REpresentational State Transfer) is an architectural style for making distributed resources available through a uniform interface that includes uniform resource identifiers (URIs), well-defined operations, hypermedia links, and a constrained set of media types. Typically, these operations include reading, writing, editing, and removing, and media types include JSON and XML/ATOM.
REST commands use standard HTTP methods as requests to point to the resource being used. Every request returns a response, indicating the status of the operation. If the request results in an object being retrieved, created, or updated, the response includes a standard representation of that object.
REST supports multiple clients, both from client machines and other servers, and it can be used from just about any client or development technology, including Java, JavaScript, Ruby on Rails, PHP, .Net, and so on.
Tip: For a good general introduction to REST, see the Wikipedia article Representational State Transfer athttp://en.wikipedia.org/wiki/Representational_State_Transfer . |
REST is typically used with Rich Internet Applications (RIA) that are client-side scripted and require the ability to interact with data from a server-side application. For example, the WebCenter iPhone App uses WebCenter REST APIs to interact with a WebCenter Spaces application. The native iPhone client is written in Objective-C, and the REST APIs enable the client to send and retrieve application data.
All of the REST APIs, except for the navigations REST API, require WebCenter Spaces. For information on the navigation REST API, see Section 13.3.2, "Using the Navigation REST APIs."
Before you can use the WebCenter REST APIs, you must perform the server-side configurations described in this section. You must perform two separate configurations. You must configure an identity asserter and you must seed required entries in the credential store, which enables the REST security tokens to function properly.
Perform these configuration tasks when WebCenter Spaces is installed for the first time or if you otherwise know the configuration tasks have not been previously performed.
For more information on security tokens, see Section 51.9, "Security Considerations for WebCenter REST APIs."
Note: This configuration is not required for the navigation REST APIs or for the CMIS REST APIs. |
First, you must configure an identity asserter before using the REST APIs. For detailed instructions, see "Configuring the REST Service" in the Oracle Fusion Middleware Administrator's Guide for Oracle WebCenter.
The second configuration step is to configure the WLS credential store. To configure the credential store, execute these commands while the server is running. You do not have to restart the server after executing these commands.
createCred(map="o.webcenter.jf.csf.map", key="keygen.algorithm", user="keygen.algorithm", password="AES") createCred(map="o.webcenter.jf.csf.map", key="cipher.transformation", user="cipher.transformation", password="AES/CBC/PKCS5Padding")
To provide additional security, every URI, for both href
and template
attributes, includes a security token parameter that is based on the authenticated username (a utoken).
The security generation algorithm uses a randomly generated "salt" along with the username. The salt ensures that if any of the parameters used to perform encryption become compromised, existing tokens can be invalidated and new ones generated. Most importantly, because the username is used as part of the user token generation algorithm, the salt prevents having to change all user names in the event of a compromise.
The salt is stored in the Credential Store Framework (CSF) in the map o.webcenter.jf.csf.map
against key user.token.salt
. You can change the value of this key (and other keys used for token encryption) by accessing CSF in Oracle Enterprise Manager.
Caution: If you change the encryption key values, all existing username based security tokens will immediately become invalid. Only change these values under extraordinary circumstances, like an algorithm parameter compromise. |
Many excellent articles have been published about REST and the benefits of the RESTful style of software architecture. Some of these benefits include:
Using "Hypermedia As The Engine Of Application State" (HATEOAS) links to access the REST API helps promote API robustness. Since the clients only use URIs returned from the server, if the server changes the URI format, the client will continue to function properly. See also Section 51.6, "Understanding the Link Model."
Using the standard HTTP protocol allows network infrastructure to cache REST requests where appropriate, reducing load on both the client and server. See also Section 51.12, "Managing Caches."
Stateless REST requests allow each request to be served by any number of different servers, helping with scalability.
Using the standard HTTP protocol allows a wide variety of clients to interact with the REST APIs without requiring specialized libraries.
In addition to enabling mobile access, WebCenter REST APIs allow you to take advantage of Web 2.0 technologies like Ajax, JavaScript, and JSON to create rich, interactive browser-based user interfaces and to access and modify WebCenter and WebCenter Spaces data. In general, the WebCenter REST commands provide a more natural and easy-to-use alternative to a SOAP-style web services approach.
Table 51-1 describes the Oracle WebCenter REST APIs provided for WebCenter Services features.
Table 51-1 Summary WebCenter Services Features Supported by REST APIs
REST API | Description | Chapter |
---|---|---|
Discussions |
Enable a client to post, read, update, and delete discussion forums, topics, and messages. |
Section 33.3.8, "Using the Discussions Service REST APIs." |
Lists |
Enables a client to browse all the lists associated with a named group space; search list columns given a search term; create new lists; add, update, and remove list rows; and similar sorts of list-related tasks |
Section 43.4, "Using the Lists Service REST APIs." |
People Connections |
Enable a client to view profile data; manage connection lists, feedback, and messages; create new activities and view activities for users, lists, and group spaces. |
Section 35.3.5, "Using the People Connections Service REST APIs." |
WebCenter Spaces |
Enable a client to retrieve group space metadata and view, create, update, and delete group space lists and list items. You can also retrieve group space membership information. |
Section 50.3, "Using the WebCenter Spaces REST APIs." |
Content Management |
Uses the CMIS (Content Management Interoperability Services) RESTful server binding to provide access to the CM VCR (Content Management Virtual Content Repository). |
Oracle Fusion Middleware Content Management REST Service Developer's Guide. |
Activity Graph |
Enables you to create your own interface for providing recommendations for connections, group spaces, and items using the underlying Activity Graph engine. |
Section 41.3.2, "Using the Activity Graph Service REST APIs." |
Events |
Lets you access calendar events associated with a named group space. |
Section 48.3.2, "Using the Events Service REST APIs." |
Feedback |
Enables a client to create, read, and delete feedback in a social networking application. |
Section 35.3.5.3, "Feedback REST APIs." |
Search |
Lets you post, read, update, and delete searches. You can specify keywords and the scope of the search; for example, the iPhone could search for "smith" in all spaces, documents and wiki pages. |
Section 40.3.7, "Using the Search Service REST APIs." |
Tags |
Enables a client to read, post, update, and delete tags and tagged items. |
Section 39.3.2, "Using the Tags Service REST APIs." |
Navigation |
Use the navigation REST APIs to create your own interface for displaying navigations. Note: The navigation REST APIs do not share the resource index described in this chapter. |
Section 13.3.2, "Using the Navigation REST APIs." |
Personalization |
Enables you to access the Personalization Conductor. |
Section 62.4, "Using Personalization APIs Externally." |
Pagelets |
Allows remote web services to retrieve information about resources and pagelets. Inject pagelets into non-proxied pages, allowing the Pagelet Producer to act as a portlet provider for Oracle WebCenter Interaction, Oracle WebLogic Portal, or other third-party portals. |
Section 58.2.3, "Using REST APIs." |
Hypermedia is at the core of two of the most successful web-based formats: HTML and ATOM. HTML and ATOM allow consumers to navigate to other hypermedia documents through links. For example, Oracle's link element is based on HTML and ATOM links.
Hypermedia drives RESTful application state (known as HATEOAS: Hypermedia As The Engine Of Application State).
Note: HATEOAS analogy to define application state:Suppose you are completing your taxes in your favorite browser. You finish entering your W-2 data and move on to deductions when the browser crashes. The state you lost—the fact that you were on deductions and still needed to enter data—is the application state; not the W-2 data entered (that is, change states from the current state). HATEOAS dictates that this state—the application state—be captured wholly in hypermedia. Application state is where you are in the application, not what data you've entered into the application. One of the benefits of this approach is that it simplifies the client and server, because they do not need to be aware of the state they are in. The link contains all the state information necessary to process the request. |
Given a set of top-level URI entry points to a RESTful service, all interactions beyond those entry points are driven by hypermedia links returned in response representations. This link-centered approach helps keep the client from becoming too tightly coupled to the server URLs. The client is using URLs given to it by the server, therefore the client code does not break if the server URLs change format.
Understanding this link model helps you understand how to use the data the service returns to navigate the REST APIs.
This section describes the hypermedia link model used by WebCenter's RESTful services. It includes the following subsections:
In WebCenter, the Resource Index is your starting point for all authenticated access. The Resource Index provides access to the set of top-level URI entry points. It provides the way in to all the available WebCenter RESTful services. The Resource Index URI is the only URI that you need to know.
The WebCenter Resource Index URI is:
http://host:port/rest/api/resourceIndex
Note: Access to the Resource Index always requires authentication; however, you can (optionally) access the CMIS resource entry point anonymously using the following URI:
See also Section 51.10, "Security Considerations for CMIS REST APIs." |
The first step in using the WebCenter REST APIs is to send a GET
request to the Resource Index. The response varies depending on the services available and the media type of the request. Example 51-1 shows how the response might look if you made an Ajax request using JavaScript (and possibly a client-side scripting library, such as Dojo) to retrieve the JSON data for the Resource Index. Note that this is an abridged sample response and does not include all of the links actually present in a real response.
Example 51-1 Response to a GET on the Resource Index
{ "resourceType": "urn:oracle:webcenter:resourceindex", "links": [ { "template": "opaque-template-uri", "resourceType": "urn:oracle:webcenter:messageBoard", "href": "opaque-uri", "capabilities": "urn:oracle:webcenter:read" }, { "resourceType": "urn:oracle:webCenter:cmis", "href": "opaque-uri", "capabilities": "urn:oracle:webcenter:read" }, { "template": "opaque-template-uri", "resourceType": "urn:oracle:webcenter:discussions:forums", "href": "opaque-uri", "capabilities": "urn:oracle:webcenter:read" }, { "resourceType": "urn:oracle:webcenter:resourceindex", "rel": "self", "href": "http://host:port/rest/api/resourceIndex", "capabilities": "urn:oracle:webcenter:read" }, { "template": "opaque-template-uri", "resourceType": "urn:oracle:webcenter:activities:stream", "href": "opaque-uri", "capabilities": "urn:oracle:webcenter:read" }, { "template": "opaque-template-uri", "resourceType": "urn:oracle:webcenter:people:person", "capabilities": "urn:oracle:webcenter:read" }, { "template": "opaque-template-uri", "resourceType": "urn:oracle:webcenter:feedback", "href": "opaque-uri", "capabilities": "urn:oracle:webcenter:read" }, { "template": "opaque-template-uri", "resourceType": "urn:oracle:webcenter:spaces", "href": "opaque-uri", "capabilities": "urn:oracle:webcenter:read" }, { "template": "opaque-template-uri", "resourceType": "urn:oracle:webcenter:people", "href": "opaque-uri", "capabilities": "urn:oracle:webcenter:read" } ] }
By interpreting the links returned in the Resource Index data, you can retrieve the URI entry point for an individual service by locating the URI for the resource type you want to use. You can then continue navigating through the hypermedia until you can perform the required operation. Example 51-2 shows a method that locates a URI given the Resource Index JSON data.
Example 51-2 Locating the URI for a Particular Service in the Resource Index
/* Parse the resourceIndex to find the specified URL and * return it. * * @Param jsonData the JSON data retrieved from calling * the /rest/api/resourceIndex URL. * @Param strResourceType the resource type of the URL * you want to retrieve from the resourceIndex data. * E.g., 'urn:oracle:webcenter:activities:stream' */ function getResourceURL(jsonData, strResourceType) { // Using the HATEOAS model, we browse the returned links // looking for the one with the correct resource type. for (var i = 0; i < data.links.length; i++) { if (data.links[i].resourceType == strResourceType) { return data.links[i].href; } } }
Example 51-3 and Example 51-4 show the anatomy of a hypermedia link as XML and in JSON document fragments, respectively.
Example 51-3 Link in an XML Document Fragment
<links> <link href="opaque-URI" template="opaque-template-URI (optional)" rel="rel-name" title="human-readable-title (optional)" type="media-type (optional)" resourceType="resource-type" capabilities="operation"/> ...repeat as needed... </links>
Example 51-4 Link in a JSON Document Fragment
"links": [ { "href":"opaque-URI", "template":"opaque-template-URI (optional)", "rel":"rel-name", "title":"human-readable-title (optional)", "type":"media-type (optional)", "resourceType":"resource-type", "capabilities":"operation" }, ...repeat as needed... ]
The resourceType
, rel
, and capabilities
attributes of the hypermedia link provide metadata that enable clients to determine which URI (href
or template
) to use, without having to parse the URIs directly. The URIs are opaque—the metadata determines which link is useful in a given circumstance.
Multiword field, element, and attribute names are formatted in camel case, unless the representation is attempting to conform to a specification not under the service author's direct control. Acronyms are treated as normal words with their case adjusted accordingly (for example, fooXml
or xmlFoo
). See Example 51-5 and Example 51-6.
This section includes the following subsections that describe the different attributes of the hypermedia link:
The resourceType
link attribute indicates the type of resource to which the link points. Clients should use the resourceType
to determine the expected response bodies for GET
and POST
and allowable request bodies for POST
and PUT
.
For more information, see Section 51.8, "Navigating Hypermedia Using HTTP."
The rel
link attribute indicates the relationship of the linked object to the current object (that is, the object that contains the list of links). The value of this attribute is a space-separated list of the following currently supported values:
self
—The linked object is the current object
related
—The linked object is related to the current object
via
—The linked object is the source of the information for the current object
alternate
—The linked object is a substitute for the current object (typically, the same object in another format, such as an HTML page that displays the current object)
urn:oracle:webcenter:parent
—The linked object is the parent of the current object. That is, the linked object owns the current object
Note: Some REST APIs for some WebCenter features may contain additionalrel link attributes. See the REST API documentation for each specific feature for more information. |
The capabilities
link attribute indicates which methods are supported by the linked resource.
Links are returned only if a client is allowed to access that resource. User authorization can affect the capabilities a client has with the links returned in a response representation. In general, services only return the capabilities that the current authorized user has permission to execute and that the resource supports.
If there is no link, then the client cannot access the resource. If a link has no capabilities, then it is not returned to the client, meaning that the client does not have permission to do anything with that link (even read it).
Capability-based expression of hypermedia links communicates the range of operations that the client can expect to succeed, which allows the client to dynamically configure any associated UI to provide the best overall user experience.
The value of this attribute is a space-separated list of the following values:
urn:oracle:webcenter:create
—This maps to the HTTP verb POST
urn:oracle:webcenter:read
—This maps to the HTTP verb GET
urn:oracle:webcenter:update
—This maps to the HTTP verb PUT
urn:oracle:webcenter:delete
—This maps to the HTTP verb DELETE
Note: TheresourceIndex link only returns the read capability, even if the user is authorized with additional capabilities. |
Note: Querying a resource for the allowed HTTP verbs usingOPTIONS returns the verbs that the resource can support in general, and does not take a user's access into account. The capabilities attribute in a link describes exactly what the current user can do with the current resource. OPTIONS may return more HTTP verbs than the current user is allowed. |
The type
link attribute indicates the media types supported by the linked object.
All REST services, except for CMIS, support both XML (application/xml
) and JSON (application/json
) media type. CMIS currently supports only ATOM. For more information about CMIS REST APIs, see the Oracle Fusion Middleware Content Management REST Service Developer's Guide.
The template
link attribute indicates that the client can use a URI template, instead of the href
URI, to provide parameterized values for the linked object. Links must include at least an href
or a template
URI, but can include both.
Some hypermedia links support request query parameters that allow the client to configure the link in different ways. Rather than force the client to know the URI format and manually build the URI, URI templates are used. These templates allow client code to easily insert data into a URI without having to understand exactly how the URI works. This maintains the opacity of hypermedia URIs and protects the client from changes to the URI format.
Example 51-7 shows a URI template including several request query parameters.
Example 51-7 URI Template
http://host:port/.../lists?startIndex={startIndex}&itemsPerPage={itemsPerPage}&q={searchTerms}&projection={projection]
WebCenter REST APIs use a simple slot replacement syntax that follows many industry URI template schemes.
For example, using the template in Example 51-7, to see 10 list items on the first page, the client would provide a value of 1
for the startIndex
parameter and a value of 10
for the itemsPerPage
parameter, as shown in Example 51-8.
Example 51-8 URI Template with Parameter Values
http://host:port.../lists?startIndex=1&itemsPerPage=10
You must URL-encode special or reserved character in parameter values. For example, to search lists for a person named Günter, you must URL-encode the ü as shown in Example 51-9.
Note: All unused parameters must be removed from a template before it can be used. Clients may not submit unprocessed templates to the service that produced it; doing so results in undefined behavior, generally returning a status code of 500.Clients must process templates into valid URI form before submitting to the server. Clients must replace slots with appropriate values, taking care to properly URI encode any value replacing the slot token. If a client does not have a suitable value for one or more of the slots in the template, then it must replace the slot token with an empty string. |
Common Request Query Parameters
Many resources support a common set of request query parameters. For example, when retrieving a collection of entities, it is common to change the shape of the results set by limiting the quantity or details of the results. The REST framework uses the following request parameters to scope results and provide security:
startIndex
—Specifies the index of the first matching result that should be included in the result set (0-n ... zero based). This is used for pagination.
itemsPerPage
—Specifies the maximum number of results to return in the response (1-n). This is used for pagination.
q
—Specifies implementation-specific searching. Searches may be specified using the following format (square brackets [] denote optional values):
[[field1:[operand]][:]value1[;field2:operand:value2]]
For example:
&q=login:equals:monty &q=title:contains:issues &q=creator:equals:monty;description:contains:Urgent
While each resource uses the same format for the q
parameter, the way search is implemented is different depending on the resource being searched. For more information about how each resource implements search, see the chapter for the specific service.
projection
—Reserved for implementation-specific projection of model representations, such as variable recursion depth, field or attribute filtering. Valid values are summary
or details
.
For example, requesting a projection of summary
for a collection of lists, returns only the title, description, and hypermedia links. Requesting a projection of details
results in the server sending back a collection of lists that includes all the column metadata for each list. This may require additional processing time or database queries on the server.
The following example request results in the response entity containing a deeper object graph.
http://host:port/...lists&projection=details
data
—Returns a comma separated list of data sets and items. This parameter lets clients specify what data they would like to receive. For example, a mobile device application might use this parameter to limit the amount of XML data returned. If both the projection
and data
query string parameters are present, the data
parameter will be used to determine which data to return. If you specify the constant 'data'
as the data parameter, all the basic information will be returned for the resource.
For information about how these parameters are supported by specific resources, see the chapter for the appropriate service.
A collection of items
makes up the actual content of responses. This is at the same level as the links
section described previously. Each item (including the top-level tag in each response) has one common attribute (resourceType
) in addition to resource-specific content and format. For details beyond the resourceType
, see the chapter for the specific service.
See Example 51-13 for an example that describes a collection of entities/items. Example 51-15 describes a single entity/item.
You can navigate REST service hypermedia in a similar way to that used to browse and interact with HTML or an ATOM feed. Interactions are performed on the resources identified by links using HTTP methods. The REST services return response codes and response bodies to the client, and the client uses the hypermedia in the response to drive further interactions.
Table 51-2 describes the general pattern followed when constructing opaque resource URIs. The resourceType
differentiates whether the HTTP method operates on a collection of resources or an individual resource.
Table 51-2 HTTP Methods
HTTP Method | Response for a Collection of Resources | Response for an Individual Resource |
---|---|---|
|
Returns resource collection container (200 HTTP response code) |
Returns resource (200 HTTP response code) |
|
Cannot update a collection of resources (405 HTTP response code) |
Updates and returns resource (200 HTTP response code) |
|
Creates and returns a new resource within the collection. Note: Can return a 201 or 204 HTTP response code. The returned code depends on whether the newly created object is directly addressable or not. For instance, activities cannot be addressed individually, so they return a 204 no-content response code. |
Cannot create a resource within an individual resource (405 HTTP response code) |
|
Cannot delete a collection of resources (405 HTTP response code) |
Deletes resource (204 HTTP response code) |
Collection resources generally support reading a collection (GET) and creating a subordinate to that collection (POST). Individual resources generally support reading a resource (GET), updating a resource (PUT), and deleting a resource (DELETE).
HTTP Response Status Codes
Table 51-3 describes the potential response status codes.
Table 51-3 HTTP Response Status Codes
HTTP Response Status Code | Description |
---|---|
200 |
OK. Upon successful completion of a |
201 |
Created. Upon successful completion of a |
204 |
No content, or any request that does not return content. For example, creating an object that cannot be linked. Upon successful completion of a |
400 |
Bad Request. The URI was malformed or could not be processed; for example, the IDs were not formatted correctly, or the ID was supplied in the URI on a |
401 |
Unauthorized. Client may retry by submitting credentials. This may be accompanied with a fault response body to help diagnose the issue. |
403 |
Forbidden. Client does not have permission to perform a particular action, such as creating or deleting a resource. Re-authenticating as the same user does not help. This may be accompanied with a fault response body to help diagnose the issue. |
404 |
Not Found. Referencing a specific resource with an ID, but that resource does not exist. |
405 |
Method Not Allowed. This includes a list of valid methods for the requested resource. |
406 |
Not Acceptable. The Accept header media type(s) sent by the client are not supported for the requested operation.This may be accompanied with a fault response body to help diagnose the issue. |
409 |
Conflict. Possibly the resource ID is in use, or an entity has been modified by another process during an update.This may be accompanied with a fault response body to help diagnose the issue. |
422 |
Bad entity body, the data in the body, although syntactically correct, was not valid, or could not be processed; for example, invalid data when updating a row. |
500 |
Internal server error. The server encountered an unexpected condition that prevented it from fulfilling the request. |
501 |
Not Implemented. The server does not support the functionality required to fulfill the request. This is the appropriate response when the server does not recognize the request method and is not capable of supporting it for any resource. |
All of the WebCenter REST URIs reference protected resources (similar to protected web pages) and require authentication for access.
Note: The one exception to the authenticated access rule is access to the CMIS resources. CMIS resources can be accessed anonymously through the CMIS URI entry point:
See also Section 51.10, "Security Considerations for CMIS REST APIs." |
You can pass this authentication in with the request using basic authentication, or you can configure the client and the WebCenter REST service to use single sign-on. For more information about single sign-on, see the section "Configuring a WebCenter Application to Use Single Sign-On" in the Oracle Fusion Middleware Administrator's Guide for Oracle WebCenter.
Basic authentication sends the user's password in plain text. If you use this type of authentication, you should consider securing the connection using SSL. For more information, see the section "Configuring WebCenter Applications and Components to Use SSL" in the Oracle Fusion Middleware Administrator's Guide for Oracle WebCenter.
To provide additional security, every URI, for both href
and template
attributes, includes a security token parameter. The security token is user-scoped. This means that it is based on and scoped to an authenticated user and can be bookmarked or cached across that user's sessions. These security tokens help prevent Cross-Site Request Forgery (CSRF) attacks.
For example:
<link template="opaque-template-uri/@me?startIndex={startIndex}&itemsPerPage={itemsPerPage} &token=generated-token" resourceType="urn:oracle:webcenter:messageBoard" href="opaque-uri/@me?token=generated-token" capabilities="urn:oracle:webcenter:read" />
Note: The security token is not used for authentication or identity propagation. |
WebCenter REST APIs operate under the identity of the authenticated user. For example, the group space REST APIs only return information for, and allow changes to, group spaces to which the user has access.
The CMIS REST APIs do not use the same authentication scheme as the other WebCenter REST APIs. Whereas other WebCenter REST APIs do not allow unauthenticated access and prompt the user for authentication before allowing access, the CMIS REST APIs do allow unauthenticated access.
If a document requires authentication information and does not receive that information (because it is being accessed by an unauthenticated user), a 404 error is returned. This does not necessarily mean that the document cannot be found, rather that the (unauthenticated) user does not have the appropriate permissions to access the document. For the request to succeed, it should include basic authentication headers to identify the current user.
CMIS stands for Content Management Interoperability Services, a standard REST interface for Enterprise Content Management Systems. For more information, see Oracle Fusion Middleware Content Management REST Service Developer's Guide.
This section describes the common types that are shared by multiple WebCenter REST APIs.
Common types provide a consistent way to reference objects used in the WebCenter REST APIs.
This section includes the following subsections:
This is a generic data type that represents a user in the system. It is used by several APIs, for example to identify the author of a message board or feedback message, or a user's manager or direct reports. It is made up of the following elements:
guid
—The GUID of the user
id
—The login ID of the user
displayName
—The display name of the user
The personReference
also includes a link to the user's profile icon. You can control the size of the icon by providing values: small
, medium
, or large
.
Depending on where the personReference
type is included, it can also return links to the associated REST APIs of the generating response. For example, if the personReference
type is included as the author in a message board response, it includes links to message board services.
This is a generic data type that represents a group space. It is used by several APIs, for example in the activity stream, to identify a group space in which a particular activity occurred. It is made up on the following elements:
guid
—The GUID of the group space
name
—The name of the group space
displayName
—The display name of the group space
The groupSpaceReference
also includes an html link, rest link, and icon link.
Portable Contact types provide users with a standard way to access their address books and friends lists over the web. Portable Contact types are used by the Profile component of the People Connections service.
Note: These types are based on the Portal Contact Types in WebCenter. They may include additional data. |
This section includes the following subsections:
This is a portable contact type that provides information about the user's name. It is made up of the following elements:
formatted
—The formatted version of the full name of the user, for example, Michael David Jones Ph.D.
familyName
—The family name, or last name, of the user, for example Jones
givenName
—The given name, or first name, of the user, for example Michael
honorificSuffix
—The honorific suffix of the user, for example, Esq. or Ph.D.
initials
—The first initials of the user, for example, M. D.
maidenName
—The maiden name of the user
Some of the elements may not be present depending on the user repository configuration and data.
This is a portable contact type that provides information about the user's address. It is made up of the following elements:
formatted
—The formatted version of the full address
type
—The type of the address, for example, Home, Work
streetAddress
—The street address
poBox
—The post office box number
locality
—The city or locality
region
—The state or region
postalCode
—The zip code or postal code
country
—The country
Some of the elements may not be present depending on the user repository configuration and data.
This is a portable contact type that provides information about the user's organizational affiliation. It is made up of:
name
—The name of the organization
employeeNumber
—The employee number of the user
employeeType
—The employee type of the user.
department
—The department within the organization to which the user belongs
defaultGroup
—The default group to which the user belongs
title
—The job title of the user within the organization
description
—A textual description of the user's role within the organization
expertise
—The expertise of the user within the organization
startDate
—The date when the user joined the organization
Some of the elements may not be present depending on the user repository configuration and data.
This is a generic object that contains data for a wide variety of contact information. It is made up of the following elements:
primary
—A boolean value that identifies whether this is the primary piece of information of this type for this person. The primary element may not be present and is only relevant if there are multiple values for the same type of data.
value
—The value for this type
type
—The type of information. Valid types are:
standard
: with valid values of work
, home
, other
phoneNumber
: with valid values of work
, home
, fax
, pager
, mobile
photos
: with a valid value of thumbnail
Client-side developers need to know how to handle HTTP cache headers in both requests and responses. Individual resources that have a "last modified" date are also return entity tags. The entity tags can be used to make retrieval of a specific entity more efficient. To learn more about the use of entity tags in caching, please see the Hypertext Transfer Protocol specification.
A proxy server is typically employed to avoid cross-domain request problems associated with making XMLHttpRequest (XHR) calls from a browser client. These calls are typically associated with the Ajax development technique for creating rich, interactive client-side interfaces. REST APIs are typically used within this kind of client-side development scenario.
For more information on setting up a proxy server, see "Configuring a Proxy Server" in the Oracle Fusion Middleware Administrator's Guide for Oracle WebCenter.
This section includes some examples illustrating how to use the WebCenter REST APIs. It includes the following subsections:
This section includes examples to illustrate how to navigate the REST service hypermedia. The examples show how to read messages on a message board, post messages to another user's message board, and delete unwanted messages.
This section includes the following subsections:
The first step is always to access the Resource Index (Example 51-10).
This request returns a list of the top-level URI entry points to the RESTful services, including the entry point for the message board (Example 51-11).
Example 51-11 Response to Accessing the Resource Index
200 OK Accept: application/json;charset=UTF-8 { "resourceType": "urn:oracle:webcenter:resourceindex", "links": [ { "resourceType": "urn:oracle:webcenter:resourceindex", "capabilities": "urn:oracle:webcenter:read", "rel": "self", "href": "http://host:port/rest/api/resourceIndex" }, { "resourceType": "urn:oracle:webcenter:messageBoard", "capabilities": "urn:oracle:webcenter:read", "href": "opaque-messageBoard-URI" }, ...repeating for other services... }
You can examine this list to find the URI that you require to access your message board. You should look for the link with a resourceType
of urn:oracle:webcenter:messageBoard
. The href
for this link is the one that you require to access your message board.
For other resources rel
, type
, and template
also help find the correct link.
Once you have determined the correct URI for your message board, you can send a GET request to that URI to read your messages (Example 51-12).
To read messages on a message board, you must be logged in.
The response provides information about all the messages on your message board (Example 51-13).
Example 51-13 Response to Retrieving Messages from Your Message Board
200 OK Accept: application/json;charset=UTF-8 { "resourceType": "urn:oracle:webcenter:messageBoard", "links": [ { "resourceType": "urn:oracle:webcenter:messageBoard", "capabilities": "urn:oracle:webcenter:read urn:oracle:webcenter:create", "rel": "self", "href": "opaque-messageBoard-URI" } ] "items": [ { "resourceType": "urn:oracle:webcenter:messageBoard:message", "links": [ { "resourceType": "urn:oracle:webcenter:messageBoard:message", "capabilities": "urn:oracle:webcenter:read urn:oracle:webcenter:delete", "rel": "self", "href": "opaque-message-URI" } ] "id": "89add57c-7a35-4d35-b24f-ea9259612eb8", "body": "What's up? It's been a while. Some of us are going to Conner O'Neal's after work. Want to go?", "created": "2009-09-10T11:18:46.696-0700", "author": { "id": "carl", "displayName": "carl", "guid": "649A27F09D5C11DEBFAA799CBD41D9B8", "links": [ { "resourceType": "urn:oracle:webcenter:people:person", "capabilities": "urn:oracle:webcenter:read", "rel": "via", "href": "opaque-person-URI" }, { "resourceType": "urn:oracle:webcenter:messageBoard", "capabilities": "urn:oracle:webcenter:read urn:oracle:webcenter:create", "href": "opaque-messageBoard-URI-for-Carl" }, { "type": "text/html", "resourceType": "urn:oracle:webcenter:spaces:profile", "capabilities": "urn:oracle:webcenter:read", "rel": "alternate", "href": "opaque-profile-URI" } ] }, } ], "startIndex": 0, "itemsPerPage": 1, }
From the response you can see that you have read
and create
capabilities on your message board. So you can read its contents and post new messages.
In addition, the response also includes a collection of items (in this case the collection consists of just a single item). These items, with a resourceType
of urn:oracle:webcenter:messageBoard:message
, are the messages on your message board. The capabilities
attribute for the message indicates that, for this particular message, you can read it or delete it from your message board.
For each message, the response provides the following information:
id
—the identifier of the message
body
—the text of the message
author
—the author of the message. The author element is also made up of several other elements:
id
—the identifier, or user name, of the author of the message
displayName
—the name of the author, formatted for display
guid
—the globally unique identifier of the author
Within the author
element there is also a collection of three links. The resourceType
of these links are:
urn:oracle:webcenter:people:person
—enables you to view information about the author of the message
urn:oracle:webcenter:messageBoard
—enables you to read or create a message on the author's message board
urn:oracle:webcenter:spaces:profile
—enables you to read a text/html
document of the author's profile
Now that you have read the message on your message board, you probably want to reply to Carl on his message board. To do this you should send a POST
request to the URI for Carl's message board.
To find the correct URI, use the href
from the author
link with resourceType
of urn:oracle:webcenter:messageBoard
.
A POST
request creates a subordinate resource of the resource to which you post it. In this case, we are posting to the messageBoard
, so we should post its subordinate resource: message
(Example 51-14).
Example 51-14 Creating a Message on Another User's Message Board (POST)
POST opaque-messageBoard-URI-for-Carl
Accept: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
{
"body": "sure; see you guys at 6."
}
The response shows that your message was successfully created on Carl's message board (Example 51-15).
Example 51-15 Response to Creating a Message on Another User's Message Board
201 Created Content-Type: application/json;charset=UTF-8 { "id": "36b8464f-afda-44b5-90ad-8ecedcb040a3", "body": "sure; see you guys at 6.", "created": "2009-09-10T12:21:09.785-0700", "resourceType": "urn:oracle:webcenter:messageBoard:message", "links": [ { "resourceType": "urn:oracle:webcenter:messageBoard:message", "capabilities": "urn:oracle:webcenter:read urn:oracle:webcenter:update urn:oracle:webcenter:delete", "rel": "self", "href": "opaque-message-URI" }, "author": { "id": "mike", "displayName": "mike", "guid": "649657609D5C11DEBFAA799CBD41D9B8", "links": [ { "resourceType": "urn:oracle:webcenter:people:person", "capabilities": "urn:oracle:webcenter:read", "rel": "self", "href": "opaque-person-URI" }, { "resourceType": "urn:oracle:webcenter:messageBoard", "capabilities": "urn:oracle:webcenter:read urn:oracle:webcenter:create", "href": "opaque-messageBoard-URI" }, { "type": "text/html", "resourceType": "urn:oracle:webcenter:spaces:profile", "capabilities": "urn:oracle:webcenter:read", "rel": "alternate", "href": "opaque:profile:URI" } ] } ] }
A PUT
request is very similar to a POST
request, except that it is performed on the resource being edited, instead of on the parent resource.
From the response to your earlier POST
request, when you created your message on Carl's message board, you can see that you have read
, update
, and delete
capabilities on the message. You can also see that the href
provides the URI for your message. Something came up at work and you must stay a bit later. Using the URI for your message, you can now send a PUT
request to update the message and let Carl know that you are going to be late (Example 51-16).
Example 51-16 Updating a Message (PUT)
PUT opaque:message:URI
Accept: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
{
"body": "working late; see you guys at 7."
}
The response is nearly identical to that of POST
, except that the body
contains your updated message (Example 51-17).
Performing a DELETE
request on a resource deletes it, if you have the delete
capability on the resource. The link to your message on Carl's message board supports delete
.
You decide to delete the message that you left on Carl's message board (Example 51-18).
The response is simply a status code of 204 (Example 51-19).
Note: DELETE is idempotent, meaning that it can be sent multiple times with the same result. Therefore if you try to delete the same object twice, you still receive the same 204 response even though it has previously been deleted. |
To properly display Activity Stream data, you must:
Retrieve the Activity Stream URI entry point
Retrieve the Activity Stream data
Process the Activity Stream data for display
This sample is available on the Oracle WebCenter Demonstrations and Samples page on the Oracle Technology Network (OTN) at:
http://www.oracle.com/technology/products/webcenter/release11_demos.html
In Example 51-20:
The getResourceURL
method shows you how to retrieve the URI entry point for the Activity Stream service by retrieving the JSON data for the main Resource Index (/rest/api/resourceIndex
) and locating the URI for the Activity Stream resource in that data.
The formatMessage
method processes the Activity Stream data into a displayable format. This involves locating an individual message and replacing any template parameters in the message with the name of the object or user that corresponds to that parameter. The parameters also include links to display the object or user. They may contain links to REST services for those objects or users, if available.
Note: To get the Resource Index and Activity Stream JSON data, make Ajax requests using Javascript (and possibly a client-side scripting library like Dojo) and pass the resulting data into the appropriate methods. |
Example 51-20 Displaying Activity Stream Data
/* Parse the resourceIndex to find the specified URL and * return it. * * @Param jsonData the JSON data retrieved from calling * the /rest/api/resourceIndex URL. * @Param strResourceType the resource type of the URL * you want to retrieve from the resourceIndex data. * E.g., 'urn:oracle:webcenter:activities:stream' */ function getResourceURL(jsonData, strResourceType) { // Using the HATEOAS model, we browse the returned links // looking for the one with the correct resource type. for (var i = 0; i < data.links.length; i++) { if (data.links[i].resourceType == strResourceType) { return data.links[i].href; } } } /* Parse the resourceIndex to find the activity stream URL and * then load it. * * @Param jsonData the JSON data retrieved from calling * the /rest/api/resourceIndex URL. */ function getActivitiesURL(jsonData) { // Parse the JSON data to get the activities URI entry point. var strHref = getResourceURL(jsonData, 'urn:oracle:webcenter:activities:stream'); // INSERT CODE HERE: Implement getting the JSON data from the // strHref URL with the Accept header set to "application/json", // and use the formatMessage(index, jsonData) function to get // the displayable activity message for each activity. } /* Replace activity message parameters. * * @Param index the index of the activity to process * @Param jsonData the JSON data retrieved from calling * the /rest/api/resourceIndex URL. */ function formatMessage(index, jsonData) { var activity = jsonData.items[index]; var strMessage = activity.message; // Look for activity parameters and replace them in the message. if (activity.templateParams && activity.templateParams.items) { for (var i = 0; i < activity.templateParams.items.length; i++) { var param = activity.templateParams.items[i]; // Each parameter also has a set of links which at least // includes an HTML link and possibly a REST API link. strMessage = strMessage.replace(param.key, param.displayName); } } if (activity.detail) { strMessage = strMessage + "<br><font size='1'>" + activity.detail + "</font>"; } return strMessage; }
Ext is a popular JavaScript library for building tables and forms and linking them to REST web services. The following example illustrates how to display a list of connections from the People Connections service REST APIs using an Ext JsonStore
and GridPanel
.
For more information about Ext, see:
Note: You must run Ext on a web server. If that server is not your WebCenter instance, then you will run into cross-site scripting problems. If you cannot run the example on your WebCenter server, and you want to use Ext, then consider a proxy, such as Apache or WebCenter Ensemble. |
This sample is available on the Oracle WebCenter Demonstrations and Samples page on the Oracle Technology Network (OTN) at:
http://www.oracle.com/technology/products/webcenter/release11_demos.html
This section includes the following subsections:
Example 51-21 shows the simple HTML page. The HTML page must reference the required Ext files and the JavaScript file, connections.js
. The body of the page contains a destination div
. The GridPanel
is rendered in this div
.
Example 51-21 The HTML Page
<head> <link rel="stylesheet" type="text/css" href="../../extjs/resources/css/ext-all.css" /> <script type="text/javascript" src="../../extjs/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="../../extjs/ext-all.js"></script> <script type="text/javascript" src="connections.js"></script> </head> <body> <div id="connections"></div> </body>
The JavaScript file, connections.js
, enables the population of the list when the page loads. Example 51-22 shows that all of the JavaScript is a parameter to Ext.onReady()
.
Example 51-22 connections.js as a Parameter to Ext.onReady
Ext.onReady(function() { //our code goes here });
The JavaScript does the following:
First, it queries the Resource Index (Example 51-23).
Notice that the example asks for responses in JSON format.
Example 51-23 Querying the Resource Index
//Connection Information
var resourceIndexURL = "http://webcenter_server/rest/api/resourceIndex";
var peopleServiceURN = "urn:oracle:webcenter:people";
var connectionsURN = "urn:oracle:webcenter:people:person:list";
var connectionsRel = "urn:oracle:webcenter:people:person:list:connections";
//create a request for the resourceIndex
Ext.Ajax.request({
url: resourceIndexURL,
method: 'GET',
success: function(response, opts) {
//locate the people connections entry point
var index = Ext.decode(response.responseText);
for (x in index.links) {
if (index.links[x].resourceType == peopleServiceURN)
getMe(index.links[x].href);
}
},
failure: function(response, opts) {
alert('Could not communicate with the REST server.');
},
headers: {
'Accept': 'application/json'
},
});
Next, the JavaScript sends an authenticated request to the People Connections entry point, and gets the Connections list URL from the response (Example 51-24).
By default, the REST API uses Basic authentication for secure APIs. In the example, credentials for passing to the Connections list URL are Base64 encoded. Ext does not have a Base64 utility object itself, but one has been developed for it at:
http://extjs.com/forum/showthread.php?p=167166
Example 51-24 Getting the Connections List URL
function getMe(requestURL) { //Encode a token to identify yourself with secure parts of the REST API. var unencodedToken = "username" + ":" + "password"; var encodedToken = "Basic " + Ext.util.base64.encode(unencodedToken); //call the connections entry point Ext.Ajax.request({ url: requestURL, method: 'GET', success: function(response, opts) { //locate the link for my connections if (index.links[x].resourceType == connectionsURN) { if (index.links[x].rel == connectionsRel) getMyConnections(index.links[x].href, encodedToken); } }, failure: function(response, opts) { alert('Could not communicate with the REST server.'); }, headers: { 'Accept': 'application/json', 'Authorization' : encodedToken }, }); }
The next step is to send an authenticated request to the Connections list URL (Example 51-25).
Example 51-25 Sending an Authenticated Request to the Connections List URL
function getMyConnections(requestURL, encodedToken) { Ext.Ajax.request({ url: requestURL, method: 'GET', success: function(response, opts) { displayData(response, opts); }, failure: function(response, opts) { alert('Could not communicate with the REST server.'); }, headers: { 'Accept': 'application/json', 'Authorization' : encodedToken }, }); }
Then, the JavaScript adds the response to a JsonStore
(Example 51-26).
Previously, this example named displayData()
as the handler for a successful call to the Connections list URL. Now, it creates the function and adds the JsonStore
code. In the JsonStore
, the data model for the data is defined and mapped to results expected from the REST call.
Example 51-26 Adding the Response to a JsonStore
function displayData(response, opts) { //create a datamodel to display the JSON var store = new Ext.data.JsonStore({ // store configs autoDestroy: true, storeId: 'forumStore', // reader configs root: 'items', idProperty: 'id', fields: ['displayName', {name:'email', mapping:'emails.value'}, {name:'phone', mapping:'phoneNumbers[0].value'}] }); }
The JavaScript creates an Ext GridPanel
to display the JsonStore
by including the code in Example 51-27 in displayData()
.
The grid defines columns and a title. It also includes other display options, such as the size of the table.
Example 51-27 Creating a GridPanel to Display the JsonStore
//create the Grid var grid = new Ext.grid.GridPanel({ store: store, columns: [ {id: 'conn', header: 'Connection', width: 80, sortable: true, dataIndex: 'displayName'}, {header: 'Email', width: 120, sortable: true, dataIndex: 'email'}, {id: 'phone', header: 'Phone', width: 120, sortable: true, dataIndex: 'phone'} ], stripeRows: true, autoExpandColumn: 'conn', height: 200, width: 400, title: 'My Connections', viewConfig: {scrollOffset: 2} });
Finally, the code renders the GridPanel
by including the line in Example 51-28 in displayData()
.
Figure 51-1 shows the list of connections from the People Connections service REST APIs.
The following example shows how to use REST APIs to update a user's WebCenter profile status.
Note: You must host the sample on a web server (for example, Apache or Oracle HTTP Server) or an application server. To avoid cross site scripting errors, you should proxy URL access to the REST service. On Apache or OHS, the conf commands would look like (changemyspaceshost and port accordingly):
ProxyPass /webcenter/ http://myspaceshost:port/webcenter/ ProxyPassReverse /webcenter/ http://myspaceshost:port/webcenter/ ProxyPass /rest/ http://myspaceshost:port/rest/ ProxyPassReverse /rest/ http://myspaceshost:port/rest/ ProxyPreserveHost on |
This sample is available on the Oracle WebCenter Demonstrations and Samples page on the Oracle Technology Network (OTN) at:
http://www.oracle.com/technology/products/webcenter/release11_demos.html
Updating user status involves making a sequence of asynchronous AJAX calls to get the URL for the status object:
urn:oracle:webcenter:resourceindex urn:oracle:webcenter:people urn:oracle:webcenter:people:person:status
The HTML page for updating user status (Example 51-29) includes an input field where users can enter the new status message (statusMessage
). Clicking the Update Status button (or pressing Enter) calls the updateStatus
method to make the initial call to the Resource Index.
Example 51-29 HTML Body
<body> <div>New status message: <input id="statusMessage" type="text" onkeyup="{if (event.keyCode==13) updateStatus();}" maxlength="250" size="60" /></div> <div> <button id="button1" onclick="updateStatus();">Update Status</button> </div> <div id="statusResults"></div> </body>
Figure 51-2 shows the HTML page.
The code in Example 51-30 retrieves the Resource Index (resourceIndexURL
variable set to /rest/api/resourceIndex
). The Resource Index is returned as an AJAX request object (resourceIndexRequest
).
Example 51-30 Retrieving the Resource Index
function updateStatus() { // Set the UI to busy state. This is cleared in the success and error callbacks setUIBusy("Updating status..."); //get the Resource Index resourceIndexRequest.get( resourceIndexURL, resourceIndexCallback, clearUIBusy); }
The getResourceURL
method shown in Example 51-31 traverses the links in the data returned by a REST call to find a specified string (URN) that identifies the required resource type.
Example 51-31 Traversing the Links
function getResourceURL(data, strResourceType) { for (var i = 0; i < data.links.length; i++) { if (data.links[i].resourceType == strResourceType) { return data.links[i].href; } } return null; }
Example 51-32 uses getResourceURL
to parse the Resource Index to find the user profile URL. The data is returned as an AJAX request object (profileRequest
).
Example 51-32 Retrieving the User Profile
function resourceIndexCallback(data) { //get my user profile profileRequest.get( getResourceURL(data, 'urn:oracle:webcenter:people'), profileCallback, clearUIBusy); }
Example 51-33 takes the new status message provided by the user in the HTML page (statusMessage
) and uses request.put
to update the status object (retrieved by again calling getResourceURL
).
Example 51-33 Retrieving the Status Object
function profileCallback(data) { profile = data; // get the URL for the status object var url = getResourceURL(data, 'urn:oracle:webcenter:people:person:status'); // get the new status and escape double quotes var newStatus = document.getElementById ('statusMessage').value.replace(/\"/g. "\\\""); //send a JSON string representing the new status object var statusMessage = '{"note": "' + newStatus + '"}'; statusRequest.put( getResourceURL(data, 'urn:oracle:webcenter:people:person:status'), statusMessage, renderStatusPutResults, clearUIBusy); }
The renderStatusPutResults
method, shown in Example 51-34, renders the new status object.
Example 51-34 Rendering the New Status Object
function renderStatusPutResults(data) { var name = profile.displayName; // get the URL for my profile HTML page in WebCenter Spaces var profileURL = getResourceURL(profile, 'urn:oracle:webcenter:spaces:profile'); var html = 'Status for <a href="' + profileURL + '" target="_blank">' + name + '</a> is: ' + data.note; // clear the UI busy state and print the new status message clearUIBusy(html); }
Example 51-35 shows the code for disabling and reenabling the UI.
Example 51-35 Disabling the UI
function setUIBusy(message) { document.getElementById('statusResults').innerHTML = message; document.getElementById('button1').disabled = true; document.getElementById('statusMessage').disabled = true; } function clearUIBusy(message) { document.getElementById('statusResults').innerHTML = message; document.getElementById('button1').disabled = false; document.getElementById('statusMessage').disabled = false; }
Example 51-36 shows the library that assists in AJAX calls. Most of this is not WebCenter specific and works for any XHR requests to a service that returns JSON.
The library includes a reusable XHR object. This object supports HTTP GET, POST, PUT, and DELETE. All functions are asynchronous and take a URL and two callback functions, one for success, and one for failure. Success calls are made with a JavaScript object containing the return data. Failure calls are made with an error string. POST and PUT also take a data argument which must be a JSON string.
Example 51-36 AJAX Library
function AjaxRequest() { // constructor to create an object oriented AJAX request var xhr = null; // get XHR object. Should work for IE 6+, Safari, and Mozilla based browsers if (window.XMLHttpRequest) { xhr = new window.XMLHTTPRequest; } else { try { xhr = new ActiveXObject('MSXML2.XMLHTTP.3.0'); } catch (ex) { xhr = null; } } if (xhr == null) { alert("Your browser does not support AJAX"); } this.get = function(url, callback, errorCallback) { xhr.open('GET', url, true); // the REST APIs return XML by default. Please return JSON xhr.setRequestHeader('Accept', 'application/json; charset=utf-8'); sendRequest(null, callback, errorCallback); }; this.post = function(url, data, callback, errorCallback) { xhr.open('POST', url, true); // set headers to send and receive JSON xhr.setRequestHeader('Accept', 'application/json; charset=utf-8'); xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8'); sendRequest(data, callback, errorCallback); }; this.put = function(url, data, callback, errorCallback) { xhr.open('PUT', url, true); // set headesr to send and receive JSON xhr.setRequestHeader('Accept', 'application/json; charset=utf-8'); xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8'); sendRequest(data, callback, errorCallback); }; this.deleteResource = function(url, callback, errorCallback) { xhr.open('DELETE', url, true); sendRequest(null, callback, errorCallback); }; // set the callbacks and send the request with data, if any function sendRequest(data, callback, errorCallback) { xhr.onreadystatechange = function () { processResponse(xhr, callback, errorCallback); }; xhr.send(data); } function processResponse(xhr, callback, errorCallback) { var data = null; // can get called here many times. 4 means really done if (xhr.readyState == 4) { // let's call any HTTP codes in the 200s success if (xhr.status >= 200 && xhr.status <300) { // convert response text into a JSON object. This is insecure. // data should not be blindly evaluated from the server return. // consider using json2.js http://www.JSON.org/js.html data = eval('(' + xhr.responseText + ')'); callback(data); } else { // we got an error. Format an error string data = 'Error: ' + xhr.status + ' ' + xhr.statusText + '<br />' + xhr.responseText; errorCallback(data); } } } }