@ctx/axios
v1.0.0
Published
Wrappers for axios for use with @ctx/context
Downloads
7
Readme
@ctx/axios
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.