Docs‎ > ‎Admin API Reference‎ > ‎

Creating a new API with REST

When you use the API Creator in a browser, all you're really doing is making REST calls to the API Server but using the admin REST API account.

Therefore everything you can do in the API Creator, you can also do using REST calls.

This page explains how to create a new API using the REST API.  Hint: There are command line utilities that provide similar functionality and mask some of the raw REST calls for you - see this page.

Step 0: which URL should you be talking to?

The easiest way to determine this is to look at the API Creator. In the following examples, instead of using https://api.acme.com, you'll want to use whatever you use in the Server field when you log in.


Step 1: get an auth token

The admin API is a REST API just like any other REST API created by CA Live API Creator. This is because, quite literally, the product is written using itself.

To get an auth token, we POST our credentials:

POST https://api.acme.com/rest/abl/admin/v2/@authentication
{
  "username": "admin",
  "password": "Password1"
}

This results in something like:

{
  "apikey": "3dc5388a87990211d38e31aa674733ce",
  "expiration": "2015-12-03T00:54:54.170Z"
}

From now on, we'll assume that we include this auth token in every request as an HTTP header:

Authorization: CALiveAPICreator 3dc5388a87990211d38e31aa674733ce:1


Step 2: figure out your basic information


You may not be aware of it, but Live API Creator can support multi-tenant installations. This means that you will need to know your account number first. This is pretty easy:

GET https://api.acme.com/rest/abl/admin/v2/accounts

We get back a single account object, e.g.:

