">
API | CodamAI - SaaS architecture and code assistant

API

Now let's have a look how you can use the CMS into your frontend (or backend) with code examples.

FunctionPort
API-Port8100
Admin Port (Metrics Health)8101
Swagger UIhttp://%yourcms%:8100/swagger-ui/

Overview

For a first look at the API of your CMS, you can open the Swagger UI. Just open the URL from the table above.

Swagger Example

img

Basics for the API

For each model you get some API Endpoints (if you did not disable them in the model configuration)

Main Information to fetch data from CMS

We have a very complex data fetch query to give you the best results for your application. It is a graphql - inspired query but on JSON build query.

Here you will see how you can fetch only id and name from a model:

{
  "response": [
    "id",
    "name"
  ]
}

You can also use wildcards and exclude fields you don’t need. There are two types of wildcard's. * responses all fields and all id from objects und lists. + returns all basic fields like string, integer, date and so on, but all objects and lists relationship will be null.

{
  "response": [ 
    "+" 
  ],
  "exclude": [
    "IBAN"
  ]
}

Fetch data from relationship fields

You can fetch data from relationships. If the relationship is from “n” side, and you receive a list, then you can add more filter or sort rules, to get the result you really required in frontend. Let’s have a look, where you can add additional information. A list of parameter is available at bottom of this page under Query API.

In this example, we fetch the id of the object, and all basic fields from the relationship bar. The response object work's recursive like each response on top.

WARNING

There will be created a subQuery for database fetch. Have this in mind, when you make recursive list fetches.

{
  "response": [
    "id",
    {
      "field": "bar",
      "response": [ "+" ]
    }
  ]
}

Query response order

You can simply create a ORDER BY query parameter in lists with the following parameters.

{
  "response": [
    "+"
  ],
  "parameter": {
    "order": [
      {
        "field": "position",
        "order": "ASC"
      }
    ]
  }
}

Example 1 Order by position with ASC. You can add multiple orders in row.

{
  "response": [
    "+",
    {
      "field": "children",
      "response": "+",
      "parameter": {
        "order": [
          {
            "field": "position",
            "order": "ASC"
          }
        ]
      }
    }
  ]
}

Example 2 Order subQuery also.

Query Where-Filter

{
  "response": [
    "+"
  ],
  "parameter": {
    "query": {
      "type": "AND",
      "filter": [
        {
          "key": "foo",
          "param": "LIKE",
          "value": "%bar%"
        },
        {
          "key": "count",
          "param": "EQ",
          "value": "1"
        }
      ]
    }
  }
}

Example 1 Search for "foo" contains "bar" (like filter) AND "count" = 1.

SELECT 'id' FROM someObject WHERE 'foo' like '%bar%' AND 'count' = 1

There are a lot of filters:

Query filter list

keyvalue
EQEquals → Must match
NEQNot Equals → everything else than given value
LIKELike parameter with wildcard option.
SAMEORBEFOREFor dates an numbers. Same or lower.
BEFOREFor date and numbers. Must be lower, not equals.
SAMEORAFTERFor dates an numbers. Same or higher.
AFTERFor date and numbers. Must be higher, not equals.
INAdd a list of id's and return all objects
ISNULLFind rows, where given field is null. Value option has no effect, you don't need to send.
ISNOTNULLFind rows, where given field is not null. Value option has no effect, you don't need to send.

Pagination in lists

You can fetch data with pagination in list query.

{
  "response": ["+"],
  "parameter": {
    "page": 0,
    "limit": 10
  }
}

Query Parameter

ParameterDescriptionRequiredDefaultExample
pageThe page parameter start at 0 and give you the ability for a pagination.no00
limitThe limit of the returned results. Use for pagination. Set to -1 return all values. But don’t use it on large lists. It will slow down your systemno103
queryThe query defines your parameters to filter the rows.no
orderOrder the result by given parametersno

Response of API Calls

The response of each is divided into _data and _meta. The meta contains all information about the result size and access. This result is a list result from query. The result from a “read“ request looks similar, but the data is an object, not a list.

{
  "meta": {
    "accessGranted": true,
    "totalCount": 1,
    "currentPage": 0,
    "currentPageSize": 1,
    "currentLimit": 10
  },
  "data": [
    {
      "id": "1",
      "children": [
        {
          "id": "someId",
          "someFoo": "someBar"
        }
      ]
    }
  ]
}

Authorize to Endpoints

All Endpoints are protected by the user access and identity management. You need to send the bearer token you get from authentication. (See Authorization Header below)

