What are bindings?

circle-exclamation
circle-info

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.tsarrow-up-right 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.

circle-info

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