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

dispatch-model

v1.1.28

Published

Simple express js response custom method for dispatch query to a web api, easy, clean, fast and beautiful code

Downloads

31

Readme

NPM

Dispatch Model

Is a simple custom response express method develop by me , member of HACKDO FOUNDATION.

To dispatch query to a web api, easy, clean, fast and beautiful code, it works great with waterline mongodb driver, localDisk and sailsjs but must be tested with mysql driver for nodejs:

If you find this module helpful please donate here with the mount of you want, it helps to maintain the project and enhands all.

Instalation

npm install dispatch-model --save

or

git clone https://github.com/Maxtermax/dispatch-model.git

Setup with sails js

Follow this steps:

  1. Inside the directory responses add a new response file:
 //api/responses/dispatchModel.js
 module.exports = require('dispatch-model');

note: dispatchModel.js is just a generic name you can call this response file whereaver you want.

  1. Add a model with some schema for example:
  //api/models/User.js
  module.exports = {
   attributes: {
    firstName: 'string',
    lastName: 'string'
  }
 }

Setup with express js

Follow this steps:

  1. In you express app configuration add
const dispatchModel = require('dispatch-model');
app.use("*",(req, res, next)=> {
  res.dispatchModel = dispatchModel;
  next();
});

Now let the magic begin inside some controller now can dispatch the User model like that:

module.exports = {
  serve: function(req, res) {
    let query = User.create({firstName: "john", lastName: "doe"});
    res.dispatchModel(query);
  }//end serve method
}//end UserController

the dispatchModel is now aviable for use, this take some arguments for dispatch some query, the first one is a Promise that is usually a query from the database that return a result, with this code you would get:

{
  "data": {
    "firstName": "john",
    "lastName": "doe",
    "createdAt": "2017-03-10T02:51:15.184Z",
    "updatedAt": "2017-03-10T02:51:15.184Z",
    "id": 34
  },
  "status": 200
}

Dispatch model, wrap an transform the data for you in this schema: firt all response that get success in his query must return and json object with data as main attribute that represent the result of query in the database, and status that represent the status of response from the web API.

Response cases

Dispatch model, must take as first argument some Promise that return some kind a information, and can also get a second argument which is is usable to transform the response.

As second argument responseCases can transform the data depend on manies escenarios like:

  • success
    • notFound
  • errors
    • notFound
    • notAllow
    • forbidden
    • badRequest
    • conflict
    • serverError

Exmaple:

module.exports = {
  // UserController.js
  serve: function(req, res) {
    let responseCases = {
      success: {
        omit: ['lastName'],
        status: 201 //change status to created
      }
    }
    let query = User.create({firstName: "john", lastName: "doe"});
    res.dispatchModel(query, responseCases);
  }//end serve method
}//end UserController

In case of success indicate that will return something like:

{
  "data": {
    "firstName": "john",
    "createdAt": "2017-03-10T03:32:05.771Z",
    "updatedAt": "2017-03-10T03:32:05.771Z",
    "id": 36
  },
  "status": 201
}

The success option can get few attibutes like:

Attribute | Required | Type -------- | ----- | ---- omit | false | array pick | false | array authentication | false | boolean session | false | json status | false | integer map | false | Function beforeResponse | false | Function afterResponse | false | Function view | false | string

Success

  • omit: list of attributes that you wanna omit of the query response
  showAll: function(req, res) {
    let responseCases = {
      success: {
        omit: ['firstName']
      }
    }
    let query = User.find({});
    res.dispatchModel(query, responseCases);
  },//end showAll

return :

{
  "data": [
    {
      "lastName": "doe",
      "createdAt": "2017-03-10T04:20:21.710Z",
      "updatedAt": "2017-03-10T04:20:21.710Z",
      "id": 38
    }
  ],
  "status": 200
}
  • pick: list of attributes that you wanna pick of the query response
module.exports = {
  serve: function(req, res) {
    let responseCases = {
      success: {
       pick: ['firstName']
     }
   }

   let query = User.find({});
   res.dispatchModel(query, responseCases);
  }//end serve
}

return :

{
  "data": [
    {
    "firstName": "john"
    }
  ],
  "status": 200
}
  • authentication: boolean attributes that indicate that yout wanna save some
  • session: object that represent information that you wanna store in the session, for example:
module.exports = {
  createAndAuth: function(req, res) {
    let responseCases = {
      success: {
        authentication: true,
        session: {
          firstName: true
        }
      }
    }

    let query = User.create({firstName: "john", lastName: "doe"});
    res.dispatchModel(query, responseCases);
  }//end createAndAuth
}

this code will create a user and save a session with the firstName and now is avaible in req.session.firstName

