@contextualize/lambda-router
v0.0.22
Published
Allows for the creation of Express-like APIs within AWS Lambda
Keywords
Readme
Lambda Router
Allows for the creation of Express-like APIs within AWS Lambda.
Routers
Routers allow you to construct API paths for your application
Basic Usage
import { Router, Handler } from '@contextualize/lambda-router';
const router = new Router();
router.get('/', (req, res)=>{
return res.status(200).json({
status: "ok"
});
})
export const lambdaHandler = Handler.handler(()=>router);
Errors
Lambda router has a number of built-in exceptions for common HTTP error codes. Rather than explicity sending an error response and returning from your endpoint code, you can just throw one of these exceptions.
If your application throws an error that does not extend from @contextualize/lambda-router/PublicError, a HTTP 500 status is returned by default with 'Internal Server Error'
router.post('/', (req, res)=>{
if(!("required" in req.body)){
// Ends execution
// Returns a HTTP 400 error to the user
// Error message is supplied to user in the response body as json
throw new BadRequestError("'required' must be in request body");
}
return res.status(200).json({
status: "ok"
});
})
Path Parameters
Parameters can be passed in through the path using {}. Lambda Router will always prioritize named paths before attempting to use a parameterized path.
router.get('/{myParam}', (req, res)=>{
return res.status(200).json({
status: "ok"
myParam: req.params['myParam']
});
});
router.get('/list', (req, res)=>{
return res.status(200).json({
status: "ok"
list: ['stuff', 'and', 'things']
});
});Middleware
Middleware allow you to run a block of code before all subsequent paths.
// Not protected by token validation
router.get('/', (req,res)=>{
return res.status(200).json({
message: "Welcome!"
});
})
// Check user token
router.use((req)=>{
const token = req.headers['Authorization'];
// Do some token validation
})
// Protected by token validation
router.get('/protected', (req, res)=>{
return res.status(200).json({
message: "You are authenticated"
});
})Subrouting
Subrouters allow you to organize like routes as well as define known states of the request a certain paths.
const router = new Router();
router.get('/', (req, res)=>{
res.status(200).json({
message: 'Home'
})
})
type UserApp = {data: UserProfile}
const userRouter = new Router<UserApp>();
dataRouter.use(async (req)=>{
// Load user's profile from the database
req.app = {data: await User.load(req.params['username'])};
});
userRouter.get('/', (req, res)=>{
// Return user's data
res.status(200).json({
...req.app.data
})
})
userRouter.get('/groups', (req, res)=>{
// Return user's groups
res.status(200).json({
groups: req.app.data.groups
})
})
router.subroute('/users/{username}', userRouter);Background Handler
Some lambdas may require tasks to run in the background after a request has been handled. Handler.backgroundHandler allows you to defer promises for after the lambda has returned a response to the client.
import { Router, Handler } from '@contextualize/lambda-router';
const router = new Router();
router.get('/', (req, res)=>{
req.handler.background(async ()=>{
// Assume this is a request that is going to take a long time
// i.e. uploading a file, running a put query
await fetch('https://example.com')
})
return res.status(200).json({
status: "ok"
});
})
export const lambdaHandler = Handler.backgroundHandler(()=>router);Run as Dedicated Server
You can run lambdas set up with lambda-router, and some that aren't using lambda-router serve. This will create a node native http server that converts HTTP requests into APIGateway-like requests, then converts the response from your router into an HTTP response.
This can be used for either local testing, or converting your serverless application to a server-based app should the needs of your application no-longer be found with lambda.
lambda-router serve -h
Usage: lambda-router serve [options] <main>
Run lambda as a dedicated server
Arguments:
main Main file for starting the lambda
Options:
-p, --port <number> server port (default: "8000")
-e, --entry <string> entry point function (default: "lambdaHandler")
-h, --help display help for command