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

rb

v0.2.2

Published

Building nodejs response with ease

Downloads

17

Readme

ResponseBuilder

Build the success and error responses in nodejs application and manage what to be sent to client.

Features

  • Automatically logging all the errors, if found, whether on terminal/file
  • Setting up status code for error and success automatically
  • Automatically detect 404 cases and sent 404 response in those cases.
  • Attaching a unique requestId each time a response a sent. With which client can report some unknown error to the API service provider, referencing that requestId.
  • Sending your custom errorCode of your app, which can help client to see and identify why an error encountered and what is the remedy.
  • Adding extra fields like message, status or any other field while sending response
  • If provided, automatically sends the API version information with each response sent to client. That can have many advantages like handling client side code based on the API version and many others if we think.
  • Every feature can be set/unset as options, that is customizable globally(throught the app), run-time(within a route function/block) or on-fly(at time of calling handler)
  • Reduced, clean and manageable code for your nodejs server.

Install

npm install rb

How to use

Before without RB :

    MongooseModel.find({ _id : some_id }, function(err, docs) {
        if (err) {
            console.error(err);
            res.status(400);
            return res.json({
              error : err
            });
        }

        if (!doc) {
            res.status(404);
            return res.json({
              error : 'Document not found'
            });
        }

        res.json(docs);
    });

After with RB :

    MongooseModel.find({ _id : some_id }, RB.build(res).all);  // where RB = require('rb')

Builder and Handlers

Builder as : RB.build(res) and handler as .all

Builder with only response

var Builder = RB.build(res [,<options>]);

Widely used. As sending response does not require any request parameter. Options are used to provide run time parameters, explained in detail below.

Builder with request as well as response

RB.build(req,res [,<options>])

Sometimes you may want to use generate some fields for response that depends up request properties, in those cases you should provide req,res [,<options>] as per above format

and now the handlers

Handler for all

.all([<error>],[<successResult>],[<extraSuccessData>]);

Widely used. Handles both error and success case callbacks. This in turn calls .error handler or .success handler based on the values found of parameters.

Error handler

.error([<error>],[<onTheFlyStatusCode>],[<onTheFlyErrorCode>])

Sometime you may want to send error back to client without having a callback. If called without any parameter, default error message will be sent with status 400.

Success handler

.success([<successResult>],[<extraSuccessData>])

Sometime you may want to send success object without having a callback. If called without any parameter, default success message will be sent with status 200. If 2nd parameter is a function, then it will be used as returning success callback instead of sending response to client.

Callback handler

.callIfSuccess(<callBackAsParameter>)

In many cases, you only want to handle only success cases to make further callbacks before sending response to client. Calling this with a function (callback) as parameter that is called with the success result after processing. If in case an error found, then this callback will not be called, and error will directly sent to client

Build once and handle at multiple places

function(req,res){
	var Builder = RB.build(req,res[,<runTimeOptions>]);
	//...
	someFunctionCallingWithCallBack(Builder.all);
	//...
	return Builder.error('You deserve 401..!',401); //Forcely sending 401 error in certain case
	//..
	someOtherFunctionCallingWithCallBack(Builder.all);
};

In some cases we want to handle response for many places that deal with same request/response. In such cases we can build the builder once and use throught the that route function.

Best Practice

In a express like application, we can setup a middleware where we can build the responseBuilder and associate it with res. eg.

  // example of setup middleware, (considering express.io being used)
  app.use(function(req,res,next){
    // you can setup any logic to build the builder based on parameter/url/method you find in request.
    // for example, here i am setting extraKey, valid only for GET request otherwise false, that will auto put total no of records fetched in case of GET requests.
    // You can build the builder the way you want, passing other valid options from table below.
    res.RB = RB.build(req,res,{ extraKey : (req.method === 'GET' ? 'total' : false) });
    // or if you want very simple, you can even do like this `res.RB = RB.build(res);` see builder section above.
  });

Now we have response builder as res.RB. Now use res.RB.<anyOfAboveHandlers> wherever you want in your controllers. See handlers above

Options

There are options which configures and handle responses. Every option can either be false or as of corresponding type.

