Code Monkey home page Code Monkey logo

express-version-route's Introduction

express-version-route

view on npm view on npm Build Codecov npm module downloads Known Vulnerabilities Security Responsible Disclosure

express-version-route

This npm package provides an Express middleware to load route controllers based on api versions.

Implementing API Versioning as simple as:

now any request would be handled with the appropriate route handler in accordance to request.version.

Usage

Create a map where the key is the version of the supported controller, and the value is a regular Express route function signature.

const versionRouter = require('express-version-route')

const routesMap = new Map()
routesMap.set('1.0', (req, res, next) => {
  return res.status(200).json({'message': 'hello to you version 1.0'})
})

Then, on the route which you wish to version, call the route function of this module with the map you created:

router.get('/test', versionRouter.route(routesMap))

If no route matches the version requested by a client then the next middleware in the chain will be called. To set a route fallback incase no version matches set a 'default' key on the routes map, for example:

routesMap.set('default', (req, res, next) => {
  return res.status(200).json({'message': 'hello to you, this is the default route'})
})

If maximal possible version (for example to get the latest bugfix) is necessary, then please specify useMaxVersion: true in route function, then the maximal possible version will be returned for your request. For example for 1.0 request, the version 1.0.2 will be returned:

const routesMap = new Map()
routesMap.set('1.0.0', (req, res, next) => {
  return res.status(200).json({'message': 'hello to you version 1.0.0'})
})
routesMap.set('1.0.2', (req, res, next) => {
  return res.status(200).json({'message': 'hello to you version 1.0.2'})
})

router.get('/test', versionRouter.route(routesMap,{useMaxVersion: true}))

Usage with TypeScript

import * as versionRouter from 'express-version-route'
import { Router, Handler } from 'express';

const router = Router();
const routesMap = new Map<string, Handler>();

routesMap.set('1.0', (req, res, next) => {
  return res.status(200).json({'message': 'hello to you version 1.0'})
})

routesMap.set('default', (req, res, next) => {
  return res.status(200).json({'message': 'hello to you, this is the default route'})
})

router.get('/test', versionRouter.route(routesMap))

How it works

The Library

A requested version from the client must be available on the request object at req.version. You are encouraged to use this module's twin: express-version-request which is another simple Express middleware that populates req.version from the client's X-Api-Version header, Accept header or from a query string (such as 'api-version=1.0.0')

The key for the routes versions you define can be a non-semver format, for example: 1.0 or just 1. Under the hood, expression-version-route uses the semver module to check if the version found on the request object at req.version matches the route.

Client-Server flow

  1. An API client will send a request to your API endpoint with an HTTP header that specifies the requested version of the API to use:
curl --header "X-Api-Version: 1.0.0" https://www.example.com/api/users
  1. The express-version-request library will parse the X-Api-Version and sets Express's req.version property to 1.0.0.
  2. The express-version-route library, when implemented like the usage example above will match the 1.0 route version because semver will match 1.0.0 to 1.0, and then reply with the JSON payload {'message': 'hello to you version 1.0'}.

Installation

yarn add express-version-route

TypeScript Support

yarn add --dev @types/express-version-route

Note: Don't forget to add types for Express as well!

Tests

yarn test

Project linting:

yarn lint

Coverage

yarn test:coverage

Commit

The project uses the commitizen tool for standardizing changelog style commit messages so you should follow it as so:

git add .           # add files to staging
yarn commit      # use the wizard for the commit message

On API Versioning...

An API versioning is a practice that enables services to evolve their APIs with new changes, signatures and the overall API contract without interrupting API consumers and forcing them to repeatedly make changes in order to keep in pace with changes to APIs.

