swatchjs-koa

2.2.1 • Public • Published

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.

Package Sidebar

Install

npm i swatchjs-koa

Weekly Downloads

8

Version

2.2.1

License

MIT

Unpacked Size

64.6 kB

Total Files

18

Last publish

Collaborators

  • jaredreisinger
  • fredly
  • furchin
  • bwtimm