Build real RESTful APIs without writing one line of code.
Build real RESTful APIs without writing one line of code. Cool, right?
Now it works perfectly with MySQL.
[toc]
koa-restql requires node v6.0.0 or higher for (partial) ES2015 support.
npm install --save koa-restql
const koa = require('koa') const RestQL = require('koa-restql')let app = koa() let restql = new RestQL(sequelize.models) // Build APIs from
sequelize.models
app.use(restql.routes())
GET /user
If you just have one database table and sequelize model both named
user, just choose the right HTTP method to visit path as exactly same name as it.
Using
querystringin your url can add condition or limit for the request. For more details, read about
querystring.
Request
GET /user
Response
HTTP/1.1 206 Partial Content X-Range: items 0-2/10
[ { "id": 1, "name": "Li Xin" }, { "id": 2, "name": "Zhang Chi" } ]
Note:
Partial Contentworks. If the response was just part of the list, the API would like to response HTTP status code 206.
Request
GET /user/1
Response
{ "id": 1, "name": "Li Xin" }
Note: Request path with id will always respond an object.
To define an 1:1 association with sequelize, use
model.hasOne()or
model.belongsTo().
Request
GET /user/1/profile
Response
{ "id": 1, "user_id": 1, "site": "https://github.com/crzidea" }
Note: This example is for
hasOne(). If the
profilewas an association defined with
belongTo(), there should not be
user_idfield.
To define an 1:N association with sequelize, use
model.belongsTo().
Request
GET /user/1/messages
Response
[ { "id": 1, "content": "hello" }, { "id": 2, "content": "world" } ]
Request
GET /user/1/messages/2
Response
{ "id": 2, "content": "world" }
To define an N:M association with sequelize, use
model.belongsToMany().
Basicly, you can use the same way to request n:n association as 1:N association. The difference is response.
Request
GET /user/1/friends/2
Response
{ "id": 2, "name": "Zhang Chi", "friendship": { "id": 1, "user_id": 1, "friend_id": 2 } }
Note: RestQL will respond the target model with another model referred
throughoption.
Another noticeable problem is, you can not do the following query with association path although it is supported by sequelize:
models.user.findAll( { include: models.user.association.friends } )
But, fortunately, you can implement the query with
querystringlike this:
GET /user?_include%5B0%5D=friends
RestQL could do all CRUD operations for you. Just choose the right HTTP method to access either the resource or the association path.
Supported HTTP verbs:
HTTP verb |
CRUD |
---|---|
GET | Read |
POST | Create |
PUT | Create/Update |
DELETE | Delete |
Supported HTTP method with body:
HTTP verb |
List | Single |
---|---|---|
POST | Array/Object | × |
PUT | Array/Object | Object |
Listpath examples:
/resource
/resource/:id/association, association is
1:nrelationship
/resource/:id/association, association is
n:mrelationship
Singlepath examples:
/resource/:id
/resource/:id/association, association is
1:1relationship
/resource/:id/association/:id, association is
1:nrelationship
/resource/:id/association/:id, association is
n:mrelationship
Note:
PUTmethod must be used with
unique key(s), which means you can not use
PUTmethod with a request body without an
unique key.
To use
POSTor
PUTmethod, you should put data into request body. Example:
POST /user{ "name": "Li Xin" }
It's strongly recommended that use
qsto stringify nesting
querystrings. And this document will assume you will use
qsto stringify querystring from JavaScript object.
Example:
qs.stringify({a: 1, b:2}) // => a=1&b=2
To understand RestQL querystring, there are only 3 rules:
Every keys in querystring not start with
_, will be directly used as
whereoption for
sequelize#query(). Example:
// query { name: "Li Xin" } // option for sequelize { where: { name: "Li Xin" } }
Every keys in querystring start with
_, will be directly used as
sequelize#query().
// query { _limit: 10 } // option for sequelize { limit: 10 }
includeoption for
sequelize#query()should be passed as
Stringof association name.
// query { _include: ['friends'] } // option for sequelize { include: [ models.user.association.friends ] }
Sometimes, you want modify
queryin your own middleware. To do so, you should modify
this.restql.queryinstead of
this.request.queryor
this.query, because the
queryMUST be parsed with the package
qs, not
querystring(which is default package of koa).
There are at least 2 ways to implement the
Access Control:
sequelize#model#associations, RestQL will handle the options.
This document will only talk about the 2nd way. And the option was only support with associations, not with models.
To specify which association should not be accessed by RestQL, add
ignoreoption. Example:
models.user.hasOne( models.privacy, { restql: { ignore: true } } )
To specify an association should not be accessed by specific HTTP method, add the method to
ignoreas an array element. Example:
models.user.hasOne( models.privacy, { restql: { ignore: ['get'] } } )
npm test
MIT