Several methodologies exist to version your API:

  • URL: A request specifies the version for the resource: http://api.domain.com/api/v1/schools/3/students
  • Query String: A request specifies the resource in a query string: http://api.domain.com/api/schools/3/students?api-version=1
  • Custom HTTP Header: A request to a resource http://api.domain.com/api/schools/3/students with a custom HTTP header set in the request X-Api-Version: 1
  • MIME Type content negotiation: A request to a resource http://api.domain.com/api/schools/3/students with an Accept header that specifies the requested content and its version: Accept: application/vnd.ecma.app-v2+json

There is no strict rule on which methodology to follow and each has their own pros and cons. The RESTful approach is the semantic mime-type content negotiation, but a more pragmatic solution is the URL or custom HTTP header.

Why API Versioning at all ?

Upgrading APIs with some breaking change would lead to breaking existing products, services or even your own frontend web application which is dependent on your API contract. By implementing API versioning you can ensure that changes you make to your underlying API endpoints are not affecting systems that consume them, and using a new version of an API is an opt-in on the consumer. read more...

Alternative Node.js libraries

Several npm projects exist which provide similar API versioning capabilities to Express projects, and I have even contributed Pull Requests to some of them that provide fixes or extra functionality but unfortunately they all seem to be unmaintained, or buggy.

Author

Liran Tal [email protected]

express-version-route's People

Contributors

captaincaius avatar drfaust92 avatar greenkeeper[bot] avatar liranbri avatar lirantal avatar mprambadi avatar mystetskyivlad avatar snyk-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

express-version-route's Issues

Project's package.json is missing repository information

Problem

The project doesn't have a repository key in its package.json and so on npmjs.org project page there's no link back to this repository.

How to fix

Add the following:

  "repository": {
    "type": "git",
    "url": "git+https://github.com/lirantal/express-version-route.git"
  }

and

"homepage": "https://github.com/lirantal/express-version-route#readme",

Connect to Travis CI

Connect to a build system by creating the travis yaml file to run project's test and linting

Update badges for project

Remove david-dm project badge as that's a bit old and we have already both greenkeeper integrated and Snyk to watch the deps vulnerabilities

Add Project Badges

  1. Add the Travis CI build status badge
  2. Connect to codecov for coverage reporting and add the badge on README

How to manage multiple middleware function

Most of my routes has more then one function in serving a request, Map is not allowing to add more then two params.
Sample:
route.post(
'/customer',
middlewares.isAuth,
middlewares.hasAccess('customer', 'create'),
async (req, res, next) => {
// will add service function to add customer.
return APIResponse.success(res, { message : 'success '});
},
);

Add support for error objects

In order to use custom error objects instead of relying on their actual name strings we can create an errors/ directory with the errors on it. Internally in the program we can simply consumer that just like any other import and for external access projects can just require it as well like:

const { CustomError } = require('express-version-route/errors/')

where errors/ folder will have an index.js that will export all error classes

cc @captaincaius

feature request: unsatisfiable version should call next with error

Hi.

Clean package :).

I'd like to request that the case that there's no matched version calls next with a specific error. My justification is that it allows much easier retirement of old versions when you no longer want to support them - and it can all be done in one place.

The only workaround with the current implementation is to do it in a 'default', but you still have to scatter it throughout every route configuration.

Thanks!

UnhandledPromiseRejectionWarning: TypeError: versionRouter.route is not a function

Getting exception error, added sample code only

import * as versionRouter from 'express-version-route';
import { Router, Handler, Request, Response } from 'express';
const routesMap = new Map<string, Handler>();
const route = Router();

export default (app: Router) => {
app.use('/version-customer', route);

routesMap.set('1.0', (req, res, next) => {
return res.status(200).json({ message: 'hello to you version 1.0' });
});

routesMap.set('default', (req, res, next) => {
return res.status(200).json({ message: 'hello to you, this is the default route' });
});

route.get('/test', versionRouter.route(routesMap));
};

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two-Factor Authentication, make configure the auth-only level is supported. semantic-release cannot publish with the default auth-and-writes level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

Question about map

Hi,
First of all, thanks for providing this package :)
I was asking myself why do you use Map instead of a basic Object ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.