JSON API
The JSON API is a path-based JSON API, described by an OpenAPI (opens in a new tab) 3.1 spec, that accepts and returns plain JSON. Actions defined in your schema become JSON endpoints like /api/json/<actionName>
.
You can download the OpenAPI 3.1 spec for your JSON API from the API explorer page in the Keel console by clicking on the "API definitions" button in the top-right of the page.
Types
The built-in Keel types are mapped to JSON types in the following way:
Keel type | JSON type |
---|---|
Text | string |
Number | number |
Boolean | boolean |
Timestamp | string (ISO8601 format) |
Date | string (ISO8601 format) |
File | See Files |
Enums
Enums defined in your Keel schema are represented as strings in both inputs and responses
enum Category {
Sports
Finance
Politics
}
model Post {
fields {
category Category
}
actions {
create newPost() with (category)
}
}
Optional inputs
If an input is marked as optional in your Keel schema then it is valid to completely omit it from the request, otherwise it must be provided.
JSON schema validation
Requests made to your JSON APIs are validated against a JSON schema (opens in a new tab) for that action. If the request does not pass validation the API will return an HTTP 400
along with a list of vaidation errors.
{
"code": "ERR_INVALID_INPUT",
"message": "one or more errors found validating request object",
"data": {
"errors": [
{
"error": "Invalid type. Expected: string, given: integer",
"field": "id"
}
]
}
}
Creating a new record
You can define an action for creating a new record in your Keel schema using the create action type. In the JSON API these actions accept the write inputs (the ones after with
) and return the newly created record.
model Profile {
fields {
username Text @unique
bio Text
}
actions {
create createProfile() with (username, bio)
}
}
Reading a single record
You can define an action for reading a single record in your Keel schema using the get action type. In the JSON API these actions return the record or null if the record could not be found.
model Profile {
fields {
username Text
}
actions {
get getProfile(id)
}
}
Updating a record
You can define an action for updating a single record in your Keel schema using the update action type. In the JSON API these actions accept an object with where
and values
keys and return the record that was updated. The read inputs of the action (first set of parenthesis) go in the where
object and the write inputs (those after with
) go in the values
object.
model Profile {
fields {
username Text @unique
bio Text
}
actions {
update updateBio(id) with (bio)
}
}
Updates with no values
Update actions don't have to take any write inputs. For example you could define an action that publishes a post that uses a @set
expression to update the record. For these cases you can omit the values key from the request.
model Post {
fields {
published Boolean
}
actions {
update publishPost(id) {
@set(post.published = true)
}
}
}
Listing records
You can define an action for listing many records in your Keel schema using the list action type. In the JSON API the inputs for these actions should be provided under a where
key and accept query objects that allow for complex filtering. The return type of these actions is an object containing results
and pageInfo
keys.
model Book {
fields {
title Text
genre Text
releaseDate Date
}
actions {
list listBooks(title?, genre?, releaseDate?)
}
}
Filtering
We can use a list action to perform queries like:
- Find all books whose title contains the word "Love"
- Find all books whose genre is "Sci-Fi" or "Crime" and were released in the last year
This is possible because in a list action each input accepts a query object. For example an input that points to a Text
field in a Keel schema can be filtered using contains
or startsWith
.
At least one key must be provided and if multiple keys are provided they are AND'd together.
All Keel types have a corresponding query type that allow filtering in ways that make sense for that type, for example a Text
input can use contains
whereas a Number
input can use greaterThan
.
{
"equals": "cat",
"notEquals": "cat",
"contains": "cat",
"startsWith": "cat",
"endsWith": "cat",
"oneOf": ["cat"]
}
Pagination
The input type for a list action has four fields that relate to pagination.
first
- Only return the first N records. Can be used withafter
.last
- Only return the last N records. Can be used withbefore
.after
- Return records after this cursor.before
- Return records before this cursor.
The response of a list action contains a pageInfo
key which contains startCursor
and endCursor
fields. These values can be passed to after
or before
in subsequent queries. For example if you fetched the first 10 book records and in the response the endCursor
value was "1234" then to get the next 10 records you would pass "1234" to the after
input.
Functions
These docs talk about actions, which is the general term for both built-in actions (implemented by the Keel runtime) and functions (implemented by you using code). There is no difference between how built-in actions and functions are surfaced in the JSON API.