var data = JSON.stringify({
  "response": [
    "id"
  ]
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "http://127.0.0.1:8100/%Group%Model%%/read/%id%/");
xhr.setRequestHeader("Authorization", "Bearer %yourtoken%");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.send(data);

Create Endpoint (POST)

Now let's have a look on the create model endpoint. You can create Models with initial value with the parameter data and return all basic fields with default content and the id to process with the object.

URL Template and Example:

[POST] cms:8100/v2/%group%%model%/create
Example: https://cms.codamic.com/v2/OfferTeamplate/create

Header:

headervalue
authorizationBearer eyJhbG[...]yourToken
content-typeapplication/json

Body:

{
  "data": {
    "name": "test",
    "foo": "bar"
  },
  "response": [
    "*"
  ]
}

Postman Example

see: Postman Setup

Read Endpoint (POST)

If you know your object id, you can made a read call to fetch more data, as you would need in a list for example. Let's say you get a list ob objects with the Query Endpoint. The user select one element, and you will display more information, than you will use the read endpoint to select just the data you will display in detail dialog.

URL Template and Example:

[POST] cms:8100/v2/%group%%model%/read/%id%
Example: https://cms.codamic.com/v2/OfferTemplate/read/111-111-111-111

Header:

headervalue
authorizationBearer eyJhbG[...]yourToken
content-typeapplication/json

Body:

{
  "response": [
    "*",
    {
      "field": "addresses",
      "response": ["+"]
    }
  ]
}

Read: Singleton Model Endpoint

WARNING

The singleton model endpoint doesn't have a query, because there is only one. This difference in the read endpoint: it does not require the id.

URL Template and Example:

[POST] cms:8100/v2/%group%%model%/read/%id%
Example: https://cms.codamic.com/v2/UserSettings/read

Update Endpoint (POST)

With the update endpoint you can replace a row in the database. The difference to patch is, that you need to send all fields. Files you don’t send will be set to null.

You can update other rows in this call if you checked “recursive update“ in field options. If you update “person” and set “addresses” and activate the recursive update (and have access) all addresses will be updated too.

Items in addresses that are not existing will be decoupled from this item. (Not deleted)

URL Template and Example:

[POST] cms:8100/v2/%group%%model%/update
Example: https://[PATCH] .com/v2/OfferTeamplate/update/111-111-111-111

Header:

headervalue
authorizationBearer eyJhbG[...]yourToken
content-typeapplication/json

Body:

{
  "data": {
    "someFoo": "someBar"
  },
  "response": [
    "*",
    {
      "field": "addresses",
      "response": ["+"]
    }
  ]
}

Patch Endpoint (PATCH)

With the patch endpoint you can update particular data in a row.

You can update other rows in this call if you checked “recursive update“ in field options. If you update “person” and set “addresses” and activate the recursive update (and have access) all addresses will be updated too.

Items you do not set in arrays (like addresses) will stay untouched.

URL Template and Example:

[PATCH] cms:8100/v2/%group%%model%/update
Example: https://yourcms.yourdomain.com/v2/OfferTeamplate/update/111-111-111-111

Header:

headervalue
authorizationBearer eyJhbG[...]yourToken
content-typeapplication/json

Body:

{
  "data": {
    "someFoo": "someBar"
  },
  "response": [
    "*",
    {
      "field": "addresses",
      "response": ["+"]
    }
  ],
  "exclude": [
    "name"
  ]
}

Delete Endpoint (DELETE)

Delete one row with this endpoint. Be aware of errors, if there are rows that references to your row. Delete them first or activate the recursive delete option in field settings.

URL Template and Example:

[DELETE] cms:8100/v2/%group%%model%/delete
Example: https://yourcms.yourdomain.com/v2/OfferTeamplate/delete/111-111-111-111

Header:

headervalue
authorizationBearer eyJhbG[...]yourToken
content-typeapplication/json

Body:no body

Query Endpoint (POST)

Get a list from the database is the most common start point in a software. This is your endpoint to fetch, filter and sort lists.

WARNING

There is no query endpoint in singleton models.

URL Template and Example:

[POST] cms:8100/v2/%group%%model%/query
Example: https://yourcms.yourdomain.com/v2/OfferTeamplate/query/

Header:

headervalue
authorizationBearer eyJhbG[...]yourToken
content-typeapplication/json

Body:

{
  "parameter": {
    "page": 0,
    "limit": 10,
    "query": {
      "type": "AND",
      "filter": [
        {
          "key": "{fieldname}",
          "param": "LIKE",
          "value": "%{searchtext}%"
        },
        {
          "key": "{modelname}.{fieldname}",
          "param": "EQ",
          "value": "1"
        }
      ],
      "query": {
        "type": "OR",
        "filter": [
          {
            "key": "{modelname}.id",
            "param": "EQ",
            "value": "1"
          },
          {
            "key": "{modelname}.id",
            "param": "EQ",
            "value": "2"
          }
        ]
      }
    },
    "order": [
      {"field": "{fieldname}", "order":  "ASC"}
    ]
  },
  "response": [
    "*",
    {
      "field": "addresses",
      "response": ["+"]
    }
  ]
}

Query response lists

You can define the sub-queries by define parameters in the response. Have a look at the previous query. In the response you see a second query under the first query. Here you can define the sub-query. See DeepRestListPayload in the next chapter for definitions.

TS Interface: Parameter

interface ListOrderLogic {
    field: string,
    order: "DESC" | "ASC"
}
interface ListSearchFilter {
    key: string,
    param: "EQ" | "NEQ" | "...see list",
    value?: string
}
interface ListSearchLogic {
    type: "AND" | "OR",
    filter: ListSearchFilter[],
    group: ListSearchLogic[]
}
interface ListSearchParameter {
    query?: ListSearchLogic,
    page: number,
    limit: number,
    order?: ListOrderLogic[]
}
interface DeepRestListPayload extends RestListPayload {
    field: string
}

Query Parameter

interface RestListPayload {
    parameter: ListSearchParameter,
    response: (string | DeepRestListPayload)[],
    exclude: string[]
}

TS Interface: Response data

Single-Response

interface ResponseObject<T> {
    data: T
}

Query:

interface ResponseList<T> {
    data: T[]
}
Last Updated:
Contributors: mertins-d