Skip to main content

Caché Source Code File REST API Tutorial

This chapter provides a brief tutorial that demonstrates how to use the Caché Source Code File REST API by a series of examples. It contains the following sections:

API Basics

The API used by Atelier to access Caché source code files uses the REST architectural style. REST is named from “Representational State Transfer.” The Caché Source Code File REST API, like many REST APIs, uses the HTTP GET, POST, PUT, DELETE, and HEAD methods and uses JSON for incoming and outgoing message bodies.

To call an API method, you need to know the following:

  • HTTP method—which is one of the following: GET, POST, PUT, DELETE, or HEAD.

  • HTTP headers—provide context information for the call. The HEADERS used in this API include:

    • Authorization, which provides access to the server. Unless you have installed your server with minimal security, you need to provide a username and password to access the API.

    • Content-Type application/json, which specifies that the inbound payload is provided in JSON. You must specify this header for all POST and PUT methods.

    • If-None-Match, which allows a GetDoc or PutDoc call to check if the source code file was modified since it was last accessed.

  • URL—The URL consists of the following parts:

    • http://

    • server-name:port-number/—In this chapter, we assume that Caché is running on the local server and is using port 57772.

    • api/atelier/—This is defined by the web application that has the %Api.AtelierOpens in a new tab dispatch class.

    • URL part that identifies the method and target. This part can include fixed text and text that you specify to identify the namespace, document name, or type.

    For example, the URL part that identifies the GetDocNames method is v1/namespace/docs/. The complete URL for this method getting the documents from the SAMPLES namespace would be:

    http://localhost:57772/api/atelier/v1/SAMPLES/docnames

    The URL part that identifies the GetServer method is an empty string, so the complete URL for GetServer is:

    http://localhost:57772/api/atelier/

  • URL parameters—modifies the call. If the API method has URL parameters, they are described in the reference section.

  • Inbound JSON payload—format of the inbound message for POST and PUT methods.

  • Outbound JSON payload—format of the outbound message returned by the HTTP method.

Getting Information about the Caché Server

Typically, the first REST call you’ll make is to the GetServer method, which returns information about the Caché Source Code File REST API version number and the namespaces available on the server.

GET http://localhost:57772/api/atelier/

This call returns the following JSON message:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "content": {
      "version": "Cache for Windows (x86-64) 2017.2 (Build 691U) Wed Jun 7 2017 20:45:20 EDT",
      "id": "B70A630D-A34D-43B1-8EA5-EDF8F38992C4",
      "api": 2,
      "features": [
        {
          "name": "DEEPSEE",
          "enabled": true
        },
        {
          "name": "ENSEMBLE",
          "enabled": true
        },
        {
          "name": "HEALTHSHARE",
          "enabled": false
        }
      ],
      "namespaces": [
        "%SYS",
        "DOCBOOK",
        "ENSDEMO",
        "ENSEMBLE",
        "INVENTORY",
        "SAMPLES",
        "USER"
      ]
    }
  }
}

All Caché Source Code File REST API methods that return JSON messages use the same general format:

  • status errors—typically the Caché Source Code File REST API returns errors as HTTP status codes. This field is used under some unusual conditions and this element contains the Caché %Status value, which may contain the text for multiple errors.

  • status summary—contains a summary of the status errors.

  • console—contains the text that Caché would display on the console for this operation.

  • result—contains the results of the method.

The GetServer method returns information about the server in the “result” element. The result element contains one value “content”, which contains:

  • version—contains the version string of the instance of Caché or Ensemble running on the server.

  • id—contains the instance GUID of Caché.

  • api—specifies the version number of the Caché Source Code File REST API implemented in this version of Caché. In Caché 2016.2 and 2017.1, this version is 1. In Caché 2017.2, this version is 2. If the version returned in this element is 3 or greater, then there will be additional APIs that you can call.

  • features—indicates whether features such as DEEPSEE, ENSEMBLE, or HEALTHSHARE are enabled on this instance.

  • namespaces—lists the namespaces defined on the Caché server.

The GetNamespace method returns information about the specified namespace, including the databases that are mapped to the namespace and a hash for each database. The hash is useful for improving efficiency of communication with the server. But you can get the information about the source code files in the namespace with just the namespace information returned by GetServer.

Getting the Source Code Files Defined in a Namespace

To get the information about the source code files in a namespace:

  • First you get the names of the files with the GetDocNames method.

  • Then you get the contents of one file with the GetDoc method or you can get the contents of multiple files with the GetDocs method.

  • If you want to improve the network efficiency of your application, you can keep a local cache of the names and contents of the source code files and use the GetModifiedDocNames method to get only the names of the source code files whose contents have changed or use the GetDoc method with the If-None-Match HTTP header.

