Hapi plugin that automatically generates RESTful API for CRUD
Go to file
Joey Baker 4e078f5ba5 Fix toJSON responses
This is a non-obvious one. Hapi is happy to convert raw sequelize
instances to proper JSON (likely because Sequelize does nice things),
but we do that, we can't use `config.response.schema`, because it
receives the full sequelize instance instead of JSON.

This is a patch release.
2016-09-07 21:06:34 -07:00
scripts Internal: upgrade to babel6 2016-07-05 14:47:44 -07:00
src Fix toJSON responses 2016-09-07 21:06:34 -07:00
.babelrc Internal: upgrade to babel6 2016-07-05 14:47:44 -07:00
.eslintrc Chore: install and configure AVA 2016-09-05 17:10:58 -07:00
.gitignore chore: ignore build directory 2016-01-19 10:07:10 +03:30
circle.yml Test (CI) configure circle 2016-09-05 17:37:50 -07:00
CONTRIBUTING chore(CONTRIBUTING): a contribution guide, git commit messages and code linting 2016-07-22 23:29:54 +04:30
package.json 2.6.0 2016-09-06 11:30:22 -07:00
README.md Docs: add more details for include and where 2016-09-06 07:28:43 -07:00

hapi-sequelize-crud CircleCI

Automatically generate a RESTful API for your models and associations

This plugin depends on hapi-sequelize.

npm install -S hapi-sequelize-crud

##Configure

Please note that you should register hapi-sequelize-crud after defining your associations.

// First, register hapi-sequelize
await register({
  register: require('hapi-sequelize'),
  options: { ... }
});

// Then, define your associations
let db = server.plugins['hapi-sequelize'].db;
let models = db.sequelize.models;
associations(models); // pretend this function defines our associations

// Now, register hapi-sequelize-crud
await register({
  register: require('hapi-sequelize-crud'),
  options: {
    prefix: '/v1',
    name: 'db', // the same name you used for configuring `hapi-sequelize` (options.name)
    defaultConfig: { ... }, // passed as `config` to all routes created

    // You can specify which models must have routes defined for using the
    // `models` property. If you omit this property, all models will have
    // models defined for them. e.g.
    models: ['cat', 'dog'] // only the cat and dog models will have routes created

    // or
    models: [
      // possible methods: list, get, scope, create, destroy, destroyAll, destroyScope, update
      // the cat model only has get and list methods enabled
      {model: 'cat', methods: ['get', 'list']},
      // the dog model has all methods enabled
      {model: 'dog'},
      // the cow model also has all methods enabled
      'cow',
      // the bat model as a custom config for the list method, but uses the default config for create.
      // `config` if provided, overrides the default config
      {model: 'bat', methods: ['list'], config: { ... }},
      {model: 'bat', methods: ['create']}
    ]
  }
});

Methods

  • list: get all rows in a table
  • get: get a single row
  • scope: reference a sequelize scope
  • create: create a new row
  • destroy: delete a row
  • destroyAll: delete all models in the table
  • destroyScope: use a sequelize scope to find rows, then delete them
  • update: update a row

where queries

It's easy to restrict your requests using Sequelize's where query option. Just pass a query parameter.

// returns only teams that have a `city` property of "windsor"
// GET /team?city=windsor

// results in the Sequelize query:
Team.findOne({ where: { city: 'windsor' }})

You can also do more complex queries by setting the value of a key to JSON.

// returns only teams that have a `address.city` property of "windsor"
// GET /team?city={"address": "windsor"}
// or
// GET /team?city[address]=windsor

// results in the Sequelize query:
Team.findOne({ where: { address: { city: 'windsor' }}})

include queries

Getting related models is easy, just use a query parameter include.

// returns all teams with their related City model
// GET /teams?include=City

// results in a Sequelize query:
Team.findAll({include: City})

If you want to get multiple related models, just pass multiple include parameters.

// returns all teams with their related City and Uniform models
// GET /teams?include=City&include=Uniform

// results in a Sequelize query:
Team.findAll({include: [City, Uniform]})

Full list of methods

Let's say you have a many-to-many association like this:

Team.belongsToMany(Role, { through: 'TeamRoles' });
Role.belongsToMany(Team, { through: 'TeamRoles' });

You get these:

# get an array of records
GET /team/{id}/roles
GET /role/{id}/teams
# might also append `where` query parameters to search for
GET /role/{id}/teams?members=5
GET /role/{id}/teams?city=healdsburg

# you might also use scopes
GET /teams/{scope}/roles/{scope}
GET /team/{id}/roles/{scope}
GET /roles/{scope}/teams/{scope}
GET /roles/{id}/teams/{scope}

# get a single record
GET /team/{id}/role/{id}
GET /role/{id}/team/{id}

# create
POST /team/{id}/role
POST /role/{id}/team

# update
PUT /team/{id}/role/{id}
PUT /role/{id}/team/{id}

# delete
DELETE /team/{id}/roles #search and destroy
DELETE /role/{id}/teams?members=5

DELETE /team/{id}/role/{id}
DELETE /role/{id}/team/{id}

# include
# include nested associations (you can specify an array if includes)
GET /team/{id}/role/{id}?include=SomeRoleAssociation

# you also get routes to associate objects with each other
GET /associate/role/{id}/employee/{id} # associates role {id} with employee {id}

# you can specify a prefix to change the URLs like this:
GET /v1/team/{id}/roles