Note: When wanna use session you must use authentication set in true

  • status Status is usable for indicate the status code of the response in the web api, this que use in all cases.
module.exports = {
  serve: function(req, res) {
    let responseCases = {
      success: {
       status: 202 //change the default status code to 203 Accepted
     }
   }

   let query = User.find({});
   res.dispatchModel(query, responseCases);
  }//end serve
}

return:

{
  "data": [
    {
      "firstName": "john"
    }
  ],
  "status": 202
}
  • map This option can be used for map the response of the query to the database, example:
module.exports = {
  showAll: function(req, res) {
    let responseCases = {
      success: {
        map: function(data, next) {
          data.fullName = data.firstName+" "+data.lastName;
          return data;
        }
      }
    }
    let query = User.find({});
    res.dispatchModel(query, responseCases);
  }//end showAll
}

return:

{
  "data": [
    {
      "firstName": "john",
      "lastName": "doe",
      "fullName": "john doe"
    }
  ],
  "status": 200
}
  • beforeResponse This method can be used for do something before response, this is called when the query to the database is done, examples:
module.exports = {
  showAll: function(req, res) {
    let responseCases = {
      success: {
        beforeResponse: function(partialData, next) {
          let owner = partialData.data.id;
          Pets.find({owner}).then(function(pet) {
            //do some with you pet
            next();
          })
          .catch((error)=>{
            if(error.message === "customError") return next(new Error("customError"));
            next(new Error("serverError"));
          })
        }
       },
       errors: {
        otherwise: {
          customError: {
            details: "my custom error detail",
            status: 400
          }
        }
      }
    }
    let query = User.find({});
    res.dispatchModel(query, responseCases);
  }//end showAll
}

Note: You must call next method to continue the process otherwise it never response, in case that something go wrong you can throw and error that will be catched by the error cases, if you are using mongoose.js you migth need to use toObject or toJSON in beforeResponse or map

In case of success return:

{
  "data": [
    {
      "firstName": "john",
      "lastName": "doe"
    }
  ],
  "status": 200
}

In case of customError return:

{
  "data": null,
  "details": "my custom error detail",
  "status":  400
}

In case of serverError return:

{
  "data": null,
  "details": "Internal server error.",
  "status":  500
}
  • afterResponse This method can be used for do something after response, this is called when the response is done, examples:
module.exports = {
  showAll: function(req, res) {
    let responseCases = {
      success: {
        afterResponse: function(data) {
          console.log("data response was: ", data);
        }
      }
    }
    let query = User.find({});
    res.dispatchModel(query, responseCases);
  }//end showAll
}
  • view Asuming that you has set some templete engine like handlebar now you can response by render a view, example:
module.exports = {
  showAll: function(req, res) {
    let responseCases = {
      success: {
       view: "path/to/template"
     }
   }
   let query = User.find({});
   res.dispatchModel(query, responseCases);
  }//end showAll
}

Note: the view option can be used in all cases, and must be equal to the path of you template, this change depend of the template engine

Errors

The errors option can get a few arguments like: Attribute | Required | Type -------- | ----- | ---- notFound | false | json notAllow | false | json forbidden | false | json badRequest | false | json conflict | false | json serverError | false | json otherwise | false | json

Note: To trigger any of this errors responses, the Promise argument must throw or reject an error with a message called the same way that the error.

The otherwise is special and represent a generic error that is not contemplated in the default errors responses list of dispatchModel , this mean that you que used like a kind a custom response error.

All of them take as schema to response this:

Attribute | Required | Type -------- | ----- | ---- details | false | string status | false | integer generic attribute | false | json

All the errors cases return the same schema, unless that you use a generic attribute to add something, example:

  showAll: function(req, res) {
    let responseCases = {
      errors: {
        notFound: {
          details: "my custom message for notFound",
          myGenerictData: "Hola mundo"
        },
        otherwise: {
          myCustomError: {
            details: "my custom message",
            status: 304
          }
        }
      }
    }
    let query = User.beHappy({});
    res.dispatchModel(query, responseCases);
  }//end showAll

In case of notFound return:

{
  "data": null
  "details": "my custom message for notFound"
  "status": 404,
  "myGenerictData": "Hola mundo"
}

Note: the notFound can be use inside of success too.

In case of myCustomError return:

{
  "data": null
  "details": "my custom message"
  "status":  304
}

Note: in case that dispatchModel get a unexpected error, that was not set in any where, it will response with a 204 No content

If you find this module helpful please donate here with the mount of you want, it helps to maintain the project and enhands all.

So this is all for now, be in touch if you have some issue or want to contribute to this project.