Simplifying the OpenText Content Server REST API

My employer Kwe.li GmbH (opens new window) has released an open source JavaScript module for simplifying the use of the OpenText Content Server REST API. You can find the @kweli/cs-rest module on npm (opens new window), GitHub (opens new window), and unpkg (opens new window).

The module simplifies three aspects of the REST API:

  • acquisition and mangement of the OTCSTicket authentication token;
  • requests requiring use of the multipart/form-data content type (since Content Server doesn't support application/json); and
  • a consistent interface for uploading documents with Node.js or the browser.

# Authentication

Every request in the OpenText Content Server REST API requires an OTCSTicket token to be added to the request header (with the exception of the authentication request). A user must first get a token before they can start using the API.

A token can be retrieved in one of two ways:

  • making a POST request to the api/v1/auth endpoint with a username and password; or
  • having the token generated and embedded into the HTML, which can be read by the underlying application.

Authenticating with a username and password is useful when developing a standalone application outside the browser context (e.g., Node.js, Python, Java, etc). However, it makes little sense in the browser context. It would be annoying to prompt a user for a username and password - especially if they are already authenticated.

The second approach is to render the token in the HTML page and make it available to the underlying application. This is the approach taken by the SmartUI (e.g., open a SmartUI page, view the page source, scroll to the bottom, and look for ticket) and doesn't require prompting the user.

There are a few ways to programatically fetch a valid ticket on behalf of an authenticated user:

  • in OScript with the $CSUI.Utils.GetOTCSTicket() function;
  • with RHCore with the RHUser otcsticket (opens new window) property method; or
  • in WebReports with the hidden [LL_REPTAG_OTCSTICKET /] data tag.

However you obtain the ticket, it will expire according to the policy defined on the "Configure Security Parameters" administration page. Fortunately, the REST API returns a fresh token in the header of each response, which the client can use in the subsequent request to keep the session active.

The @kweli/cs-rest module simplifies the handling of authentication by:

  • providing a consistent interface for creating a session regardless if it's with a token or username and password, and
  • automatically capturing and using the latest authentication token when it's returned in a response.

Here's how to use it:

const { Session } = require("@kweli/cs-rest");

// with a username and password
const session = new Session({
  baseURL: "https://.../cs.exe",
  username: "Admin",
  password: "******",
});

// or, with a token
const session = new Session({
  baseURL: "https://.../cs.exe",
  otcsticket: "<token>",
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14

That's pretty much it. The session object wraps an axios (opens new window) instance, which is a promised based HTTP client. The session instance manages the authentication token and proxies the most common request types (GET, POST, PUT, PATCH. DELETE, and OPTIONS) to the axios instance. You just have to use it. For example:

const response = await session.get("api/v1/nodes/2000");
1

# Content type multipart/form-data

Content Server doesn't support the commonly used application/json content type. Content Server requires the client to submit requests (typically POST, PUT, and PATCH) using multipart/form-data, which requires the use of the browser FormData API (opens new window). For example, to create a new folder with axios:

const formData = new FormData();
formData.append("type", 0);
formData.append("parent_id", 2000);
formData.append("name", "My New Folder");

const response = await axios.post("api/v2/nodes", formData);
1
2
3
4
5
6

This is somewhat verbose and not supported in Node.js (since Node.js doesn't natively support FormData).

The @kweli/cs-rest module simplifies the syntax by providing a postForm, putForm, and patchForm method to condense this:

const response = await session.postForm("api/v2/nodes", {
  type: 0,
  parent_id: 2000,
  name: "My New Folder",
});
1
2
3
4
5

The postForm, putForm, and patchForm methods also work with Node.js.

# Other Helpers

The module provides a few shortcuts for common tasks. For example, adding a folder:

const response = session.nodes.addFolder(2000, "My New Folder");
1

A document can be uploaded with:

const response = session.nodes.addDocument(2000, file, "My New File.pdf");
1

The file parameter depends on the context:

  • In the browser, file is an instance of File (opens new window).
  • In Node.js, file is a file path (e.g., 'C:/temp/my_file.pdf')

The API is by no means complete and will grow as needed.

# Availability

As I wrote in the introduction you can find the @kweli/cs-rest module on npm (opens new window), GitHub (opens new window), and unpkg (opens new window). You can also jump directly to the README.md (opens new window).

We hope you find it useful!