0.0.11 • Published 2 years ago

http-doc v0.0.11

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

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

ParameterTypeDescription
appobjectHTTP framework instance
documentationPathstringDocumentation display path (Default: /swagger.json)
documentationAccessfunctionFunction used to restrict access to the documentation configuration file. (default: request => true)
driverclassProvides plugin to use for HTTP framework interaction.
getUserAccessstring/array/functionList of user access list. Can be a single string, or a function returning a string or an array of strings.
monitorbooleanMonitor all API calls (count, time metrics). Creates a set of monitoring API endpoints (See Monitoring section). (default: false)
monitorAccessfunctionFunction used to restrict access to the monitoring API. (default: request => true)
prefixstringPrefix for all routes
schemasFolderstringPath to folder containing all OpenAPI Schemas (default: schemas)

Route Options

ParameterTypeDescription
titlestringEndpoint name in documentation.
descriptionstringEndpoint description in documentation.
accessstring/array/functionList of user access requirements. Can be a string, a function or an array of string or functions. Functions will return a boolean.
acceptsstring/array/objectRestricts 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.
returnsobjectList of possible returned data, by HTTP code.
returns.{code}objectObject describing returned data.
returns.{code}.schemastringOpenAPI Schema path, relative to schemasFolder Api configuration field.
returns.{code}.descriptionstringDescription of returned data.
parameters.{name}objectObject describing parameter.
parameters.{name}.schemastringOpenAPI Schema path, relative to schemasFolder Api configuration field.
parameters.{name}.descriptionstringDescription 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

0.0.11

2 years ago

0.0.10

2 years ago

0.0.9

2 years ago

0.0.8

2 years ago

0.0.7

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago