You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Store API provides a way to share data between middleware and route handlers without relying on closures or module-level variables. There are two types of store: **request** and **shared**.
928
+
929
+
#### Request store
930
+
931
+
The request store is scoped to a single invocation. Each time your Lambda function handles a request, a fresh store is created. This is ideal for passing values like authenticated user IDs or parsed tokens from middleware to route handlers.
932
+
933
+
You can interact with the request store directly on the request context using `set`, `get`, `has`, and `delete`.
1. Middleware stores the authenticated user ID in the request store.
942
+
2. Route handler retrieves the user ID set by middleware.
943
+
944
+
!!! note "Request store lifecycle"
945
+
The request store is created at the beginning of each invocation and is not shared across concurrent or subsequent requests. You don't need to clean up after yourself — the store is discarded when the invocation completes.
946
+
947
+
#### Shared store
948
+
949
+
The shared store lives on the `Router` instance and persists across invocations for the lifetime of the execution environment. This makes it suitable for values that are expensive to compute and don't change between requests, such as database clients, configuration, or feature flags.
950
+
951
+
You can access the shared store via `app.shared` at the module level (e.g., during cold start), or via `reqCtx.shared` inside middleware and route handlers.
1. Set shared values at the module level during cold start.
960
+
2. Access shared values inside route handlers via `reqCtx.shared`.
961
+
962
+
#### Typed stores
963
+
964
+
By default, both stores accept any string key and return `unknown` values. When you know the shape of your data ahead of time, you can define an `Env` type to get full type safety on store keys and values.
1. Define the shape of the request store — keys and their value types.
973
+
2. Define the shape of the shared store.
974
+
3. `app.shared.set` only accepts keys defined in `AppEnv['store']['shared']` with matching value types.
975
+
4. `reqCtx.set` only accepts keys defined in `AppEnv['store']['request']` with matching value types.
976
+
5. `reqCtx.get('userId')` returns `string | undefined` instead of `unknown`.
977
+
6. `reqCtx.shared.get('db')` returns the typed database client or `undefined`.
978
+
7. Accessing a key not defined in `AppEnv` is a type error — the compiler only allows `'userId'` and `'isAdmin'`.
979
+
980
+
!!! tip "Store values are always `T | undefined`"
981
+
Even with typed stores, `get` returns `T[K] | undefined`. This ensures you handle the case where a value hasn't been set yet, for example if a middleware hasn't run or a shared value wasn't initialized during cold start.
982
+
983
+
#### Typed stores with split routers
984
+
985
+
When using [split routers](#split-routers), each sub-router can declare its own `Env` type with only the store keys it needs. You can then chain `includeRouter` calls to merge the store types together, so the parent router sees all keys from all sub-routers.
1. `MergeEnv` computes the intersection of the sub-router store types into a single `Env`.
1010
+
2. The parent router is created with the merged `AppEnv` type — all store keys are known upfront.
1011
+
3. `includeRouter` accepts any sub-router whose `Env` is a subset of the parent's.
1012
+
925
1013
### Considerations
926
1014
927
1015
This utility is optimized for AWS Lambda computing model and prioritizes fast startup, minimal feature set, and quick onboarding for triggers supported by Lambda.
0 commit comments