Using the Guillotina API

Before we start using the Guillotina API, let's get us some test data to play with.

Using the testdata command, we'll populate our database with some data from wikipedia.

g testdata --per-node=5 --depth=2 --container=container

Interacting with the API

You can use whatever you'd like but this training will mention use of Postman.

Open up Postman and do a GET on http://localhost:8080/db/container with the username root and password root for basic auth.

We can not necessarily go over every single API but will touch on a few and give a general understanding of how to explore and use the API.

Creating content

To create content, do a POST request on a container or folder object.

POST /db/container

Create Item

Example request

POST /db/container HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Basic cm9vdDpyb290

{
  "@type": "Item",
  "id": "foobar"
}

Example response

HTTP/1.1 201 OK
Content-Type: application/json

{
  "@id": "http://localhost:8080/db/container/foobar",
  "@type": "Item",
  "parent": {
      "@id": "http://localhost:8080/db/container",
      "@type": "Container"
  },
  "creation_date": "2017-10-13T23:34:18.879391-05:00",
  "modification_date": "2017-10-13T23:34:18.879391-05:00",
  "UID": "f4ab591f22824404b55b66569f6a7502",
  "type_name": "Item",
  "title": null,
  "__behaviors__": [],
  "__name__": "foobar",
  "guillotina.behaviors.dublincore.IDublinCore": {
      "title": null,
      "description": null,
      "creation_date": "2017-10-13T23:34:18.879391-05:00",
      "modification_date": "2017-10-13T23:34:18.879391-05:00",
      "effective_date": null,
      "expiration_date": null,
      "creators": [
          "root"
      ],
      "tags": null,
      "publisher": null,
      "contributors": [
          "root"
      ]
  }
}
Request Headers:
 
Status Codes:

Adding behaviors

To add a dynamic behavior, we use the @behavior endpoint.

PATCH /db/container/foobar/@behaviors

Add behavior

Example request

PATCH /db/container/foobar/@behaviors HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Basic cm9vdDpyb290

{
  "behavior": "guillotina.behaviors.attachment.IAttachment"
}

Example response

HTTP/1.1 201 OK
Content-Type: application/json
Request Headers:
 
Status Codes:

Uploading files

Simple file uploads can be done with the @upload endpoint.

PATCH /db/container/foobar/@upload/file

Upload file

Example request

PATCH /db/container/foobar/@upload/file HTTP/1.1
Authorization: Basic cm9vdDpyb290

<binary data>

Example response

HTTP/1.1 200 OK
Content-Type: application/json
Request Headers:
 
Status Codes:

Then, to download the file, use the @download endpoint.

GET /db/container/foobar/@download/file

Download file

Example request

GET /db/container/foobar/@downlaod/file HTTP/1.1
Authorization: Basic cm9vdDpyb290

Example response

HTTP/1.1 200 OK
<binary data>
Request Headers:
 
Status Codes:

Uploading files with TUS

Guillotina also supports the TUS protocol using the @tusupload endpoint. The TUS protocol allows you to upload large files in chunks and allows you to have resumable uploads.

First, initialize the TUS upload with a POST

POST /db/container/foobar/@tusupload/file

Upload file

Example request

POST /db/container/foobar/@tusupload/file HTTP/1.1
Authorization: Basic cm9vdDpyb290
UPLOAD-LENGTH: 2097152
TUS-RESUMABLE: 1

Example response

HTTP/1.1 200 OK
Content-Type: application/json
Request Headers:
 
Status Codes:

Next, upload the chunks(here we're doing chunks of 1MB):

PATCH /db/container/foobar/@tusupload/file

Upload file

Example request

PATCH /db/container/foobar/@tusupload/file HTTP/1.1
Authorization: Basic cm9vdDpyb290
Upload-Offset: 0
TUS-RESUMABLE: 1
CONTENT-LENGTH: 1048576

< binary data >

Example response

HTTP/1.1 200 OK
Content-Type: application/json
Request Headers:
 
Status Codes:

And final chunk of 1MB:

PATCH /db/container/foobar/@tusupload/file

Upload file

Example request

PATCH /db/container/foobar/@tusupload/file HTTP/1.1
Authorization: Basic cm9vdDpyb290
Upload-Offset: 1048576
TUS-RESUMABLE: 1
CONTENT-LENGTH: 1048576

< binary data >

Example response

HTTP/1.1 200 OK
Content-Type: application/json
Request Headers:
 
Status Codes:

Unknown upload size

Guillotina's TUS implementation has support for the Upload-Defer-Length header. This means you can upload files with an unknown final upload size.

In order to implement this correctly, you will need to provide the Upload-Defer-Length: 1 header and value on the initial POST to start the TUS upload. You are then not required to provide the UPLOAD-LENGTH header.

Then, before or on your last chunk, provide a UPLOAD-LENGTH value to let TUS know the upload can not finish.

Simultaneous TUS uploads

Guillotina's TUS implementation also attempts to prevent simultaneous uploaders.

If two users attempt to start an upload on the same object + field at the same time, a 412 error will be thrown. Guillotina tracks upload activity to detect this. If there is no activity detected for 15 seconds with an unfinished TUS upload, no error is thrown.

To override this, send the TUS-OVERRIDE-UPLOAD: 1 header.

Modifying permissions

The @sharing endpoint is available to inspect and modify permissions on an object.

GET /db/container/foobar/@sharing

Get sharing information

Example request

GET /db/container/foobar/@sharing HTTP/1.1
Authorization: Basic cm9vdDpyb290

Example response

HTTP/1.1 201 OK
Content-Type: application/json

{
  "local": {
      "roleperm": {},
      "prinperm": {},
      "prinrole": {
          "root": {
              "guillotina.Owner": "Allow"
          }
      }
  },
  "inherit": [
      {
          "@id": "http://localhost:8080/db/container",
          "roleperm": {},
          "prinperm": {},
          "prinrole": {
              "root": {
                  "guillotina.ContainerAdmin": "Allow",
                  "guillotina.Owner": "Allow"
              }
          }
      }
  ]
}
Request Headers:
 
Status Codes:

To modify, we use the same endpoint but with a POST.

POST /db/container/foobar/@sharing

Add local permissions

Example request

POST /db/container/foobar/@sharing HTTP/1.1
Content-Type: application/json
Authorization: Basic cm9vdDpyb290

{
  "prinperm": [
    {
      "principal": "foobar",
      "permission": "guillotina.ModifyContent",
      "setting": "Allow"
    }
  ]
}

Example response

HTTP/1.1 201 OK
Content-Type: application/json

{}
Request Headers:
 
Status Codes:

There are three types of permission settings you can modify:

  • prinperm: principal + permission
  • prinrole: principal + role
  • roleperm: role + permission

Each change can use the following settings:

  • Allow : you set it on the resource and the children will inherit
  • Deny : you set in on the resource and the children will inherit
  • AllowSingle : you set in on the resource and the children will not inherit
  • Unset : you remove the setting

Exploring the API with Swagger

In the previous step, we installed guillotina_swagger. With Swagger, we can inspect any context and explore the API.

Visit http://localhost:8080/@docs

alt text

click the Authorize button

alt text

The Base API Endpoint setting is what the current context is that you're exploring on. If you create content at /db/container/foobar and want to explore that content's API, you should change the URL. Different content types will have different services available.

References