• Stars
    star
    447
  • Rank 97,615 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 8 years ago
  • Updated almost 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Build real RESTful APIs without writing one line of code.

koa-restql

Travis branch NPM version

Build real RESTful APIs without writing one line of code. Cool, right?

Now it works perfectly with MySQL.

[toc]

Installation

koa-restql requires node v6.0.0 or higher for (partial) ES2015 support.

npm install --save koa-restql

Usage

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())

How to request real RESTful APIs

Basic

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 querystring in your url can add condition or limit for the request. For more details, read about querystring.

List

  • 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:

    • Request for a list will always respond an array.
    • This response example include necessary HTTP headers to explain how Partial Content works. If the response was just part of the list, the API would like to response HTTP status code 206.

Single

  • Request

    GET /user/1
    
  • Response

    {
      "id": 1,
      "name": "Li Xin"
    }
    

    Note: Request path with id will always respond an object.

Association

1:1

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 profile was an association defined with belongTo(), there should not be user_id field.

1:N

To define an 1:N association with sequelize, use model.belongsTo().

List
  • Request

    GET /user/1/messages
    
  • Response

    [
      {
        "id": 1,
        "content": "hello"
      },
      {
        "id": 2,
        "content": "world"
      }
    ]
    
Single
  • Request

    GET /user/1/messages/2
    
  • Response

    {
      "id": 2,
      "content": "world"
    }
    

N:M

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 through option.

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 querystring like this:

GET /user?_include%5B0%5D=friends

Read more.

CRUD

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
  • List path examples:
    • /resource
    • /resource/:id/association, association is 1:n relationship
    • /resource/:id/association, association is n:m relationship
  • Single path examples:
    • /resource/:id
    • /resource/:id/association, association is 1:1 relationship
    • /resource/:id/association/:id, association is 1:n relationship
    • /resource/:id/association/:id, association is n:m relationship

Note: PUT method must be used with unique key(s), which means you can not use PUT method with a request body without an unique key.

To use POST or PUT method, you should put data into request body. Example:

POST /user

{
  "name": "Li Xin"
}

querystring

It's strongly recommended that use qs to stringify nesting querystrings. And this document will assume you will use qs to 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 where option 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
    }
  • include option for sequelize#query() should be passed as String of association name.

    // query
    {
      _include: ['friends']
    }
    // option for sequelize
    {
      include: [
        models.user.association.friends
      ]
    }

Sometimes, you want modify query in your own middleware. To do so, you should modify this.restql.query instead of this.request.query or this.query, because the query MUST be parsed with the package qs, not querystring (which is default package of koa).

Access Control

There are at least 2 ways to implement the Access Control:

  1. Add another middleware before request be handled by RestQL.
  2. Add options on 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.

  1. To specify which association should not be accessed by RestQL, add ignore option. Example:

    models.user.hasOne(
      models.privacy,
      {
        restql: {
          ignore: true
        }
      }
    )
  2. To specify an association should not be accessed by specific HTTP method, add the method to ignore as an array element. Example:

    models.user.hasOne(
      models.privacy,
      {
        restql: {
          ignore: ['get']
        }
      }
    )

Running tests

npm test

License

MIT

More Repositories

1

mpvue

基于 Vue.js 的小程序开发框架,从底层支持 Vue.js 语法和构建工具体系。
JavaScript
20,419
star
2

walle

Android Signature V2 Scheme签名下的新一代渠道包打包神器
Java
6,770
star
3

Leaf

Distributed ID Generate Service
Java
6,438
star
4

Logan

Logan is a lightweight case logging system based on mobile platform.
C
5,709
star
5

SQLAdvisor

输入SQL,输出索引优化建议
C
5,551
star
6

Robust

Robust is an Android HotFix solution with high compatibility and high stability. Robust can fix bugs immediately without a reboot.
Java
4,420
star
7

Zebra

美团点评集团统一使用的MySQL数据库访问层的中间件。主要提供对业务开发透明、读写分库、分库分表能力,并提供了端到端SQL监控的集成方案。
Java
2,746
star
8

DBProxy

C
2,226
star
9

beeshell

React Native 组件库
TypeScript
1,797
star
10

lyrebird

移动应用插件化测试工作台
Python
1,163
star
11

MyFlash

flashback mysql data to any point
C
1,102
star
12

Shield

A declarative, efficient, and flexible Native framework for building user interfaces.
Java
940
star
13

octo-rpc

OCTO-RPC 是支持Java和C++的企业级通信框架,在RPC服务之上扩展了丰富的服务治理功能,为美团各业务线提供高效、统一的通信服务。
Java
644
star
14

octo-ns

OCTO-NS是美团OCTO服务治理体系服务注册发现功能的套件, 包括SDK(Java/C++)、本地服务治理代理(SgAgent), 服务缓存(NSC), 云端健康检查(Scanner)等基础组件,目前已经在全公司大规模使用
C++
327
star
15

asap

ASAP: A Chinese Review Dataset Towards Aspect Category Sentiment Analysis and Rating Prediction
311
star
16

vision-ui

视觉UI分析工具
Python
251
star
17

octo-portal

OCTO-Portal 是OCTO服务治理体系的管理端,为服务权重修改,性能数据分析等服务治理功能提供人性化的一站式管理平台
JavaScript
173
star
18

lyrebird-android

本程序是一个Lyrebird的插件,用于支持获取Android设备信息。
Python
125
star
19

vision-ml

A R-CNN machine learning model for handling Pop-up window in mobile Apps.
Python
71
star
20

lyrebird-ios

本程序是Lyrebird插件,您可以在插件中快速查看已连接iOS设备的详细设备信息,截取屏幕快照,以及查看已连接设备的应用信息。
Python
71
star
21

cat-go

Go
50
star
22

lyrebird-tracking

Tracking 是基于Lyrebird的插件,提供服务请求的数据分析及验证的功能
Python
25
star
23

lyrebird-api-coverage

API-Coverage是基于Lyrebird的插件,为客户端提供API维度测试覆盖评估方法。
Python
23
star
24

mos-mss

mtyun MSS(Meituan Storage Service) sdk for Node.js
JavaScript
19
star
25

lyrebird-java-client

lyrebird-java-client 是Lyrebird的一个 Java SDK,通过调用Lyrebird本身提供的API实现在Java项目中控制 Lyrebird Services
Java
15
star
26

lyrebird-bugit

lyrebird-bugit是Lyrebird的一个插件,目前应用于提交Bug场景
Vue
14
star
27

cat-python

Python
6
star
28

cat-node-js

CMake
5
star
29

cat-c-client

C
1
star
30

groupmeal-java-sdk

Java
1
star