http-doc

0.0.11 • Public • Published

Coverage Badge Last build

http-doc

Creates your HTTP routes with ACL, data filtering and automatic documentation.

Features

  • Documentation on routes or controllers
  • Automatic OpenAPI documentation generator
  • Access control management
  • Plugin system to handle additional HTTP frameworks

Installation

Install http-doc with npm

npm install http-doc --save

or with yarn

yarn add http-doc

API instanciation

import { Api, collection } from 'http-doc'

const api = new Api({
  // options, see Api Options section
})

// Register routes
collection(
  'Users',
  router => {
    router.get('/', UserController.list, {
      // options, see Route Options section
    })
  },
  {
    title: 'Users',
    description: 'Managing users',
    prefix: '/users'
  }
)

// Apply configuration to your HTTP framework
api.setup()

Api Options

Parameter Type Description
app object HTTP framework instance
documentationPath string Documentation display path (Default: /swagger.json)
documentationAccess function Function used to restrict access to the documentation configuration file. (default: request => true)
driver class Provides plugin to use for HTTP framework interaction.
getUserAccess string/array/function List of user access list. Can be a single string, or a function returning a string or an array of strings.
monitor boolean Monitor all API calls (count, time metrics). Creates a set of monitoring API endpoints (See Monitoring section). (default: false)
monitorAccess function Function used to restrict access to the monitoring API. (default: request => true)
prefix string Prefix for all routes
schemasFolder string Path to folder containing all OpenAPI Schemas (default: schemas)

Route Options

Parameter Type Description
title string Endpoint name in documentation.
description string Endpoint description in documentation.
access string/array/function List of user access requirements. Can be a string, a function or an array of string or functions. Functions will return a boolean.
accepts string/array/object Restricts input with provided OpenAPI Schema. Can be a string (file path to schema), an object (OpenAPI schema), or an array of strings (file path to schema) or objects (direct schema or conditional object : {schema: String, handler: Function, description: String}). Validated schemas will be merged.
returns object List of possible returned data, by HTTP code.
returns.{code} object Object describing returned data.
returns.{code}.schema string OpenAPI Schema path, relative to schemasFolder Api configuration field.
returns.{code}.description string Description of returned data.
parameters.{name} object Object describing parameter.
parameters.{name}.schema string OpenAPI Schema path, relative to schemasFolder Api configuration field.
parameters.{name}.description string Description of parameter.

Access Control Lists

ACL is based on custom strings, like admin, users:list, per example. You define which permissions a user have, and he'll be able to access only routes with correct permissions.

Example

import { Api, collection } from 'http-doc'

const api = new Api({
  getUserAccess: request => {
    // Logged in user :
    /* {
      permissions: ['users:list', 'users:create']
    } */
    return request.user.permissions
  }
})

controller('Users', router => {
  router.get('/', listController, {
    access: 'users:list' // Will have access to this endpoint
  })
  router.post('/', createController, {
    access: ['admin', 'users:create'] // Will have access to this endpoint, because one of the requirements is fulfilled
  })
  router.put('/:id', updateController, {
    access: [
      'admin',
      'users:edit',
      request => request.params.id === request.user.id
    ] // Will not have access to this endpoint if he tries to edit another user
  })
})

OpenAPI Schemas

Input data and returned data filtering works with OpenAPI Schemas, stored where you want on your project folder in JSON format. References are relative to the provided schemas folder when initializing API.

Example :

{
  "type": "object",
  "required": ["name"],
  "properties": {
    "name": {
      "type": "string"
    },
    "address": {
      "$ref": "Address"
    },
    "age": {
      "type": "integer",
      "minimum": 0
    }
  }
}

More info on OpenAPI Schemas here.

Handled string formats :

  • date
  • date-time
  • byte (or base64)
  • email
  • uuid
  • objectid
  • uri

Unsupported features :

  • allOf
  • anyOf
  • oneOf
  • not

Parameters

With parameters route configuration parameter, you can describe and filter parameters located in query, path, headers or cookies.

Example

import { collection } from 'http-doc'

controller('Users', router => {
  router.get('/', listController, {
    parameters: {
      page: { schema: 'params/Page', description: 'Page' },
      limit: { schema: 'params/Limit', description: 'Limit' }
    }
  })
})

Input data filtering

You can filter input data with accepts configuration field on routes.

Example

import { collection } from 'http-doc'
import UserGetFilter from '../UserGetFilter.json'

controller('Users', router => {
  router.get('/', listController, {
    accepts: 'UserListFilters'
  })
  router.get('/:id', listController, {
    accepts: UserGetFilter
  })
  router.post('/', createController, {
    accepts: [
      'UserCreate',
      {
        schema: 'UserCreateAdmin',
        handler: request => !!request.user?.admin,
        description: 'If user is admin'
      }
    ]
  })
})

Returned data filtering

With returns route configuration parameter, you can automatically filter data returned by your controller according to an OpenAPI Schema, accordingly to the returned HTTP code.

Example

import { collection } from 'http-doc'
import UserGetFilter from '../UserGetFilter.json'

controller('Users', router => {
  router.get('/', listController, {
    returns: {
      200: { schema: 'UserLite', description: 'User data' },
      403: { schema: 'Error', description: 'Not authorized' },
      500: { schema: 'Error', description: 'Unknown error' }
    }
  })
  router.get('/:id', listController, {
    returns: {
      200: { schema: 'User', description: 'User data' },
      403: { schema: 'Error', description: 'Not authorized' },
      500: { schema: 'Error', description: 'Unknown error' }
    }
  })
  router.post('/', createController, {
    returns: {
      201: { schema: 'User', description: 'User data' },
      400: { schema: 'Error', description: 'Bad input data' },
      403: { schema: 'Error', description: 'Not authorized' },
      500: { schema: 'Error', description: 'Unknown error' }
    }
  })
})

Decorators

Decorators are provided to configure your routes, directly from the controllers :

import {
  title,
  description,
  access,
  accepts,
  returns,
  parameter
} from 'http-doc'

export default class UsersController {
  @title('Login')
  @description('Logs in a user')
  @access(true)
  @accepts('Login')
  @parameter('source', 'Source', 'Accepted auth source')
  @returns(200, 'UserJwt', 'Authorized JWT token')
  @returns(403, 'Error', 'Invalid credentials')
  @returns(500, 'Error', 'System error')
  static async login (request, reply, routeConf) {
    // Handling login
    return { loggedIn: true }
  }
}

You need to add babel configuration to handle ES6 decorators (experimental for now):

{
  "plugins": [["@babel/plugin-proposal-decorators", { "version": "2022-03" }]]
}

Authors

Readme

Keywords

none

Package Sidebar

Install

npm i http-doc

Weekly Downloads

1

Version

0.0.11

License

MIT

Unpacked Size

96.2 kB

Total Files

50

Last publish

Collaborators

  • guillaume-gagnaire