Alagarr
🦍 Alagarr is a request-response helper library that removes the boilerplate from your Node.js (AWS Lambda) serverless functions and helps make your code portable.
Install / Use
/learn @adieuadieu/AlagarrREADME

Alagarr is a request-response helper library for serverless/faas functions<sup>*</sup> invoked via HTTP events (e.g. via API Gateway). Alagarr makes your code portable: it abstracts the event-context-callback function signatures of various serverless-providers so that you can spend less time writing boring function-as-a-service-related boilerplate.
Alagarr is a higher-order function which abstracts the the programming models of various serverless-cloud providers and adds a standardized request-response model extensible through composable middleware functions. It's API is concise and will be familiar to anyone who's worked with Express.js. It comes with built-in error handling which makes it trivial to implement error-recovery strategies.
<sup>*</sup>Currently: AWS Lambda/API Gateway. Next: GCP & Azure
Without Alagarr:
// AWS Lambda / API Gateway
module.exports.myHandler = function(event, context, callback) {
callback(null, {
statusCode: 200,
body: JSON.stringify({ foo: 'bar' }),
headers: {
'content-type': 'application/json',
},
})
}
With Alagarr:
const alagarr = require('alagarr')
module.exports.myHandler = alagarr(() => ({ foo: 'bar' }))
Contents
- Features
- Full Example
- Installation & Usage
- Configuration
- API
- Error Handling
- Logging
- Middleware
- Contributing
- Similar Projects
- Related Thingies
- License
Features
- Concise & familiar API
- Zero dependencies
- Fully tested
- Built-in error handling makes catching and throwing errors a breeze
- Kibana-ready request logging
- Middleware for common tasks included
- Request cookie parsing
- Normalized request headers
- Includes request body parsers
- Response CSP headers
- Response gzipping/deflate
- Easily respond with images/binary data
- Support for custom middleware
Full Example
Alagarr helps you cut out all the boilerplate involved with handling HTTP requests in serverless functions. Albeit somewhat contrived, here is a before-and-after example of a common pattern frequently found in AWS Lambda function's:
Without Alagarr 😭
const got = require('got')
module.exports.handler = function(event, context, callback) {
const { queryStringParameters: { currency } } = event
if (!currency) {
callback(null, {
statusCode: 400,
body: JSON.stringify({
message: 'Please provide the "currency" query parameter.',
}),
headers: {
'content-type': 'application/json',
},
})
}
got(`https://api.coinmarketcap.com/v1/ticker/${currency}`)
.then(response => {
callback(null, {
statusCode: 200,
body: JSON.stringify(response),
headers: {
'content-type': 'application/json',
},
})
})
.catch(error => {
callback(null, {
statusCode: error.statusCode,
body: JSON.stringify({
error: error.response,
}),
headers: {
'content-type': 'application/json',
},
})
})
}
With Alagarr 😁
const { alagarr, ClientError } = require('alagarr') // @TODO: this require is wrong
const got = require('got')
module.exports.handler = alagarr((request, response) => {
const { query: { currency } } = request
if (!currency) {
throw new ClientError('Please provide the "currency" query parameter.')
}
return got(`https://api.coinmarketcap.com/v1/ticker/${currency}`)
})
There are a few things being handled for you in the above Alagarr example:
- The programming model has been normalized. You can run this code without modification on any of the supported cloud/faas/serverless providers. Not just AWS Lambda. Alagarr makes your code portable.
- The
callback()is being handled for you. Alagarr will set the status code, content-type, and body appropriately. More on this behavior here. - Errors are caught for you and turned into something appropriate for the client based on the type of error. If you don't like the default behavior, you can provide your own error handler.
Installation & Usage
Install Alagarr with NPM or Yarn:
npm install alagarr
Then include it in your serverless function:
const alagarr = require('alagarr')
module.exports.exampleHandler = alagarr(request => {
const { path, provider } = request
return `You've ended up at ${path} on the ${provider} cloud.`
})
Configuration
Alagarr ships with default configuration that should work for most use-cases. But, it's possible to pass a configuration object as the second parameter to the alagar() function:
const alagarr = require('alagarr')
module.exports.handler = alagarr(() => 'Hello world!', {
headers: {},
logger: console.log,
})
Configuration Options
The available configuration options are outlined here:
| Option | Default | Description |
| ---------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| cspPolicies | [] | List of CSP policies to include in the response headers |
| errorHandler | | Provide a custom error handler. See the section on Error Handling for more details |
| headers | {} | Headers to include in every response |
| logger | | Logger to use to log requests. If undefined, Alagarr will use an internal logger. Logging can be disabled by setting to false. See the section on Logging for more details |
| requestMiddleware | | Array of custom request middleware to use. See the section on Request Middleware for more details |
| responseMiddleware | | Array of custom response middleware to use. See the section on Response Middleware for more details |
API
Alagarr module
Request methods
request.bodyrequest.contextrequest.cookiesrequest.headersrequest.hostnamerequest.metarequest.methodrequest.pathrequest.providerrequest.queryrequest.sourcerequest.timestamp
Response methods
response.json()response.html()response.text()response.svg()response.png()response.jpeg()response.respondTo()response.raw()
<a name="api-alagarr-module-default" />
alagarr(handlerFunction, configurationOptions?): void
@TODO
const alagarr = require('alagarr')
const configurationOptions = {
logger: false,
}
const handlerFunction = function(request, response) {
const { query: { name } } = request
return response.html(`Hello ${name}.`)
}
module.exports.handler = alagar(handlerFunction, configurationOptions)
<a name="api-alagarr-handlerFunction" />
The handlerFunction has a function signature of:
export type HandlerFunction = (
request: any,
response: any,
) => string | object | void | Promise<string | object | void>
If your handlerFunction returns falsey, then it's your responsibility to call the appropriate response method to end the invocation (e.g. response.json()). For convenience, if the handlerFunction returns a string, the result will be passed to response.html() or response.text() for you. Alternatively, if the handler returns an object, it will be passed to response.json(). You may also return a Promise (or make your handler async).
<a name="api-alagarr-module-request-middleware" />
Related Skills
node-connect
352.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
111.3kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
352.5kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
352.5kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
