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

sails-hook-api-version-accept

v0.1.0

Published

Sails.js hook that enabled API versioning through the Accept header

Downloads

3

Readme

A Sails.js hook that enables API versioning via the HTTP Accept header. It forces clients to specify the version and routes requests for older versions to Sails.js helpers.

Still alpha. Not ready for use yet.

How to use this hook

  1. install the hook into your project
      yarn add sails-hook-api-version-accept
  2. enable the hook in your .sailsrc by listing it as a hook:
    /* .sailsrc */
    {
      "generators": {...
      "_generatedWith": {...
      "hooks": {
        "api-version-accept": true /* <- add this line */
      }
    }
  3. on each of your models that you want versioned, you need to add the versionConfig field
    module.exports = {
    
      attributes: {...
    
      versionConfig: { /* <- add this config, see next section for help */
        versions: ['v1', 'v2'],
        vendorPrefix: 'vnd.techotom',
      }
    }
  4. for versions that aren't the latest, you need to define some helpers to service those requests. Each helper will match the pattern: api/helpers/<version>-<model>-<action>.js. For example, for version=v1, model=Foo and action=Find we would create a helper with the file name: api/helpers/v1-Foo-Find.js. You can create the file by hand or use the sails generator:
    sails generate helper v1FooFind
  5. implement the helper(s) you've just created. You can do this however you see fit. As an example, to implement a find action for an older version, it makes sense to call the .find() action (effectively getting the results for the latest version), then transform the result before sending the response. See demo/api/helpers/v1FooFind.js for an example.
  6. update any clients for this API so they send the correct Accept header.

Reference for versionConfig object

| field name | type | example | description |---|---|---|---| | versionConfig | {} | {versions: [], vendorPrefix: 'string'} | The container object for the config | versionConfig.versions | string[] | ['v1', 'v2'] | Each element represents a version. Make sure your names have legal syntax for Content-types. The order of element is important; the last element is implicitly the latest version. The recommendation is to keep it simple: ['v1', 'v2', 'v3', ...]. | versionConfig.vendorPrefix | string | vnd.example | It is suggested that you use the vendor tree prefix of vnd. and then some subtree of that for your project. You're meant to register them with IANA but you can probably write your API first and worry about that later when it starts to take off. This value will be inserted into the MIME like application/<vendorPrefix>.v1+json.

Why create this hook?

RESTful API Versioning has a number of schools of thought, you can read some background at the following links:

  • https://www.troyhunt.com/your-api-versioning-is-wrong-which-is/
  • https://www.narwhl.com/content-negotiation/

Troy captures the different schools of thought concisely:

...let me outline the three common schools of thought in terms of how they’re practically implemented:

  1. URL: You simply whack the API version into the URL, for example: https://haveibeenpwned.com/api/v2/breachedaccount/foo
  2. Custom request header: You use the same URL as before but add a header such as “api-version: 2”
  3. Accept header: You modify the accept header to specify the version, for example “Accept: application/vnd.haveibeenpwned.v2+json”

I like option 3. I also like Sails.js. This repo is my attempt to add support for API versioning whilst also keeping all the things that make Sails awesome.

What this hook does

This hook tries to leave as much as possible to pure Sails and only step in when required. This means:

  1. you define version config on the models you want versioned
  2. requests for the latest version, or */*, just use the Sails Blueprint or whatever default handler you have. The only difference is this hook will force the Content-type response header to be the correct, versioned MIME.
  3. requests for earlier versions rely on Sails helpers that you must write

Assumptions

  1. you're using the hook from the start for a new project. You can use it for existing projects, it might require more work to add though.
  2. you have Blueprint shadow routes enabled
  3. your Sails.js project is basically a HTTP API, i.e. you selected Empty when you generated a new Sails project. No testing against a "full" Sails web app (with MVC) has been done yet.

TODO

  1. work out how to handle deleted fields in a given Model. This requires that the model can still store the old field but requests for newer versions don't include it. Perhaps we can add an optional config param that defines which version is the default, so you can pin that to a version and write helpers for newer versions.
  2. handle the blueprint association routes
  3. work out how to handle version POST (Create) requests. Older clients will want to send what they've always sent but that might not be valid for the newer schema. Perhaps we can ask the API developer to write a helper and dynamically add it as a beforeCreate hook for the model. The fallback and be to reject the request.