@ctx/axios
TypeScript icon, indicating that this package has built-in type declarations

1.0.0 • Public • Published

@ctx/axios

Build Status Dependency Status

Utilities to make using contexts easier when making HTTP calls via axios.

See the typedoc for API documentation.

Example

Add a timeout to multiple requests

Adding a timeout to a single request is easy, but it's harder for multiple requests, as you have to do things like calculating how long you have left before the timeout is up, which is a right pain. And that's why most people don't bother. Contexts make this super easy:

const context = require('@ctx/context')
const axios = require('@ctx/axios')

async function getFooThenBar(ctx) {
  [ctx, cancel] = context.WithTimeout(ctx, 1000)
  try {
    const foo = axios.get(ctx, 'http://foo.com')
    const bar = axios.get(ctx, `http://bar.com/${foo.foz}`)
    cancel()
    return bar
  } catch (e) {
    cancel()
    throw e
  }
}

In this example, if getFoo takes 900ms, and getBar takes 200ms, the getBar call will throw an exception after about 100ms. That's super painful to do without something like ctx!

Passing headers through a service

What say we want every single request passed through to have a random request id, and we want out servers to log that and then propogate them onwards.

This example uses @ctx/express.

const express = require('express')
const context = require('@ctx/context')
const expressCtx = require('@ctx/express')
const axios = require('@ctx/axios')

const app = express()

app.use(expressCtx.readHeaders(['request-id']))
// If the upstream didn't pass in a request-id, we'll add one
app.use((req, res) => {
  if (!req.ctx.Value('request-id')) {
    let cancel
    [req.ctx, cancel] = context.WithValue(ctx, 'request-id', 'random value')
    req.on('finish', cancel)
  }
})
// Tell @ctx/axios to propogate the request-id header
app.use((req, res) => {
  let cancel
  [req.ctx, cancel] = axiosCtx.setPropogatedValues(ctx, ['request-id'])
  req.on('finish', cancel)
})
// Now in our handler, the header will be passed through automatically
app.get('/foo', async (req, res) => {
  res.json(await axios.get(ctx, 'https://downstream.api/foo')).end()
})

The two middlewares in the above example can be packaged up into your own specific wrappers; @ctx/axios and @ctx/express don't do this as 1) they don't have opinions on the headers to be passed through, and 2) they shouldn't require each other, while bundling the above middleware would require that.

Readme

Keywords

none

Package Sidebar

Install

npm i @ctx/axios

Weekly Downloads

3

Version

1.0.0

License

MIT

Last publish

Collaborators

  • lclarkmichalek