Option | Description | If found unset(false) | Type | Default | ValidOnlyIf --- | --- | --- | --- | --- | --- errorKey | Name of the key with which main error is associated in response. | Response body will only contain the error after preprocessing. | String | 'error' | Error Handler called successKey | Name of the key with which main success result is associated in response. | Response body will only contain the success object after preprocessing. | String | false | Success Handler called extraKey | The key in success response with which contains extra success data. (came with 3rd parmeter in .all or with 2nd parameter in .success). | Extra information will not get associated with response object | String | false | Success handler called getRequestId | This will link every response with unique requestId for future references. This is the function that return the requestId for a request. You just need to setup this function once globaly with setOptions function of RB, and will be called throughout the application whenever a RB being used. req can be found as first parameter if builder having property req | requestId will not be linked | Function | Current TimeStamp in MS | (errorKey OR successKey) AND addRequestIdWhen addRequestIdWhen | addRequestId constraints. 0 : never, 1 : only on success, 2 : only on error, 3 : always | requestId will not be linked | Integer[0-3] | 0 | errorKey or OR successKey addToError | Object which will get merged with the error response object | Nothing additional will be merged | Object | false | errorKey addToSuccess | Object which will get merged with the success response object | Nothing additional will be merged | Object | false | successKey defaultSuccess | In case of falsy value in successResult, this will will be the raw error. | Raw input will be used | String | 'SUCCESS' | successKey defaultError | In case of falsy value in error, this will will be the raw error. | Raw input will be used | String | 'SOME_UNKNOWN_ERROR' | errorKey responseType | RB first try to find if req and its Accept header found. If not so, this one determines what default Content-Type header to be sent. | will not set any Content-Type | String | 'application/json' | Either req not found or its Accept is not amongs xml, html or plain successStatus | Success status sode to be sent | 304 | Integer(100-600) | 200 | Success Handler Called errorStatus | Error status sode to be sent | 304 | Integer(100-600) | 400 | Error Handler Called errorCode | These are the custom/application error code. So that if end user find this error code in response, one may refer some error code ref page and find reason and how to get rid of that error. | No error code will be set | String without space | false | errorKey and Error handler called errorCodeKey | with which key errorCode to be associated in error object | String | 'errorCode' | false | errorCode is set and error handler called noResultStatus | What status code to be sent if none of error and successResult found | 304 | Integer(100-600) | 404 | none of error or successResult found noResultError | What Error message to be sent if none of error and successResult found | if noResultStatus found and noResultError not found, response will be send without body | String | 'RECORD_NOT_FOUND' | noResultStatus successCallback | Builder will build the successObject and then handler will call this function instead of sending to client. Usefull in cases when you want to perform nested database operations before sending final response | Response will be sent to client | Function that get successResult as first parameter | false | success handler called filterProperties | To remove the fields in response that are critical when known to client eg password, some private key etc. | No fields will be removed | String containing space separated keys | false | success handler called preProcessError | If you want to modify/customize error object before sending to client. You get errorObject as first parameter and you should return modified errrorObject in function | Raw error will be sent | Function that returns modified error | MongoDB Unique entry preprocessor. If you are not using mongoDB, rest assured. In 99% cases it wont affect your error. | error handler called preProcessSuccess | same as preProcessError but for success cases. | Raw success data will be sent | Function returning modified success data | false | success handler called attachFile | this gives filename of file that needed to be sent as attachement in the response. | Normal response will be sent | String or Function returning name of file as string | false | success handler called noResponseBody | to send no response body, only status required to be sent | normal response will be sent | Boolean | false | always valid version | you may like to send version information of the api client is using. You just need to set version globaly with setOptions function of RB, and will be saved throughout the application. This field represents the version information. | no version field will be sent | String | false | errorKey or successKey is set versionKey | the key with which version info to be associated | No version info will be send | String | 'version' | version option is set logger | Used to log the error/success responses so as to debug easily in development environment, or customize it so that error/response will be saved in file. (you may integerate winston easily for prod) | no loggin will take place | Function | console.log(requestId, info) | logLevel is set logLevel | in which cases logger should call. // 0 : never, 1 : only on success, 2 : only on error, 3 : always | logger will not be called | integer[0-3] | 2 | always valid headers | additional header to be sent with response. Common headers like *-powered-by to be set once and will be used automatically whenever RB is used. | no additional header will be sent | Object, key value pairs of (headerName : headervalue) | false | always valid

How to set options

Globally

require('rb').setOptions(optionsObject)
// optionsObject may be something like
// {version : '1.4.3', noResultStatus : false, successKey : 'result', addToError: { ok : false }, addToSuccess : { ok : true }, //otherValidOptions }

You can set global options like version ,getRequestId, and everything that are application specific. This should be called after RB is loaded and before the main application starts.

At builder

RB.build(res, optionsObject);
OR
RB.build(req, res, optionsObject); //if req is also used further
// optionsObject may be something like
// {errorCode : 'OUT_OF_SERVICE', attachement : 'file_name', addToError : { message : 'Credentials are not valid.!' } //otherValidOptions }

You can set request/response specific options at build time.

At error handler

Builder.error('some_error', statusCodeOnTheFly, ErrorCodeOnTheFly)

Applicable only for error handler. These will be used when you are calling handler yourself without a handler. You may set the properties like statusCode or ErrorCode.

Roadmap

Raise a feature request by logging an issue, and that will fill this place

Any hurdles?

Found anything difficult to understand? or some bug or some improvement?. Create an issue issue for the same.

License

ResponseBuilder is released under the MIT license:

http://www.opensource.org/licenses/MIT