[
  {
    "ident": 1708,
    "ts": "2015-10-29T10:46:31.979282Z",
    "name": "Acme account",
    "url_name": "acme",
    "status": "A",
    "public_key": null,
    "private_key": null,
    "@metadata": {
      "href": "https://api.acme.com/rest/abl/admin/v2/admin:accounts/1708",
      "checksum": "A:cce2b1e2975e2916",
      "links": [
        {
          "href": "https://api.acme.com/rest/abl/admin/v2/admin:logic_libraries?sysfilter=equal(account_ident:1708)",
          "rel": "children",
          "role": "logic_librariesList",
          "type": "http://www.espressologic.com/model/admin:logic_libraries"
        },
        {
          "href": "https://api.acme.com/rest/abl/admin/v2/admin:authproviders?sysfilter=equal(account_ident:1708)",
          "rel": "children",
          "role": "authprovidersList",
          "type": "http://www.espressologic.com/model/admin:authproviders"
        },
      etc...

So now we know that our account ident is 1708, and its url_name is acme. This will be handy later.

Next, let's figure out what our authentication provider is. We can do so by simply following the link whose role is authprovidersList in the response above:

GET https://api.acme.com/rest/abl/admin/v2/admin:authproviders?sysfilter=equal(account_ident:1708)

We will usually get a single object back:

[
  {
    "ident": 1666,
    "ts": "2015-10-29T10:46:31.981353Z",
    "name": "Built-in authentication",
    "comments": null,
    "auth_type_ident": 1,
    "class_name": "com.kahuna.server.auth.db.DefaultAuthProvider",
    "bootstrap_config_value": null,
    "class_location": "",
    "param_map": "datasource=AdminDB",
    "account_ident": 1000,
    "@metadata": {
      "href": "https://api.acme.com/rest/abl/admin/v2/admin:authproviders/1666",
      etc...

Our authentication provider's ident is 1666. We now have enough information to create a new API.

Step 3: create a new project/API

Let's create a new API:

POST https://api.acme.com/rest/abl/admin/v2/admin:projects
{
  "name": "My new API",
  "url_name": "myapi",
  "is_active": true,
  "account_ident": 1708,
  "authprovider_ident": 1666
}

The response will include several objects, including the new project:

{
  "statusCode": 201,
  "txsummary": [
    {
      "ident": 2033,
      "ts": "2015-12-01T15:57:46.406481Z",
      "name": "My new API",
      "url_name": "myapi",
      "comments": null,
      "status": null,
      "is_active": true,
      "account_ident": 1708,
      "authprovider_ident": 1666
      "@metadata": {
        "href": "https://api.acme.com/rest/abl/admin/v2/admin:projects/2033",
        "resource": "admin:projects",
        "verb": "INSERT",
        etc...

We get back more than one object because, when we created a new API/project, several other objects were automatically created: an API key (a.k.a. auth token), some roles, etc...

We now have a new API, its URL name is myapi (we'll need that later), and its ident is 2033. We know the creation was successful because the POST call returned a status of 201.

Step 4: create a database connection

The last basic step to create a new API is to connect it to a database:

POST https://api.acme.com/rest/abl/admin/v2/admin:dbaseschemas
{
  "prefix": "cust",
  "name": "Customer database",
  "url": "jdbc:mysql://dbserver.acme.com:3306/customers",
  "catalog_name": "customers",
  "user_name": "cust_app",
  "password": "secret",
  "active": true,
  "project_ident": 2033,
  "dbasetype_ident": 1
}

If all the parameters are correct, we will get back something like:

{
  "statusCode": 201,
  "txsummary": [
    {
      "ident": 2032,
      "ts": "2015-12-01T16:13:16.472265Z",
      "conn_type": null,
      "prefix": "cust",
      "name": "Customer database",
      "comments": null,
      "datasource_name": null,
      "url": "jdbc:mysql://localhost:3306/test",
      "catalog_name": "test",
      "schema_name": null,
      "user_name": "abl",
      "password": "2:ApOA/E3Th8nzAh+6v6Gb/NktiuGNnvH2Z6fzvLIno8OnunxZsllVbg==",
      "salt": "+qVMK0PpfE/VgU+IQZJb8vjGV1L4+VvMUvnvicEv",
      "port_num": null,
      "read_only": null,
      "schema_editable": null,
      "admin_url": null,
      "active": true,
      "status": null,
      "project_ident": 2033,
      "dbasetype_ident": 1,
      "@metadata": {
        "href": "https://api.acme.com/rest/abl/admin/v2/admin:dbaseschemas/2032",
        "resource": "admin:dbaseschemas",
        "verb": "INSERT",
        "links": [
        etc...

Notice that the database password was not stored in the clear. It was salted using a random string, then encrypted using a strong encryption algorithm (we can specify our own key at the container level).

What valid values can we provide for dbasetype_ident, you ask? Let's find out with:

GET https://api.acme.com/rest/abl/admin/v2/admin:dbasetypes

We get back:

[
  {
    "ident": 1,
    "ts": "2015-10-29T10:46:31.858488Z",
    "name": "MySQL",
    "description": "MySQL Database",
    "version_name": "All versions",
    "driver_class_name_list": "org.mariadb.jdbc.Driver,com.mysql.jdbc.Driver",
    "catalog_term": "Database",
    "schema_term": null,
    "url_prototype": "jdbc:mysql://<host>:<port>/<database>",
    "driver_help": null,
    "@metadata": {
      "href": "https://api.acme.com/rest/abl/admin/v2/admin:dbasetypes/1",
      "checksum": "A:b80a746d15e6a187"
    }
  },
  {
    "ident": 2,
    "ts": "2015-10-29T10:46:31.858488Z",
    "name": "Oracle",
    etc...

and we can choose the ident of the desired database type.

Step 5: verify the new API

At this point, if the connection to the database was successful, we should have the default API in place. By default, a user "demo" and a user "guest" should have been created, both with a default password ("Password1" - remember to change it, or delete these users, before you get serious with this new API).

Let's start by getting an auth token for the new API:

POST https://api.acme.com/rest/acme/myapi/v1/@authentication
{
  "username": "demo",
  "password": "Password1"
}

We get back an auth token for our new API:

{
  "apikey": "b1226e0cb79b301eb947ece897326a2e",
  "expiration": "2015-12-03T00:54:54.170Z"
}


Important note: it's remarkably easy to get confused between API's. We are now dealing with two very different API's:

 https://api.acme.com/rest/abl/admin/v2/...The admin API: you use it to query and manipulate API's, database connections, resources, rules, etc...
 https://api.acme.com/rest/acme/myapi/v1/... Our brand-new API: used to query and manipulate data in your database (customers and orders in our example)

Make sure that you are talking to the right one. If you get a puzzling error (most likely an authentication error, since the auth token for one API obviously will not work in a different API), check your URL and make sure you're talking to the correct API.

From now on, our HTTP header will use this new auth token, not the one for the admin API:

Authorization: CALiveAPICreator b1226e0cb79b301eb947ece897326a2e:1


Let's make sure our database schema was properly read (obviously the details will depend on your database schema):

GET https://api.acme.com/rest/acme/myapi/v1/@tables

And we should see a list of the default endpoints, created from the database schema:
[
  {
    "@metadata": {
      "href": "https://api.acme.com/rest/default/myapi/v1/@tables/cust:customers"
    },
    "prefix": "cust",
    "entity": "customers",
    "name": "cust:customers"
  },
  {
    "@metadata": {
      "href": "https://api.acme.com/rest/default/myapi/v1/@tables/cust:orders"
    },
    "prefix": "cust",
    "entity": "orders",
    "name": "cust:orders"
  },
etc...

And we can retrieve some customers:

GET https://api.acme.com/rest/acme/myapi/v1/cust:customers

which should return some data, e.g.:

[
  {
    "cust_no": 54321,
    "name": "Jones Inc",
    "balance": 1234.56,
    "city": "Anytown",
    "@metadata": {
      "href": "https://api.acme.com/rest/acme/myapi/v1/cust:customers/54321",
      "checksum": "A:9dc29d18f94b803c",
      "links": []
    }
  },
  etc...

A few more tips and tricks

If you want to do something that the API Creator is doing, a great way to peek under the hood is to look at what network calls the browser is making. For instance, on Chrome, creating a new resource results in:

Screenshot of Chrome debugger