super-api
v0.4.6
Published
Define a JSON API with JSON
Downloads
75
Readme
super-api
Define a JSON API with JSON
Quick start
Set up aliases:
alias super-api="coffee ~/Projects/super-api/super-api.coffee"
alias super-service="coffee ~/Projects/super-api/super-service.coffee"
Run the example Hello Service & API:
super-api examples/hello-api
super-service examples/hello-api/services/hello
Test the routes:
somata-repl
#| set url http://localhost:6399
'http://localhost:6399'
#| get $url/hello.json?name=Fred
'Hello, Fred!'
#| {greeting: "Beat it"} | put $url/hello/greeting.json
'Changed to Beat it'
#| get $url/hello.json?name=kid
'Beat it kid!'
Usage
Setup
An app directory requires at least app.json
and optionally views/
, static/
, and services/
:
simple-chat/
app.json
static/
js/
app.coffee
css/
app.sass
views/
index.jade
services/
simple-dynamodb/
index.coffee
create-websocket-url/
index.coffee
config.json
app.json
The app's name
, slug
, port
, routes
, and optionally middleware
are defined in app.json
.
Routes
Each route is defined as request
, steps
, and response
:
"routes": [
{
"request": { ... },
"steps": [ ... ],
"response": { ... },
},
...
]
Request
request
defines the incoming request's method
and path
.
"request": {
"method": "get",
"path": "/hello.json"
}
You may also define an optional auth
, which is a condition that will be expanded to true or false per request, and send a 401 response if false.
"request": {
"auth": "$res.locals.user.is_admin",
"method": "get",
"path": "/secret"
}
Steps
steps
is an array of steps which will be called in series. Right now there is step type, "remote", which will call a somata service with the given service
name, method
, and array of args
.
"steps": [
{
"type": "remote",
"service": "hello-service",
"method": "sayHello",
"args": [
"$req.query.name"
]
}
]
When the step returns some data, it is by default set in the response context as res.locals.data
. You can specify a custom return
key to set it as res.locals[return]
, for example to multiple steps of data around for some specific template variables.
"steps": [
{
"type": "remote",
"service": "hello-service",
"method": "sayHello",
"args": [
"$req.query.name"
]
},
{
"type": "remote",
"service": "reverse-service",
"method": "reverseString",
"args": [
"$res.locals.data"
],
"return": "reversed"
}
]
In the above example the first step does not define a return
key, so by default the data is set as res.locals.data
. The second step uses that data as an argument, but sets a different return
key "reversed". Now both res.locals.data
and res.locals.reversed
are available for the response.
Response
response
defines either the content_type
of the data to be used as a response (expects res.locals.data
to be set from some prior remote step), or a template
that will be rendered with an optional context
.
Respond with plain text:
"response": {
"content_type": "text/plain"
}
Render the template hello.jade
with a context variable title
set by some step:
"response": {
"template": "hello",
"context": {
"title": "$res.locals.title"
}
}
Render a template depending on some step's return value:
"response": {
"template": "$res.locals.template",
"context": {
"user": "$res.locals.user"
}
}
Option expansion
Values in request
, steps
, and response
definitions that match "$req" or "$res" will be expanded for each request, for example "$req.body", "$res.locals.data", or "$req.headers.token".
GET /hello?name=Jones
"$req.query.name" -> "Jones"