The GetDocNames method returns the names of all of the source code files in all databases mapped to the namespace.

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "content": [
      {
        "name": "%Activate.Enum.cls",
        "cat": "CLS",
        "ts": "2016-08-03 20:01:42.000",
        "upd": true,
        "db": "CACHELIB",
        "gen": false
      },
      ...
      {
        "name": "EnsProfile.mac",
        "cat": "RTN",
        "ts": "2003-09-19 13:53:31.000",
        "upd": true,
        "db": "INVENTORYR",
        "gen": false
      },
      ...
      {
        "name": "xyz.mac",
        "cat": "RTN",
        "ts": "2016-08-11 15:05:02.167",
        "upd": false,
        "db": "INVENTORYR",
        "gen": false
      }
    ]
  }
}

The following GetDoc call returns the contents of the xyz.mac file:

http://localhost:57772/api/atelier/v1/INVENTORY/doc/xyz.mac

This call returns:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "name": "xyz.mac",
    "db": "INVENTORYR",
    "ts": "2016-09-14 14:10:16.540",
    "upd": false,
    "cat": "RTN",
    "status": "",
    "enc": false,
    "flags": 0,
    "content": [
      "ROUTINE xyz",
      "xyz ;",
      "   w \"hello\""
    ]
  }
}

Creating a New File in a Namespace or Updating an Existing File

To create a new file in a namespace or update an existing file, you use the PutDoc method. For example, the following REST call creates a new xyz.mac source code file in the INVENTORY namespace or, if the xyz.mac file exists, this call replaces the original definition of the file with the new one. If you are updating a new file, you must specify either the HTTP header If-None-Match to identify the current version of the file or the ?ignoreConflict=1 URL parameter to bypass version checking. See PutDoc in the reference section for details.

PUT http://localhost:57772/api/atelier/v1/INVENTORY/doc/xyz.mac

You should specify the Content-Type application/json and the following JSON message:

{
 "enc": false,
 "content": [
   "ROUTINE xyz",
   "xyz ;",
   "   w \"hello\""
   ]
}

The call returns the following JSON message. It shows that the source code file has been created in the INVENTORYR database, which is the default database for routines in the INVENTORY namespace.

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "name": "xyz.mac",
    "db": "INVENTORYR",
    "ts": "2016-09-14 14:10:16.540",
    "upd": false,
    "cat": "RTN",
    "status": "",
    "enc": false,
    "flags": 0,
    "content": []
  }
}

If you are updating or creating a binary file, specify a true value for enc and include the binary contents as an array of blocks of the base64 encoding of the binary value.

Compiling a File

The Compile method compiles the source code files specified by name in the incoming JSON array. For example, to compile xyz.mac, POST the following:

http://localhost:57772/api/atelier/v1/INVENTORY/action/compile

with the following JSON message:

["xyz.mac"]

The method returns:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [
    "",
    "Compilation started on 08/14/2016 15:25:20 with qualifiers 'cuk'",
    "xyz.int is up to date. Compile of this item skipped.",
    "Compilation finished successfully in 0.008s."
  ],
  "result": {
    "content": []
  }
}

For some source code files, such as classes, Compile returns storage information in the returned content.

Deleting a File

The DeleteDoc method deletes the file specified in the URL. The DeleteDoc method has the same URL as the GetDoc method except that you use the HTTP Delete method instead of the Get Method. To delete xyz.mac, make an HTTP DELETE request with the URL:

http://localhost:57772/api/atelier/v1/INVENTORY/doc/xyz.mac

The Delete method returns the following JSON message:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "name": "xyz.mac",
    "db": "INVENTORYR",
    "ts": "",
    "cat": "RTN",
    "status": "",
    "enc": false,
    "flags": 0,
    "content": []
  }
}

When a file has been deleted, the timestamp, ts, has a value of "" (empty string).

Performing an SQL Query

The Query method performs an SQL query on any Caché database. For example, if your application wants to present the user with a list of Caché roles, it can discover them with the following call:

POST http://localhost:57772/api/atelier/v1/%25SYS/action/query

With the SQL query specified in the incoming JSON message:

{"query": "SELECT ID,Description FROM Security.Roles"}

This call returns the results of the SQL query as JSON in the result content element.

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "content": [
      {
        "ID": "%all",
        "Description": "The Super-User Role"
      },
      {
        "ID": "%db_%default",
        "Description": "R/W access for this resource"
      },
      ... 
      {
        "ID": "%sqltunetable",
        "Description": "Role for use by tunetable to sample tables irrespective of row level security"
      }
    ]
  }
}

You can use the Query method to query any table in Caché. The following call queries the SAMPLES Sample.Person database.

POST http://localhost:57772/api/atelier/v1/SAMPLES/action/query
{"query": "SELECT Age,SSN,Home_City,Name FROM Sample.Person WHERE Age = 25"}

This call returns:

{
  "status": {
    "errors": [],
    "summary": ""
  },
  "console": [],
  "result": {
    "content": [
      {
        "Age": 25,
        "SSN": "230-78-7696",
        "Home_City": "Larchmont",
        "Name": "DeLillo,Jose F."
      },
      {
        "Age": 25,
        "SSN": "546-73-7513",
        "Home_City": "Gansevoort",
        "Name": "Klingman,Thelma H."
      }
    ]
  }
}
FeedbackOpens in a new tab