Creating a Custom Web API - Documentation topics on: custom web api,json,rest,restful,xml,.

Creating a Custom Web API

You can create your own custom Web API within dotCMS in a number of ways

Create your own custom Web API. Extend the dotCMS REST API to provide additional information not natively provided by dotCMS.

The following methods can be used to implement a custom web API in dotCMS (in order, from the simplest to the most involved):

Redirect to an External Site

If you have an existing site which provides a web API, you can configure URL rewrite rules to redirect API calls made to your dotCMS site to the external site (while still displaying the domain and paths configured in dotCMS). This allows you to quickly migrate an existing web API to your dotCMS site without having to re-implement the API within dotCMS.

Create an API Page Directly in dotCMS

You can create pages in dotCMS which use Velocity or scripting code to deliver content which you determine in a whatever format you wish.

  1. Create a new Widget which contains the code which implements your API.
    • Your Widget code should do the following:
      • Process any URL parameters or Request header parameters required by your API.
      • Pull appropriate dotCMS content based on the API call.
      • Format the content appropriately for the API (e.g. JSON, XML, etc.).
    • Note: You can use the Simple Widget Content Type to create your Widget code.
      • However if you plan to implement multiple different web API calls, you may wish to create a Widget Content Type to use for all of your API code.
  2. Add code to the Widget to set the content type of the page appropriately for the format of the data returned.
    • For example, to create a web API call that returns data in JSON format, add the following code to the widget:
      $response.setContentType("application/json")
      
  3. Create an appropriate folder within dotCMS to provide access to your web API.
    • The dotCMS REST API uses the path /api, so you can not use this same path (to prevent conflicts).
    • A top-level folder (for example /rest) is often preferable, to limit the length of your API URL.
  4. Create a new Page Asset inside your API folder (which represents a single API call you wish to support).
    • Configure the Page to use the Blank Template.
    • The URL of the page represents the URL used to access the specific API call.
  5. Add your Widget to your API page.

Example 1

The following code implements an API which performs a simple content pull (using an Elasticsearch Lucene Query), and returns the search results in JSON format:

$response.setContentType("application/json")

#if( $UtilMethods.isSet( $request.getParameter("search") ) )
    #set($searchterm = $request.getParameter("search"))
#else
    #set($searchterm = "invest")
#end

#set($results = $dotcontent.pull("+_all:$searchterm", 20, "title asc"))
$results

Note: The $dotcontent.pull() method returns the search results in JSON format, so no formatting of the results is necessary to deliver the API results in JSON format.

Example 2

The following code implements a more sophisticated API which performs a full Elasticsearch query (using the full Elasticsearch JSON query syntax), and returns the search results in XML format.

This requires a little more sophistication, since:

  • The values of Velocity variables ($searchterm and ${item.fields.identifier.value}) must be separated from the rest of the strings.
    • This is necessary to properly embed literal characters (which requires the use of both single and double quotes) in the query string.
  • The data is returned from the $estool.search() call in JSON format, but needs to be displayed in XML format.
$response.setContentType("application/xml")

#if( $UtilMethods.isSet( $request.getParameter("search") ) )
    #set($searchterm = $request.getParameter("search"))
#else
    #set($searchterm = "invest")
#end

## Submit the Elasticsearch query
#set( $querypre = '{
    "query": {
        "bool": {
            "must": {
                "term": {
                    "title": "' )
#set( $querypost = '"
                }
            }
        }
    }
}' )
#set($results = $estool.search("$querypre$searchterm$querypost"))

<RESULTS>
## Iterate through the results, displaying the Identifier of each result in an XML tag
#set($resp    = $json.generate($results.response))
#foreach($item in $resp.hits.hits)
    <CONTENT>
        <ID>${item.fields.identifier.value}</ID>
    </CONTENT>
#end
</RESULTS>

Develop a Plugin

The most complete (and most involved) method of implementing a web API in dotCMS is to implement a plugin. This allows you to provide almost any functionality you wish (via Java code), but requires both that you hook into the dotCMS REST API path with your plugin and integrate the plugin into dotCMS.

For more information on building plugins, please see the Developing documentation section.

For examples of code which provides dotCMS REST API functionality, please see the /dotCMS/src/main/java/com/dotcms/rest folder in the dotCMS Github Repository