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

totoro-node

v2.0.5

Published

Route Management for API Versioning

Downloads

365

Readme

totoro-node

Totoro is a Node.js module to help simplify route management and reduce code duplication for multiple API versions. Totoro will keep you dry!

This module allows you to easily define multiple API versions which can inherit endpoints from previous versions or override the functionality of an endpoint in a subsequent version of the API.

Totoro uses express to create a router with all the routes you define in the API version definition. It returns a router with routes to each of your defined endpoints that can be easily modified, deprecated or disabled as your API changes and grows over time.


Installation

npm install totoro-node

or add a dependency to your package.json

"totoro-node": "<version>"

Usage

The following syntax can be used:

app.use(path, totoro.rain(configuration, loggerInstance, clearConsole));

Where,

  • path is the base path for the router returned by totoro.rain().
  • configuration is the router configuration, as described below.
  • loggerInstance is a custom logger instance.
  • clearConsole boolean; if true, console will be cleared whenever rain() is called. Defaults to false.

Example

var express = require('express');
var app = express();

var totoro = require('totoro-node');

app.use('/api', totoro.rain({
    v1: { // this is an API version definition
        active: true, // this parameter are optional but the default value is true when not specified
        deprecated: false, // this parameter are optional but the default value is false when not specified
        endpoints: [
            {
                route: "/test/endpoint",
                method: "GET",
	        middleware: [myMiddlewareFunctionOne, myMiddlewareFunctionTwo],
                active: true, // this parameter are optional but the default value is true when not specified
                deprecated: false, // this parameter are optional but the default value is false when not specified
                implementation: originalImplementationFunction
            },
            {
                route: "/another/test/endpoint",
                method: "POST",
                implementation: anotherImplementationFunction
            }
        ]
    },
    v2: {
        endpoints: [
            {
                route: "/test/endpoint",
                method: "GET",
                implementation: overridingOriginalImplementationFunction
            }
        ]
    }
}));

This returns a router with the following routes:

/api/v1/test/endpoint
/api/v1/another/test/endpoint
/api/v2/test/endpoint - overrides original implementation from version v1
/api/v2/another/test/endpoint

All the previous endpoints in version v1 are carried over to version v2 but any endpoints that are redefined in v2 will override the original endpoint with the new v2 implementation. This type of inheritance and overriding can be controlled using the active and deprecated fields in the API versioning definition above.


Logging

Logging is performed internally using Winston by logging debug messages. Logging can be enabled by passing a reference to the Winston logger when calling the rain function.
Note: Any other logger object that supports logger.log({<level>, <message>}) interface can be passed to loggerInstance.

totoro.rain({<configuration>}, loggerInstance)

Configuration

The configuration map used in the rain function contains a few fields:

  • active (optional)

    • This indicates whether or not the endpoint should be added to the current version of your API. If this field is set to false for an entire API version then that version will no longer be accessible but subsequent versions of the API will still inherit all the endpoints of this disabled version. This allows you to easily bump the version of an entire API while updating the implementation of specific endpoints in the next version. If this field is set to false for a specific endpoint definition then only that endpoint is excluded from the version. But, as before the endpoint is still inherited by later versions of the API meaning you can provide an updated implementation if you no longer want the old version to be used. By default this is set to true.
  • deprecated (optional)

    • This field allows you to disable the inheritance of an entire API or a specific set of endpoints in later versions of your API. By setting this to true, the endpoint or API version will no longer be accessible in subsequent versions of the API but will still be included in the current version. This is most to support legacy applications that may not have upgraded to your latest API version. By default this is set to false.
  • method (required)

    • This can only be defined in the endpoint definition, not the API version definition! It specifies the HTTP method used for that endpoint.
  • middleware (optional)

    • This fields attaches middleware implementation to a specified endpoint.
  • endpoints (required)

    • This is the list of endpoints for the API version definition. Each of the endpoints that you define will create a corresponding route in the router.
  • implementation (required)

    • This points to a function which will be invoked when the endpoint is called. The function must accept three parameters; apiVersion, req, res, next e.g. function(apiVersion, req, res, next) { <endpoint implementation> } This is based on the express functions get, post, delete and put each of which require req, res and next parameters.
      • apiVersion
        • This is the API version of the endpoint being called. In the above example, it would be v1 and v2 respectively. This can be used in your endpoint implementation function to decide which version of the endpoint is being called. If you choose to reuse the same implementation function across multiple versions but want to make a minor change for one specific version of the endpoint then this will help avoid the need to create another implementation function.
      • req
        • This is the express router parameter which holds all the request data when the endpoint is called.
      • res
        • This is the express router parameter used to send a response when the endpoint is called.
      • next
        • This is the express router parameter used to pass control to the next handler when the endpoint is called.

Contact

If you have any suggestions or encounter any problems using this module then feel free to open an issue on GitHub.
Contributions are welcome.
Thank you for reading :)