AWS Lambda + API Gateway Adapter
AWS Lambda adapter
The AWS Lambda adapter is supported for API Gateway REST API(v1) and HTTP API(v2), and Lambda Function URL use cases.
httpBatchLink
requires the router to work on a single API Gateway Resource (as shown in the example). If you'd like to have a Resource per procedure, you can use thehttpLink
instead (more info).
Example app
Description | Links |
---|---|
API Gateway with NodeJS client. |
How to add tRPC
1. Install deps
bash
yarn add @trpc/server
bash
yarn add @trpc/server
2. Create a tRPC router
Implement your tRPC router. A sample router is given below:
server.tsts
import { initTRPC } from '@trpc/server';import { z } from 'zod';export const t = initTRPC.create();const appRouter = t.router({getUser: t.procedure.input(z.string()).query((opts) => {opts.input; // stringreturn { id: opts.input, name: 'Bilbo' };}),});// export type definition of APIexport type AppRouter = typeof appRouter;
server.tsts
import { initTRPC } from '@trpc/server';import { z } from 'zod';export const t = initTRPC.create();const appRouter = t.router({getUser: t.procedure.input(z.string()).query((opts) => {opts.input; // stringreturn { id: opts.input, name: 'Bilbo' };}),});// export type definition of APIexport type AppRouter = typeof appRouter;
3. Use the Amazon API Gateway adapter
tRPC includes an adapter for API Gateway out of the box. This adapter lets you run your routes through the API Gateway handler.
server.tsts
import { CreateAWSLambdaContextOptions, awsLambdaRequestHandler } from '@trpc/server/adapters/aws-lambda';const appRouter = /* ... */;// created for each requestconst createContext = ({event,context,}: CreateAWSLambdaContextOptions<APIGatewayProxyEventV2>) => ({}) // no contexttype Context = Awaited<ReturnType<typeof createContext>>;export const handler = awsLambdaRequestHandler({router: appRouter,createContext,})
server.tsts
import { CreateAWSLambdaContextOptions, awsLambdaRequestHandler } from '@trpc/server/adapters/aws-lambda';const appRouter = /* ... */;// created for each requestconst createContext = ({event,context,}: CreateAWSLambdaContextOptions<APIGatewayProxyEventV2>) => ({}) // no contexttype Context = Awaited<ReturnType<typeof createContext>>;export const handler = awsLambdaRequestHandler({router: appRouter,createContext,})
Build & deploy your code, now use your API Gateway URL to call your function.
Endpoint | HTTP URI |
---|---|
getUser | GET https://<execution-api-link>/getUser?input=INPUT where INPUT is a URI-encoded JSON string. |
A word about payload format version
API Gateway has two different event data formats when it invokes a Lambda. For REST APIs they should be version "1.0"(APIGatewayProxyEvent
), but you can choose which for HTTP APIs by stating either version "1.0" or "2.0".
- Version 1.0:
APIGatewayProxyEvent
- Version 2.0:
APIGatewayProxyEventV2
To infer what version you might have, supply the context as following:
ts
function createContext({event,context,}: CreateAWSLambdaContextOptions<APIGatewayProxyEvent>) {...}// CreateAWSLambdaContextOptions<APIGatewayProxyEvent> or CreateAWSLambdaContextOptions<APIGatewayProxyEventV2>
ts
function createContext({event,context,}: CreateAWSLambdaContextOptions<APIGatewayProxyEvent>) {...}// CreateAWSLambdaContextOptions<APIGatewayProxyEvent> or CreateAWSLambdaContextOptions<APIGatewayProxyEventV2>
Read more here about payload format version
AWS Lambda Response Streaming Adapter
AWS Lambda supports streaming responses to clients.
Response streaming is only supported for Lambda Function URLs. You can not use API Gateway to stream responses. Read more here about response streaming.
Example app
Description | Links |
---|---|
Lambda Function URL with NodeJS client. |
Response Streaming
The signature of a streaming handler is different from the default handler. The streaming handler additonally receives a writable stream parameter, responseStream
, besides the default node handler parameters, event
and context
. To indicate that Lambda should stream your responses, you must wrap your function handler with the awslambda.streamifyResponse()
decorator.
Note that the
awslambda
namespace is automatically provided by the Lambda execution environment. You can import the types from@types/aws-lambda
to augment the global namespace with theawslambda
namespace.
server.tsts
import { awsLambdaStreamingRequestHandler } from '@trpc/server/adapters/aws-lambda';import type { StreamifyHandler } from 'aws-lambda';const appRouter = router({iterable: publicProcedure.query(async function* () {for (let i = 0; i < 10; i++) {await new Promise((resolve) => setTimeout(resolve, 500));yield i;}}),});export const handler = awslambda.streamifyResponse(awsLambdaStreamingRequestHandler({router: appRouter,/* ... */}),);
server.tsts
import { awsLambdaStreamingRequestHandler } from '@trpc/server/adapters/aws-lambda';import type { StreamifyHandler } from 'aws-lambda';const appRouter = router({iterable: publicProcedure.query(async function* () {for (let i = 0; i < 10; i++) {await new Promise((resolve) => setTimeout(resolve, 500));yield i;}}),});export const handler = awslambda.streamifyResponse(awsLambdaStreamingRequestHandler({router: appRouter,/* ... */}),);