Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tbeseda/obelisk-lambda
A request router for "monolithic" Lambdas.
https://github.com/tbeseda/obelisk-lambda
aws lambda nodejs router
Last synced: 5 days ago
JSON representation
A request router for "monolithic" Lambdas.
- Host: GitHub
- URL: https://github.com/tbeseda/obelisk-lambda
- Owner: tbeseda
- Created: 2023-05-28T04:31:34.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-04-26T14:43:56.000Z (7 months ago)
- Last Synced: 2024-04-26T15:53:18.110Z (7 months ago)
- Topics: aws, lambda, nodejs, router
- Language: JavaScript
- Homepage: https://jxrrngx355.execute-api.us-west-2.amazonaws.com/
- Size: 362 KB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Όbelisk λ
A powerful request router for "monolithic" Lambdas.
Obelisk is powered by [`find-my-way`](https://github.com/delvedor/find-my-way) - used by Fastify and Restify. Obelisk adopts route-matching from `find-my-way` and provides a more Lambda-like interface for handlers.
## Install
Make sure you actually want a "fat function", then:
```
npm i obelisk-lambda
```Requires Node.js v18+ (v16 works, but isn't recommended).
## Usage
lambda.js:
```js
import { ObeliskRouter } from "obelisk-lambda";const router = new ObeliskRouter();
router.on(
"GET",
"/things/near/:lat-:lng/radius/:r",
async ({ params, store, searchParams }) => {
const { lat, long, r } = params// use coordinates and r (radius) to find the thing
return {
statusCode: 200,
headers: { "content-type": "application/json" },
body: JSON.stringify({ params, store, searchParams }),
};
},
);export const handler = router.mount();
```A more elaborate router can be found in `./example/src/http/any-catchall/router.mjs`
## Deployment
The deploy target is an AWS Lambda behind a v2 HTTP API Gateway1.
These sort of HTTP Lambdas can easily deployed with [Architect](https://arc.codes) -- see `./example` for a sample Arc project2.
1 v1 REST API Gateways are ***not*** supported. [Read about API Gateway v2 Lambda integration](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html).
2 Obelisk is not currently compatible with Arc's Node.js helper library: `@architect/functions`. Specifically the `http()` and `http.async()` methods.
## API
### Constructor
Create a new Obelisk router.
#### `defaultRoute` is optional
Similar to `find-my-way`, you can specify a default handler that will be invoked when no route is matched or a matched route does not return.
```js
function defaultRoute ({ event, context, params, searchParams, store }) {
// event and context are always available
// params, searchParams, and store are only available if a route was matched
console.log("defaultRoute", event.rawPath);return {
statusCode: 404,
headers: { "content-type": "text/plain; charset=utf8" },
body: "not found.",
};
}const router = new ObeliskRouter({ defaultRoute });
```### Instance Methods
#### `on(method, path, [options], handler, [store])`
Add a route to a router instance. See `find-my-way`'s [docs on `method` and `path`](https://github.com/delvedor/find-my-way#onmethods-path-opts-handler-store).
Note that handler functions are quite different from `find-my-way`. See [Handlers API](#handlers-api) below.
```js
router.on("GET", "/things/:id", ({ params }) => {
const { id } = params;return {
statusCode: 200,
headers: { "content-type": "application/json" },
body: JSON.stringify({ thingId: id }),
};
});
````options` are optional.
`on()` tries to maintain `find-my-way`'s method signature.
The optional `store` is not managed in the same way as `find-my-way` and will likely change in the future.
#### `mount()`
Create a Lambda handler function from the Obelisk router.
#### `prettyPrint()`
Calls the internal router's `prettyPrint` method to return an ASCII diagram of known routes.
### Instance Properties
These are mostly used internally and likely not helpful to developers at runtime. They are exposed for debugging purposes.
#### `defaultRoute`
The original `defaultRoute` passed into the constructor.
#### `handlers`
A `Map` of registered routes keyed by the value returned when registering a route.
#### `router`
The internal `FindMyWay` router instance.
Note: provided route handlers are not actually registered with `router.router` and are managed in `router.handlers`.## Handlers API
### Payload
#### `event` API Gateway 2.0 Event
Reference: [Working with AWS Lambda proxy integrations for HTTP APIs](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html)
#### `context` Lambda Context
Reference: [AWS Lambda context object in Node.js](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-context.html)
#### `params` FindMyWay parsed path params
```js
router.on(
"GET",
"/things/near/:lat-:lng/radius/:r",
async ({ params }) => {
const { lat, lng, r } = params;
const thing = await things.geoFind({ lat, lng }, r);
return {
statusCode: 200,
headers: { "content-type": "application/json" },
body: JSON.stringify({ thing }),
};
},
);
```#### `searchParams` FindMyWay's parsed search params
```js
router.on("GET", "/search", async ({ searchParams }) => {
const { q } = searchParams// GET /search?rating=5&sale=true
// q == { rating: '5', sale: 'true' }const results = await things.search({ query: q })
return {
statusCode: 200,
headers: { "content-type": "text/html; charset=utf8" },
body: renderSearchResults(results),
};
});
```#### `store` FindMyWay store
The `store` is currently passed through but not entirely functional as in `find-my-way`.
## FAQ
Why not use the typical
(req, res) => {}
signature?1. IMO ordered arguments are a bummer
1. `res` isn't as simple as `return`ing data
1. a payload with many keys means Obelisk can easily attach AWS-provided data`function (req, res) {}` has, and will continue, to serve long-lived Node processes well, but structured payloads are more ergonomic for evented "cloud functions".
How do I parse a POST body?
Decode the base64 body on the `event`. Assuming the body was sent as `x-www-form-urlencoded` (HTML forms are):
```js
import { parse } from "node:querystring"; // or your query string parser of choicerouter.on("POST", "/form", ({ event }) => {
// `event` is an APIGatewayProxyEventV2
const data = Buffer.from(event.body, "base64").toString("utf8");
const decoded = parse(data);
// ...
```
defaultRoute
isn't getting some parameters, what gives?If the original request doesn't match a route, `defaultRoute` is invoked with only the `event` and `context` objects.
What's the
store
for?In `find-my-way` it is used to persist data when the route is registered and/or between handlers. This feature is only partially implemented in Obelisk.