How to use the API

The actual API is (will be) documented mainly using Swagger. However, we have a standardized way of communicating with the back-end. This page is about some of our core principles.

All entities have their own base path. Time records, for example, have a base path /api/1.0/companies/cloudware/timeRecords. The base path is implied in the rest of this document.

CRUD - Create, Read, Update, Delete

  • Create: POST to /

  • Read a single entity: GET from /{id}

  • Read a list of entities: GET from /

  • Update: PUT or PATCH to /{id}. They both work the same way, but PATCH is a more logical method to use if you only want to update parts of an object, and thus only submit the changed parts.

  • Delete: DELETE from /{id}.

Includes

Moment uses an "includes" concept. This is done primarily to increase the speed of the requests. The main idea was taken from GraphQL: return only the data that is really needed. It:

  • works faster than the usual GET method

  • provides a standard way of getting additional metadata for requested data

  • helps us create pure inline-editing of single fields in our objects

How do includes work?

In some API requests you can specify which fields, parts of entities or what metadata you want get in the response.

Part - it is a group of fields that commonly uses together

Metadata - it is a data that contains additional information about entities that was return

NB!

  • Parts and metadata must be defined and implemented on back-end manually.

  • Fields within objects can be requested without any changes in the code.

  • The id field of all objects is always returned.

  • Fields of inner objects can be requested with .. Example: field customer.name will be returned as customerName.

  • Includes support Create (POST), Read (GET) and Update (PUT) methods.

Get a collection of objects

Here is an example request, asking for the base information in addition to currencyCode and metadata for the overviewPage, for offers:

GET <entities>/include/{parts:.+}
// Example
GET /offers/include/base+currencyCode+metadata.overviewPage
// Response
{
"content": [
{ "id": 1, "name": "Offer 1", "issueDate":"2018-01-01", "currencyCode": "USD", }, ...
],
"metadata": {
"totalSumInCompanyCurrency": 1726.50
}
}

POST/PUT entity

Here is an example request where we update the customer for an offer by POSTing a customer id. Using includes, we will get only a small portion of the customer info in return.

POST <entities>/include/{parts:.+}
PUT <entities>/{id}/include/{parts:.+}
// Example
PUT /offers/666999/include/customer.id+customer.name
BODY { "customerId": 3333777 }
// Response
{
"id": 666999,
"customerId": 3333777,
"customerName": "Richest AS"
}

Batch processing

Sometimes it's useful to do multiple things at once. For performance reasons, or because we want to keep all the actions within the same transaction, and make sure everything is rolled back if anything goes wrong.

Batch: POST to /batch, passing along an object containing all the instructions. The input JSON structure is as follows:

{
"create": [object1, object2, ...],
"update": {
"id1": { object1 },
"id2": { object2 },
...
},
"delete": [id1, id2, ...]
}

Here are a few examples (posted to /batch):

  • Create multiple entities: {"create":[{"projectId":4598,"name":"First entry"},{"projectId":4598,"name":"Second entry"}]}

  • Update multiple entities: {"update":{"11362":{"name":"New name 1"},"11361":{"name":"New name 2"}}}

  • Delete multiple entities: {"delete":[11357,11356]}

Here is an example of the returned JSON after a successful POST:

{
"created": [{
"projectId": 4598,
"name": "First entry",
"projectMembershipId": null,
"id": 11321
}],
"updated": [],
"createOrderIntact": true
}