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

swatchjs-koa

v2.2.1

Published

KOA adapter for swatchjs

Downloads

168

Readme

swatchjs-koa

CircleCI | codecov | Coverage Status | Known Vulnerabilities

An adapter to expose swatchjs via KOA.

Quick start

The following exposes the simple API from the swatchjs's README file:

// Application server
const Koa = require('koa');
const swatch = require('swatchjs');
const swatchKoa = require('swatchjs-koa');

const model = swatch({
    "numbers.add": (a, b) => Number(a) + Number(b),
    "numbers.sub": (a, b) => Number(a) - Number(b),
});

const app = new Koa();
swatchKoa(app, model);

app.listen(3000);

That's it! No HTTP headers, status codes, or any other distracting verbiage. Each API method you declared can now be invoked using any of the supported HTTP verbs.

Note: It is strongly advised that you only enable your APIs over HTTPS. Read more about HTTPS and why it's important and how to use HTTPS with your node server. This tutorial also provides a walkthrough of the entire process, including certificate setup and configuration.

Verbs

GET

The GET binding expects all parameters to be passed in the query string.

For instance, using the popular request package, you would invoke the numbers.add method above as follows:

// Client code (ex: Node server)
var request = require('request');

request('https://my-server/numbers.add?a=1&b=2');

Note: Every parameter in the query string is received as, well, a string. So if you plan on supporting the GET verb, it is recommended that either you provide parse functions for each of your arguments, or that you validate and coerce them inside your function (as shown in the example above).

POST

The POST binding expects parameters to be passed in the body property of KOA' request object.

Below is an example of calling the API using an XMLHttpRequest object:

// Client code (ex: Browser JS)
function post(url, body) {
    var request = new XMLHttpRequest();

    request.open('POST', url);
    request.setRequestHeader('Content-Type', 'application/json');
    request.send(JSON.stringify(body));

    return request;
}

var request = post(
    'https://my-server/numbers.add',
    {
        a: 1,
        b: 2,
    });

Note

Be mindful that how the body property of KOA' request object gets populated depends on which body-parsing middleware you have enabled.

There are popular libraries for KOA that enable the service to choose their behavior with regards to body parsing. A popular one is koa-bodyparser.

If you have a simple JSON body parser, then it will parse application/json content types, and your parameters could potentially have non-string types.

If, on the other hand, you have application/x-www-form-urlencoded parsing enabled, then all parameters will be strings, and the same considerations of the GET verb apply.

Security Notice: Remember that you may receive string objects using either approach, which you should validate and coerce before passing to your handler functions.

API reference

The swatchKoa function

// Application server
const swatchKoa = require('swatch-koa');

swatchKoa(app, model, options);

Loading this library will result in a function (swatchKoa in the example above) which takes the following parameters:

| Parameter | Required | Description | |:--- |:--- |:--- | |app | Yes | The KOA app to populate. | |model | Yes | The API model created by swatchjs. | |options | No | Additional options when exposing the API. When present, must be an object. |

The options object has the following properties:

| Property | Example | Default value | Description | |:--- |:--- |:--- |:--- | |verbs |['get'] |['get','post'] | An array with a list of enabled HTTP verbs. Each verb must be a string. | |prefix |'api' |'' | A URL prefix to be added to every route. For example, if the value of this option is 'product', then the URL of all APIs will start with /product/. | |authAdapter |fn |See below | A function to perform authentication and extract credentials from a request. | |onException |fn |See below | A function to catch any exception and optionally rescue before returning an error. | |rawResponse |boolean |false | Returns the raw response object without the { ok: true } or { ok: false } wrapper. | |requestIdProp|string |undefined | A string matching the koa-bunyan-logger key for requestIdContext.prop parameter. If present, the request ID will be returned in x-swatch-request-id response header. If empty, no header will be set. |

The authAdapter function

Clients can specify a function to map an incoming KOA request into a custom object containing user credentials or authentication details. The authAdapter function is run as the first piece of middleware in any request. It should have the following form:

async function sampleAuthAdapter(koaCtx) {
  // Use koaCtx.request.headers to access headers
  var token = koaCtx.request.headers.authorization;

  // Validate authentication param synchronously
  //  or make an async call to a token service
  var userInfo = await externalTokenService.verify(token);

  // Throw an exception if authentication fails
  //                    OR
  // Return any object if authentication succeeds
  return {
    token: token,
    userName: userInfo.name,
    userRole: userInfo.role,
  };
}

If the authAdapter throws an exception, the request will short-circuit and return the error code with status ok: false. If the authAdapter returns any value, it will store the result under swatchCtx.auth. The result can be accessed later, allowing clients to reuse any result in the handler.

The onException function

Clients can specify a function that will execute whenever an error is thrown from a handler. This function will run before a response is set, allowing the client to handle the error. The onException function can do one of three things:

  1. Re-throw to return the exception to client with { ok: false } semantics
  2. Throw an alternate exception to return to client with { ok: false } semantics
  3. Return any object to rescue the error and return to client with { ok: true } semantics

The function must be synchronous, and should have the following form:

function sampleOnException(error) {
  // Returning an object will rescue
  if (error === 'some_minor_error') {
    return { rescued_error: true };
  }

  // Map the error to another error by throwing
  if (error === 'some_internal_db_error') {
    throw 'generic_server_unavailable_error';
  }

  // Otherwise caller can re-throw the original
  throw error;
}

The requestIdProp parameter

Clients can use the koa-bunyan-logger package to configure a request logger for their service. That package exposes a requestIdContext function that generates a unique ID for each request to correlate related log messages. The unique ID is saved on the KOA context object under a key you can override with the prop parameter (the default value is reqId. See that package documentation for details.)

The swatchjs-koa package uses this bunyan logger as a part of the swatchCtx. To provide additional debugging support, clients can request that the unique ID be returned in a response header: x-swatch-request-id. To enable this behavior, set the loggerRequestId property in the swatchjs-koa configuration to a string that matches the prop parameter passed into the koa-bunyan-logger configuration. This will allow swatchjs-koa to look up the request ID value from the KOA context. If not set, the header will not be included in the response.

Additionally, if the loggerRequestId property is set in the swatchjs-koa configuration, the caller can choose to pass in their own request ID in the request headers. Simply make an API request to a swatch endpoint and pass in any value under the x-swatch-request-id header, and it will overwrite the bunyan logger request guid with the client guid to be included in all logs.

Middleware

The swatchjs package allows the creation of middleware functions to be executed before the API handler. Those middleware functions should be written in the style of KOA middleware, accepting a Swatch context object and a callback function. The Swatch context has a ctx.req property which contains the request parameters copied from the KOA request context.

Developers

Coding Style

This project follows the AirBnB Javascript Coding Guidelines using ESLint settings.