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

json-status

v0.5.4

Published

A connect-compatible middleware for status responses on JSON HTTP APIs

Downloads

29

Readme

Json-Status

Build
Status Coverage Status NPM version

Json-status is a node.js library that makes JSON status and error messages simpler and more consistent.

Simple example:

If you use the middleware, you'll be able to give consistent json responses for all kinds of different HTTP status code scenarios:

eg This code:

  res.status.notFound("couldn't find that object");

...will respond with a json string like so:

  {
    error : {
      type : 404,
      message : "Not found",
      detail : "couldn't find that object"
    }
  }

##Installation

npm install json-status --save

##Setup as connect middleware

  var JsonStatus = require('json-status');
  var connect = require('connect');
  var server = connect.createServer();
  var statusMiddleware = JsonStatus.connectMiddleware({ 
    onError : function(data){
      console.log("error: ", data.type, data.message, data.detail);
    }
  });
  server.use(statusMiddleware);
  server.use(function(req, res){
    res.status.internalServerError("fake error!");  // this will respond with a 500
  });

##No frills setup

  var JsonStatus = require('json-status');
  var http = require('http');
  http.createServer(function (req, res) {
    new JsonStatus(req, res).internalServerError("fake error too!");
  }).listen(1337, '127.0.0.1');

General Usage

To understand what the HTTP status codes mean, please refer to http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.

JsonStatus.connectMiddleware(options)

This method takes an options object and returns a connect-compatible middleware, ready to be use()ed in a connect/express application.

Example:

  var statusMiddleware = JsonStatus.connectMiddleware({ 
    namespace : "status"
    quiet500 : true
    onError : function(data){
      console.log("error: ", data.type, data.message, data.detail);
    }
  });
  server.use(statusMiddleware);

The options object is actually optional, as are all its properties. You can modify how the middleware behaves through these properties though:

namespace (string) : dictate the name that will be used to add json-status to a response object.

eg, if you do this:

  var statusMiddleware = JsonStatus.connectMiddleware({ 
    namespace : "blah"
  });

The json-status object will be usable in a request handler like this:

  res.blah.internalServerError("something bad happened");

The default value is "status".

quiet500 (boolean): turn on 'quiet500' mode, meaning that the details of a 500 error will be suppressed.

eg, for this code:

  res.status.internalServerError("something bad happened");

The response will be this if quiet500 is true:

  {
    error : {
      type : 500,
      message : "Internal Server Error"
    }
  }

The response will be this if quiet500 is unset or false:

  {
    error : {
      type : 500,
      message : "Internal Server Error",
      detail : "something bad happened"
    }
  }

The quiet500 mode is nice on production systems where you don't necessarily want your users to know exactly what went wrong on an internal server error, but you still want to provide the details for logging purposes.

onError (function): pass a callback that takes an error object as its only parameter in order to have that callback called on every 4xx or 5xx status code. The error object will have req, res, type, message, and detail parameters on it. This is really useful for logging and/or metrics.

Methods

These methods generally set the HTTP status and end the response, so in general you should not expect to write more to the response after these. If a response body makes sense, it will generally be written automatically. For clarity, it's recommended that when you call one of these functions, you call it with return in front of it. Here's an example:

server.route('/', {  GET : function(req, res){
                              return res.status.redirect('/someOtherUrl');
                            }});

Here are the functions that it makes available in your method handler:

###Redirect scenarios ####res.status.created(redirectUrl, [responseJsonObject]); This method is used for HTTP STATUS 201 scenarios when the server has just created a resource successfully so that the server can tell the client where to find it. It sets the status to 201 and sets the 'Location' header to the redirectUrl. An optional second parameter can additionally be sent to be stringified as the response body.

####res.status.movedPermanently(redirectUrl); This method is used for HTTP STATUS 301 scenarios where a resource has been permanently moved somewhere else so the server can tell the client where to find it. It sets the status to 301 and sets the 'Location' header to the redirectUrl.

####res.status.redirect(redirectUrl); This is just an alias of movedPermanently()

###Success responses

"200 OK" statuses are the default, so you don't need to specify those explicitly.

201 Created statuses are described in the redirect section above.

####res.status.accepted();

Used to indicate that a response has been accepted, but not yet processed, this response will emit a "202 Accepted" status.

####res.status.noContent(); Used to indicate that a request was successful, but there's no body to return (for example, a successful DELETE). This response will emit a "204 No Content" status.

####res.status.resetContent();

Used to indicate that a request was sucessful so a related UI (usually a form) should clear its content. This response will emit a "205 Reset Content" status.

###Error Scenarios All of the error scenarios are handled similarly and attempt to show a response body that indicates the error that occurred as well. The status code will be set on the response as well as in that response body.

All of these methods additionally take a single parameter where additional detail information can be added. For example:

server.route('/', {  GET : function(req, res){
                              return res.status.internalServerError('The server is on fire.');
                            }});

Output:

{"type":500,"message":"Internal Server Error","detail":"The server is on fire"}

###Error response methods:

####res.status.badRequest([detail])

{"type":400,"message":"Bad Request"}

####res.status.unauthenticated([detail])

{"type":401,"message":"Unauthenticated"}

####res.status.forbidden([detail])

{"type":403,"message":"Forbidden"}

####res.status.notFound([detail])

{"type":404,"message":"Not Found"}

####res.status.methodNotAllowed([detail])

{"type":405,"message":"Method Not Allowed"}

####res.status.notAcceptable([detail])

{"type":406,"message":"Not Acceptable"}

####res.status.conflict([detail])

{"type":409,"message":"Conflict"}

####res.status.gone([detail])

{"type":410,"message":"Gone"}

####res.status.lengthRequired([detail])

{"type":411,"message":"Length Required"}

####res.status.preconditionFailed([detail])

{"type":412,"message":"Precondition Failed"}

####res.status.requestEntityTooLarge([detail])

{"type":413,"message":"'Request Entity Too Large"}

####res.status.requestUriTooLong([detail])

{"type":414,"message":"Request URI Too Long"}

####res.status.unsupportedMediaType([detail])

{"type":415,"message":"Unsupported Media Type"}

####res.status.unprocessableEntity([detail])

{"type":422,"message":"'Unprocessable Entity"}

####res.status.tooManyRequests([detail])

{"type":429,"message":"Too Many Requests"}

####res.status.internalServerError([detail])

{"type":500,"message":"Internal Server Error"}

####res.status.notImplemented([detail])

{"type":501,"message":"Not Implemented"}

####res.status.badGateway([detail])

{"type":502,"message":"Bad Gateway"}

####res.status.serviceUnavailable([detail])

{"type":503,"message":"Service Unavailable"}

####res.status.gatewayTimeout([detail])

{"type":504,"message":"Gateway Timeout"}