Reference
Each endpoint configuration (in /endpoint-configs) consists of path, method and processors where each processor is a JSON Object. The processor has one key which is the name of the processor.
{
"path": "/examples/hello-world" # path of this endpoint
"method": "get", # HTTP method
"processors": {
"onRequest": { # name of required first processor (required)
"Translator": { # processor component name
...
}
},
"otherProcessor": { # name of some other processor
...
}
}
}
An API call is handled by executing the processor named onRequest.
Each processor must update the model with the name of the next processor to be executed (i.e set processor name in field /next).
An API reponse is returned by the built-in processor named sendResponse.
Processor Components use JSON Templates in interaction with the model. Detailed documentation is provided below.
JSON Templates
JSON Templates makes it possible to specify any JSON structure and inject dynamic content directly into that JSON structure. To render the template it is applied to a model. A model is a JSON Object. To point to a value in the model from the JSON Template a JSON String with prefix $ followed by a JSON Pointer (RFC 6901) is used.
JSON Pointer example: "$/contacts/0/name" – the value of field name in the first element of the JSON Array named contact
JSON Template operations are JSON objects with one operator key starting with a $ (e.g {"$concat": ["Hello ", "$/contacts/0/name"]}).
Template example:
The following template creates an object with a field named name set to the result of concatenating firstName of the model, a space and lastName of the model.
{
"name": { # The field to be set by JSON template
"$concat": # Operator
[
"$/firstName", # Pointer to value in processor model
" ", # Single space static JSON value
"$/lastName" # Pointer to value in processor model
]
}
}
When the template is rendered for processor model below
{
"firstName": "Peter", # Pointed by "$/firstName"
"lastName": "Andersson" # Pointed by "$/lastName"
}
…the result is:
{
"name": "Peter Andersson" # "Peter" + " " + "Andersson"
}
Template Operators
| $array.lengthOf | Length of an array | {"$array.lengthOf": “$/someArray”} |
| $and | Logical AND | {"$and": [true, "$/someboolean"]} |
| $concat | Concatenates strings | {"$concat":["a", "b"]} |
| $divide | Divides a number by another number | {"$divide": [10.8, 2]} |
| $eq | Equal to | {"$eq": [3, "$/someVal"]} |
| $forEach | Apply operation for elements in array | {"$forEach": { |
| $if | Conditional operation | { |
| $loop | Loop until condition of $break is true. | {"$loop": [{"/counter": {"$sum":["$/counter", 1]}},{"$break":{"if": {"$eq": ["$/counter", 7]}, "thenReturn": "Value to return"}}]} |
| $mongodb.createObjectId | Creates a JSON object with one key ObjectId and value in hex format, e.g: {"ObjectId": "507f1f77bcf86cd799439011"} | {"$mongodb.createObjectId": "now"} |
| $multiply | Multiplies numbers | {"$multiply": [2, 3, 5.2]} |
| $not | Logical NOT | {"$not": "$/someboolean"} |
| $openapi.requestParameters | Parses and validates parameters based on OpenAPI format (see OpenAPI Parameter Serialization) | {"$openapi.requestParameters":"request": "$/request", "spec": [{"in": "query","name": "multiValueInt","required": true,"schema": {"type": "array","items": {“ type": "integer" }}"style": "form","allowReserved": true,"explode": false}]} |
| $optional | Allows for a field to be removed if value rendering $optional is undefined | {"will_be_removed": {"$optional": "$/non_existing_field"}} |
| $or | Logical OR | {"$or": [true, "$/someboolean"]} |
| $sum | Creates sum of numbers | {"$sum": [1, 2.6]} |
| $schema.validate | Validation based on JSON schema Possible outputFormats are FLAG, DETAILED, WEB_API_ERRORS_OBJECT, WEB_API_ERRORS_ARRAY JSON Schema specification | { {"type": "array"}, |
| $schema.filter | Filter based on JSON schema JSON Schema specification | {"schema": {"pattern", "^.*@.*$"}, "value": "$/value1" |
| $string.split | Splits string into array | {"$string.split": {"separator": "_",}} |
| $uri.path | Returns the path of an URI | {"$uri.path": "$/request/uri"} |
Processor Components
HTTP Component
The HTTP component makes calls over HTTPS.
Example of calling POST https://echo-api.3scale.net/hello-you?limit=10&offset=0
{
"Http": {
"baseUrl": "https://echo-api.3scale.net", # The prefix of each URL
"request": { # request object is JSON template (i.e may be dynamic)
"method": "post",
"path": "/hello-you", # Will be prefixed with baseUrl
"headers": {
"content-type": ["application/json"]
}
"query": "limit=10&offset=0", # Query string of URL
"body": {
"firstName": "Peter",
"lastName": "Andersson"
},
},
"response": "/response", # Location to put result in processor model
"next": "sendResponse" # Next processor to be executed
}
}
baseUrl
This is a static URL containing protocol (https://), host, port and base path (optional). The baseUrl cannot be changed. path and query from request may be appended.
request
request contains everything to be sent to the baseUrl.
method – the HTTP method to be used
path – the URL path to be appended to the baseUrl when sending the HTTP request. Must start with ‘/‘.
headers – an object where each key is an HTTP header name and the value is an array of one or more strings representing the header value(s).
query – a string representing the query of the URL.
response
A JSON Pointer target for the HTTP response in the model.
next
The next processor to be executed after the current.
MongoDB Component
The MongoDB component makes it possible to do native integration (i.e not via HTTP) with MongoDB.
Insert a document to database
{
"MongoDB": {
"connection": {{YOUR_MONGODB_CONNECTION_STRING}}, # Get your free cloud MongoDB instance from https://mongodb.com :)
"db": "playground",
"in": { # input to the MongoDB component
"insert": {
"collection": "accounts",
"documents": [ # array of documents to be inserted in the accounts collection
{
"_id": "$/accountId", # get _id from the processor model
"users": [
{
"email": "$/request/body/users/0/email", # get the email of a user from the request body
"emailConfirmed": false
}
]
}
]
}
},
"out": "/resultOfInsert", # put the result from MongoDB in the processor model at /resultOfInsert
"next": "yourNextProcessorToRun" # the next processor to run when this MongoDB processor is done
}
}
Result will appear at the location in the processor model specified in the out field where the value of ok says if the insert operation succeded {"ok": 1} or not {"ok": 0}
{
"ok": 1
... // more fields omitted for readability
}
More documentation on the MongoDB component will be provided soon.
If there is any specific use case you would like to see implemented. Please let me know.
Translator Component
The translator component transforms (i.e updates) the model. Transformations are specified by listing which fields in the model to update. Each transformation consists of one JSON Pointer key and a JSON Template defining the value.
Translator example:
Set model field of name response to value {"body":{"hello": "world"}} and set model field of name next to "sendResponse"
{
"Translator": { # Name of component
"transformations": [
{
"/response": # Pointer in processor model
{ # Value to set
"body": { #
"hello": "world" #
} #
}
},
{
"/next": # Pointer in processor model (next processor)
"sendResponse" # Next processor to be executed
}
]
}
}
