What are bindings?

This project and documentation are work in progress

Example code: src/bindings

Bindings take a library that has been instantiated with adapters, and expose it to the outside world. In the case of the example project, our binding is a REST HTTP interface, but you could write a binding to support GraphQL, pub/sub events, or even commands from a user interface (like in a CLI app).

Example: the Express binding

To make the community library app into a webservice, I've written an Express.js binding that maps library functions to incoming HTTP calls:

import express from 'express'
import bodyParser from 'body-parser'
import { Library, Entities } from '@lib'
import { route } from './route'

export function binding (lib: Library) {
  const port = 3000
  const app = express()

  app.use(bodyParser.json())

  app.get('/health', (req, res) => res.sendStatus(200))

  app.post('/book', route({
    fn: lib.book.add,
    validateInput: Entities.castBookInput,
    onSuccess: (res, result) => res.status(201).json(result)
  }))

  app.post('/loan', route({
    fn: lib.loan.take,
    validateInput: Entities.castLoanInput,
    onSuccess: (res, result) => res.status(201).json(result)
  }))

  app.post('/return/:bookID', route({
    fn: lib.loan.return,
    validateInput: Entities.castUUID,
    getInput: (req, params) => (params as any).bookID,
    onSuccess: (res) => res.sendStatus(200)
  }))

  app.post('/user', route({
    fn: lib.user.add,
    validateInput: Entities.castUserInput,
    onSuccess: (res, result) => res.status(201).json(result)
  }))

  app.delete('/user/:userID', route({
    fn: lib.user.remove,
    validateInput: Entities.castUUID,
    getInput: (req, params) => (params as any).userID,
    onSuccess: (res) => res.sendStatus(200)
  }))

  app.listen(port, () => {
    console.log('Example library app listening at port', port)
  })
}

The Route function is defined in src/bindings/express.route.ts and takes an object with four fields:

  • the fn from the library to call

  • a function that validates the input into the format expected

  • a function to extract input from Express' Request object

  • a function for handling success and responding with the right status code

The example route function also manages validation failure and how to log and respond to exceptions.

The route function isn't provided as a cast iron code example, rather a suggestion for how you can reduce boilerplate in your Express apps. Use it just as a starting point and make your own customisations.

Last updated