npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

hapi-sequelize-crud3

v2.7.6

Published

Hapi plugin that automatically generates a RESTful API for CRUD, building on hapi-sequelize-crud

Downloads

6

Readme

hapi-sequelize-crud2

Automatically generate a RESTful API for your models and associations, with simple route configuration and behavior extensibility.

This plugin depends on hapi-sequelize, and builds on the work of hapi-sequelize-crud.

npm install -S hapi-sequelize-crud2

##Configure

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

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

// Now, register hapi-sequelize-crud2
await server.register({
  register: require('hapi-sequelize-crud2'),
  options: {
    prefix: '', // Global prefix for all routes
    scopePrefix: 's', // Prefix for model scope routes (see below)
    snakeCase: false, // Create routes with snake_case instead of default camelCase
    controllers: 'controllers/**/*.js', // Glob to handler controller override files (can be array) [see below]
    private: [] // Array of model names to exclude from route creation
  }
});

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

##What do I get

Let's say you have associations like this:

Team.belongsToMany(Role, { through: 'teamRoles' });
Team.hasOne(Player, { as: 'captain' });

You get these CRUD routes:

| Method | Route | Name | |---|---|---| | GET | /teams | index1 2 3 | | GET | /teams/{id} | get3 | | POST | /teams | create | | PUT | /teams/{id} | update | | DELETE | /teams/{id} | destroy | | GET | /teams/s/{scope} | scope1 2 3 | | GET | /teams/count | count1 |

And these one-to-one association routes:

| Method | Route | Name | Description | |---|---|---|---| | GET | /teams/{id}/captain | index3 | Retrieve the related model | | POST | /teams/{id}/captain | create | Create a new related model and sets the association | | PUT | /teams/{id}/captain/{aid} | update | Sets the association with an existing related model | | DELETE | /teams/{id}/captain | destroy | Unsets the association |

And these one-to-many association routes:

| Method | Route | Name | Description | |---|---|---|---| | GET | /teams/{id}/roles | index1 2 3 | Retrieve the related models | | POST | /teams/{id}/roles | create | Create a new related model and adds it to the associations | | PUT | /teams/{id}/roles/{aid} | update | Sets the association with an existing related model | | PUT | /teams/{id}/roles | updateMany | Sets the association with a many related models, as provided by id[] querystring parameter | | DELETE | /teams/{id}/roles/{aid} | destroy | Unsets the association | | DELETE | /teams/{id}/roles | destroyMany | Unsets all associations, optionally limited to those given by id[] querystring parameter | | GET | /teams/{id}/roles/count | count1 | Counts the number of associated models |

1 Accepts a query string parameter object filter to limit results by given criteria, e.g. ?filter[status]=active

2 Accepts query string parameters limit and offset to control paginated results

3 Accepts a querystring parameter include to include a related model with the returned parent model

##Custom Route Configuration Automatic route handling is convenient for getting a basic API in place during development. But in a production application, authentication, ACL and caching concerns need to be addressed. Taking advantage of Hapi's convention over configuration approach to route set-up, you can easy extend and override the plugin's default route options and handler.

Simply create a file named modelName.js (or model_name.js if you prefer) in your controllers path defined in the plugin options, and your options will be mixed in during route registration. A controller should export a function that accepts two arguments, a Hapi server instance and the model object, and returns an object mapping route names to Hapi route configuration object partials or false to disable a route.

Include a default configuration to apply to all routes in a controller by setting the * key. Apply only to all association routes by setting associations.*. To set a default controller, include a _default.js file in your controllers file path.

For example, a read-only endpoint with limited scope access may look like:

// This standard Hapi package make composing 
// route configuration options easy
const Hoek = require('hoek');
const Joi = require('joi');

modules.export = function(server, Team) {
  const plural = Team.options.name.plural;
  
  return {
    '*': {
      cache: {
        expiresIn: 30 * 1000,
        private: 'private'
      }
    },
    
    scope: {
      config: {
        validation: {
          params: {
            scope: Joi.string().valid('scope1', 'scope2')
          }
        }
      }
    },
    
    count: {
      path: `${plural}/total`,
      handler: function(request, reply) {
        ...
        const total = ...;
        
        reply({total: total}); 
      }
    },
        
    create: false,
    update: false,
    destroy: false,
    
    associations: {
      captain: {
        create: false,
        update: false,
        destroy: false
      },
      
      roles: false
    }
  };
});

Provide Already Retrieved Model

Have you already queried for and retrieved the model instance (or parent instance for association routes) earlier in your pre-handler cycle? You can provide this to the plugin by assigning the request.pre.model key to your request object and it will not execute the find query.

Dynamic Scope Limiting

Need to assign a scope based on ACL or other pre-handler results? Assign the request.pre.scope key to your request object and it will apply the supplied pre-defined model scopes to the find queries.