-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feat(server): support streaming in API Gateway REST API #7039
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@anatolzak is attempting to deploy a commit to the trpc Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughAdds API Gateway REST API response streaming support: new streaming example project, implements required toStream for v1/v2 in the AWS Lambda adapter, adjusts adapter types/runtime checks, and updates docs and example artifacts. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant APIGW as API Gateway (REST)
participant Lambda as AWS Lambda
participant Planner as Adapter/Planner
participant Stream as HttpResponseStream
Client->>APIGW: HTTP request (/{proxy+})
APIGW->>Lambda: Invoke (payload v1)
activate Lambda
Lambda->>Planner: Build response (router -> procedure)
alt Procedure yields streaming data
Planner->>Stream: Send metadata (statusCode, headers, cookies)
loop chunks
Planner->>Stream: Write chunk
end
Stream-->>APIGW: Streamed response
else Non-streaming response
Planner->>Stream: Send metadata + full body
Stream-->>APIGW: Single response
end
deactivate Lambda
APIGW-->>Client: HTTP response (streamed if enabled)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (5)
www/docs/server/adapters/aws-lambda.md (1)
129-129: Duplicate heading "Example apps" may cause navigation issues.The static analysis tool correctly identified that there are now two headings with identical text ("Example apps" on lines 15 and 129). This can cause issues with documentation anchor links and table of contents navigation.
Consider differentiating the headings:
-## Example apps +## Streaming example appspackages/server/src/adapters/aws-lambda/getPlanner.ts (1)
133-149: Consider extracting shared streaming logic to reduce duplication.The
toStreamimplementations inv1Processorandv2Processorare nearly identical. While not blocking, extracting a shared helper would improve maintainability.+async function streamResponse( + response: Response, + stream: Writable, + headers: Record<string, string>, + cookies: string[], +): Promise<void> { + const metadata = { + statusCode: response.status, + headers, + cookies, + }; + + const responseStream = awslambda.HttpResponseStream.from(stream, metadata); + + if (response.body) { + await pipeline(Readable.fromWeb(response.body as any), responseStream); + } else { + responseStream.end(); + } +} const v1Processor: Processor<APIGatewayProxyEvent> = { // ... other methods toStream: async (response, stream) => { const { headers, cookies } = getHeadersAndCookiesFromResponse(response); - - const metadata = { - statusCode: response.status, - headers, - cookies, - }; - - const responseStream = awslambda.HttpResponseStream.from(stream, metadata); - - if (response.body) { - await pipeline(Readable.fromWeb(response.body as any), responseStream); - } else { - responseStream.end(); - } + await streamResponse(response, stream, headers, cookies); }, };Also applies to: 198-214
examples/lambda-api-gateway-streaming/package.json (1)
5-5: Consider removing unnecessarymainfield.Example packages typically don't require distribution fields like
main,module, ortypessince they aren't published or distributed.Apply this diff to remove the unnecessary field:
"private": true, "type": "module", - "main": "index.js", "license": "MIT",examples/lambda-api-gateway-streaming/tsconfig.json (1)
3-3: Remove unnecessary DOM library for Lambda backend.The
"dom"library is intended for browser environments and is unnecessary for an AWS Lambda backend. Including it may allow inadvertent use of browser-only APIs that won't be available at runtime.Apply this diff to remove the DOM library:
- "lib": ["esnext", "dom"], + "lib": ["esnext"],examples/lambda-api-gateway-streaming/src/server.ts (1)
7-16: Consider improving type safety for version detection.The type assertion
(event as { version?: string }).versionon line 13 is used to detect the API Gateway payload format version. However, this approach bypasses TypeScript's type checking.Consider a more explicit approach:
function createContext({ event, context, }: CreateAWSLambdaContextOptions<APIGatewayProxyEvent>) { + const version = 'version' in event ? (event as any).version : undefined; return { event: event, - apiVersion: (event as { version?: string }).version ?? '1.0', + apiVersion: version ?? '1.0', user: event.headers['x-user'], }; }Or use a type guard if version detection becomes more complex in the future.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (10)
examples/lambda-api-gateway-streaming/.gitignore(1 hunks)examples/lambda-api-gateway-streaming/README.md(1 hunks)examples/lambda-api-gateway-streaming/package.json(1 hunks)examples/lambda-api-gateway-streaming/serverless.yml(1 hunks)examples/lambda-api-gateway-streaming/src/client.ts(1 hunks)examples/lambda-api-gateway-streaming/src/server.ts(1 hunks)examples/lambda-api-gateway-streaming/tsconfig.json(1 hunks)packages/server/src/adapters/aws-lambda/getPlanner.ts(3 hunks)packages/server/src/adapters/aws-lambda/index.ts(2 hunks)www/docs/server/adapters/aws-lambda.md(4 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,md,mdx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
Use camelCase for file names (with exceptions like TRPC/RPC/HTTP/JSON acronyms, .config.js, .d.ts, and tests)
Files:
examples/lambda-api-gateway-streaming/README.mdexamples/lambda-api-gateway-streaming/src/client.tsexamples/lambda-api-gateway-streaming/src/server.tspackages/server/src/adapters/aws-lambda/getPlanner.tspackages/server/src/adapters/aws-lambda/index.tswww/docs/server/adapters/aws-lambda.md
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
**/*.{ts,tsx}: Always useimport typefor type-only imports
Separate type imports from value imports
Avoid overzealous object destructuring; prefer direct property access
Object destructuring is acceptable when a variable is used 3+ times
Prefer array destructuring
Avoid sparse array destructuring
Never destructure in function parameter declarations
Avoid destructuring potentially nullish nested properties
Maximum 3 parameters per function; use options objects when more
Type parameter names must match /^(T|$)(A-Z)?[0-9]*$/
Prefix unused variables, parameters, and caught errors with_
Prefer namespace imports for validation libraries and large modules (e.g.,import * as z from 'zod',import * as React from 'react')
Follow import order: test helpers, tRPC test imports, third-party, then relative
Never import from@trpc/*/src; import from the package root instead
Do not useSymbol.disposeorSymbol.asyncDispose; usemakeResource()/makeAsyncResource()
Always useawait usingfor resource cleanup
PrefermakeResource()/makeAsyncResource()over manual disposal logic
Avoid non-null assertions (!)
Use proper type guards and optional chaining instead of non-null assertions
Switch statements must be exhaustive for union types
Rely on TypeScript inference; avoid unnecessary explicit return/output types
Use explicit types at public API boundaries, for complex generic constraints, or when inference is insufficient/ambiguous
Use thesatisfiesoperator to retain inference while enforcing shapes
Useas constfor literal type inference when appropriate
Prefer explicit typing overany
Use type assertions sparingly
Leverage TypeScript strict mode features
Files:
examples/lambda-api-gateway-streaming/src/client.tsexamples/lambda-api-gateway-streaming/src/server.tspackages/server/src/adapters/aws-lambda/getPlanner.tspackages/server/src/adapters/aws-lambda/index.ts
packages/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
No
console.login packages; use proper logging instead
Files:
packages/server/src/adapters/aws-lambda/getPlanner.tspackages/server/src/adapters/aws-lambda/index.ts
🧠 Learnings (17)
📚 Learning: 2025-09-05T16:48:06.982Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-09-05T16:48:06.982Z
Learning: Applies to **/*.{ts,tsx,md,mdx} : Use camelCase for file names (with exceptions like TRPC/RPC/HTTP/JSON acronyms, .config.js, .d.ts, and tests)
Applied to files:
examples/lambda-api-gateway-streaming/tsconfig.json
📚 Learning: 2025-09-05T16:48:06.982Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-09-05T16:48:06.982Z
Learning: Applies to **/*.{ts,tsx} : Leverage TypeScript strict mode features
Applied to files:
examples/lambda-api-gateway-streaming/tsconfig.json
📚 Learning: 2025-06-09T14:01:20.033Z
Learnt from: juliusmarminge
Repo: trpc/trpc PR: 6789
File: packages/tanstack-react-query/tsdown.config.ts:1-24
Timestamp: 2025-06-09T14:01:20.033Z
Learning: In the tRPC monorepo, packages/tests and packages/upgrade don't need main/module/types fields in their package.json because tests is not distributed and upgrade just exposes a binary.
Applied to files:
examples/lambda-api-gateway-streaming/tsconfig.jsonexamples/lambda-api-gateway-streaming/package.json
📚 Learning: 2025-09-05T16:48:06.982Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-09-05T16:48:06.982Z
Learning: Share common functionality through `trpc/server` and keep client/server concerns separate
Applied to files:
examples/lambda-api-gateway-streaming/README.mdexamples/lambda-api-gateway-streaming/serverless.ymlexamples/lambda-api-gateway-streaming/src/client.tsexamples/lambda-api-gateway-streaming/src/server.tspackages/server/src/adapters/aws-lambda/index.ts
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Use `ctx.useTRPCClient()` for direct (vanilla) tRPC client access in tests
Applied to files:
examples/lambda-api-gateway-streaming/src/client.tsexamples/lambda-api-gateway-streaming/src/server.ts
📚 Learning: 2025-09-05T15:16:48.745Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-09-05T15:16:48.745Z
Learning: Applies to **/*.test.ts : Use `ctx.client` from the test resource for making tRPC calls
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:48.745Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-09-05T15:16:48.745Z
Learning: Applies to **/*.test.ts : Import `testServerAndClientResource` from `trpc/client/__tests__/testClientResource`
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Create the tRPC React client with createTRPCReact<typeof appRouter>()
Applied to files:
examples/lambda-api-gateway-streaming/src/client.tsexamples/lambda-api-gateway-streaming/src/server.ts
📚 Learning: 2025-09-05T15:16:48.745Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-09-05T15:16:48.745Z
Learning: Applies to **/*.test.ts : Configure client options via the `client` callback in `testServerAndClientResource` options
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Import getUntypedClient from 'trpc/client' when an untyped client is needed
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:17:32.520Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/upgrade-tests.mdc:0-0
Timestamp: 2025-09-05T15:17:32.520Z
Learning: Applies to packages/upgrade/**/*.{test,spec,trpc,snap}.tsx : Import both 'trpc/react-query' as rq (legacy) and 'trpc/tanstack-react-query' as trq (modern) when writing migration tests
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-06-29T21:21:07.306Z
Learnt from: heitorlisboa
Repo: trpc/trpc PR: 6849
File: examples/minimal-react-typesafe-errors/client/src/Users.tsx:6-6
Timestamp: 2025-06-29T21:21:07.306Z
Learning: In the minimal-react-typesafe-errors example, the `trpc.user.list` query is designed to never throw errors since it's a minimal example focused on demonstrating typed error handling in mutations rather than queries.
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Import createTRPCReact from 'trpc/react-query' (legacy API)
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : If not using createAppRouter, you may create an inline router using testServerAndClientResource with appropriate server and client link configuration
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Wrap components with a custom App that provides trpc.Provider (legacy) and QueryClientProvider
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Use `ctx.useTRPC()` for TanStack React Query hooks access in components under test
Applied to files:
examples/lambda-api-gateway-streaming/src/client.tsexamples/lambda-api-gateway-streaming/src/server.ts
📚 Learning: 2025-04-07T05:50:41.797Z
Learnt from: zirkelc
Repo: trpc/trpc PR: 6680
File: packages/server/src/adapters/aws-lambda/index.ts:89-124
Timestamp: 2025-04-07T05:50:41.797Z
Learning: In AWS Lambda, the `awslambda` namespace is provided globally by the runtime environment and doesn't require an import statement. It contains utilities for response streaming such as `streamifyResponse` and `HttpResponseStream.from`.
Applied to files:
examples/lambda-api-gateway-streaming/src/server.tspackages/server/src/adapters/aws-lambda/index.tswww/docs/server/adapters/aws-lambda.md
🧬 Code graph analysis (2)
examples/lambda-api-gateway-streaming/src/client.ts (3)
examples/lambda-api-gateway-streaming/src/server.ts (1)
AppRouter(48-48)packages/client/src/links/loggerLink.ts (1)
loggerLink(214-268)packages/client/src/links/httpBatchStreamLink.ts (1)
httpBatchStreamLink(23-186)
packages/server/src/adapters/aws-lambda/index.ts (1)
packages/server/src/adapters/aws-lambda/getPlanner.ts (1)
LambdaEvent(11-11)
🪛 GitHub Actions: autofix.ci
examples/lambda-api-gateway-streaming/package.json
[error] 1-1: Lockfile specifiers do not match package.json: lockfile has {"@trpc/client":"workspace:","@trpc/server":"workspace:","tsx":"^4.19.3","zod":"^3.25.51","@types/aws-lambda":"^8.10.149","@types/node":"^22.13.5","esbuild":"^0.17.10","eslint":"^9.26.0","serverless":"^4.28.0","serverless-esbuild":"^1.55.0","typescript":"^5.9.2"} while package.json requires {"@types/aws-lambda":"^8.10.149","@types/node":"^22.13.5","esbuild":"^0.17.10","eslint":"^9.26.0","serverless":"^3.38.0","serverless-esbuild":"^1.55.0","typescript":"^5.9.2","@trpc/client":"workspace:","@trpc/server":"workspace:","tsx":"^4.19.3","zod":"^3.25.51"}.
🪛 GitHub Actions: main
examples/lambda-api-gateway-streaming/package.json
[error] 1-1: pnpm install failed: ERR_PNPM_OUTDATED_LOCKFILE Cannot install with 'frozen-lockfile' because pnpm-lock.yaml is not up to date with the package.json. Use 'pnpm install --no-frozen-lockfile' to update the lockfile.
🪛 LanguageTool
examples/lambda-api-gateway-streaming/README.md
[style] ~12-~12: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...npm install pnpm build pnpm deploy ``` This will deploy the Lambda function and API...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.18.1)
www/docs/server/adapters/aws-lambda.md
129-129: Multiple headings with the same content
(MD024, no-duplicate-heading)
🔇 Additional comments (12)
packages/server/src/adapters/aws-lambda/index.ts (2)
10-10: LGTM! Clean import update.The removal of
APIGatewayProxyEventV2from direct imports and addition ofStreamifyHandlerproperly reflects the expanded streaming support for both payload format versions.
86-114: LGTM! Streaming handler now supports both v1 and v2 payload formats.The generic constraint change from
APIGatewayProxyEventV2toLambdaEventcorrectly enables streaming for both REST API (v1) and HTTP API (v2), fulfilling the PR objective. The implementation maintains consistency withawsLambdaRequestHandler.www/docs/server/adapters/aws-lambda.md (2)
125-127: LGTM! Documentation accurately reflects the new streaming capabilities.The updated description correctly explains that streaming is now supported for both Lambda Function URLs and API Gateway REST APIs, with proper guidance on the
responseTransferMode: STREAMconfiguration requirement.
33-40: LGTM! Example links added for the new streaming example.The new example rows are properly formatted and link to the correct example directory for API Gateway REST API streaming.
Also applies to: 147-154
packages/server/src/adapters/aws-lambda/getPlanner.ts (3)
44-44: LGTM! MakingtoStreamrequired aligns with universal streaming support.This interface change correctly reflects that all processors now must implement streaming, supporting both v1 and v2 payload formats.
99-118: LGTM! Headers processing correctly prioritizes multiValueHeaders.The refactored logic properly processes
multiValueHeadersfirst (which can have multiple values per header) and then adds single-value headers only if not already present. This follows AWS API Gateway behavior wheremultiValueHeaderstakes precedence.
145-145: Consider using a more specific type assertion or verify if a newer@types/nodeversion resolves this typing incompatibility.The
as anycast works around a known TypeScript typing difference betweenReadableStream<Uint8Array>(from the Fetch API) andReadable.fromWeb. While this workaround is functional, the coding guidelines prefer explicit typing overany. Consider checking if a newer@types/nodeversion has resolved this issue, or alternatively, use a more specific type assertion (e.g.,as unknown as ReadableStream<any>) to avoid the blanketanytype. Both occurrences (lines 145 and 210) use this same pattern.examples/lambda-api-gateway-streaming/.gitignore (1)
1-1: LGTM!The
.serverlessdirectory exclusion is appropriate for Serverless Framework deployments.examples/lambda-api-gateway-streaming/README.md (1)
1-27: LGTM!The documentation clearly explains the streaming setup, deployment steps, and usage. The AWS blog post reference provides helpful context.
examples/lambda-api-gateway-streaming/src/client.ts (1)
1-38: LGTM!The client correctly demonstrates tRPC streaming with:
- Proper type-only import for
AppRouterhttpBatchStreamLinkfor streaming supportloggerLinkfor debugging- Good examples of query, parallel deferred calls, and async iteration
- Appropriate error handling
The placeholder URL on line 14 is expected per the README instructions.
examples/lambda-api-gateway-streaming/src/server.ts (1)
19-55: LGTM!The server implementation correctly demonstrates tRPC streaming:
- Proper context creation with event and headers
- Good streaming examples (async generator in
iterable, deferred responses)- Correct use of
awslambda.streamifyResponsewrapper- Type export for client usage
Note: The
awslambdaglobal is provided by the Lambda runtime and doesn't require an import. Based on learnings, this is the expected usage pattern.examples/lambda-api-gateway-streaming/serverless.yml (1)
9-17: LGTM on streaming configuration!The HTTP event configuration correctly enables response streaming with
transferMode: STREAM, which is essential for API Gateway REST API streaming support. The/{proxy+}path withanymethod allows tRPC to handle all routes.
@trpc/client
@trpc/next
@trpc/react-query
@trpc/server
@trpc/tanstack-react-query
@trpc/upgrade
commit: |
|
I hadn't realised that API Gateway finally got streaming support! We'll be very keen to land this one, just shout when it's done 😃 |
@Nick-Lucas it's ready! :) |
Nick-Lucas
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! I just pushed a small tweak to the example as I had a little confusion (my AWS is rusty) but it works!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
examples/lambda-api-gateway-streaming/README.md (1)
1-5: Clarify “REST API (payload v1)” vs “HTTP API (payload v2)” to prevent deployment confusion.
Given tRPC historically supported streaming on payload v2, it’d help to explicitly call out here that this example targets API Gateway REST API (payload format v1).Also applies to: 13-13
examples/lambda-api-gateway-streaming/src/client.ts (2)
13-16: Prefer configuring the URL via env var (and fail fast if unset) instead of a hard-coded placeholder.
Reduces accidental misconfig and makes the example easier to run in CI/docs tooling.- httpBatchStreamLink({ - // Insert your API Gateway URL after deploying the serverless app - url: 'https://???????.execute-api.us-east-1.amazonaws.com/dev', - }), + httpBatchStreamLink({ + url: + process.env.TRPC_API_URL ?? + (() => { + throw new Error('Missing TRPC_API_URL'); + })(), + }),
20-39: Catch block: treaterrorasunknownand log viaconsole.error(example ergonomics).
This avoids losing stack traces and keeps TS strictness-friendly patterns for users.- } catch (error) { - console.log('error', error); + } catch (error: unknown) { + console.error('error', error); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (2)
examples/lambda-api-gateway-streaming/README.md(1 hunks)examples/lambda-api-gateway-streaming/src/client.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
**/*.{ts,tsx}: Always useimport typefor type-only imports
Separate type imports from value imports
Avoid overzealous object destructuring; prefer direct property access
Object destructuring is acceptable when a variable is used 3+ times
Prefer array destructuring
Avoid sparse array destructuring
Never destructure in function parameter declarations
Avoid destructuring potentially nullish nested properties
Maximum 3 parameters per function; use options objects when more
Type parameter names must match /^(T|$)(A-Z)?[0-9]*$/
Prefix unused variables, parameters, and caught errors with_
Prefer namespace imports for validation libraries and large modules (e.g.,import * as z from 'zod',import * as React from 'react')
Follow import order: test helpers, tRPC test imports, third-party, then relative
Never import from@trpc/*/src; import from the package root instead
Do not useSymbol.disposeorSymbol.asyncDispose; usemakeResource()/makeAsyncResource()
Always useawait usingfor resource cleanup
PrefermakeResource()/makeAsyncResource()over manual disposal logic
Avoid non-null assertions (!)
Use proper type guards and optional chaining instead of non-null assertions
Switch statements must be exhaustive for union types
Rely on TypeScript inference; avoid unnecessary explicit return/output types
Use explicit types at public API boundaries, for complex generic constraints, or when inference is insufficient/ambiguous
Use thesatisfiesoperator to retain inference while enforcing shapes
Useas constfor literal type inference when appropriate
Prefer explicit typing overany
Use type assertions sparingly
Leverage TypeScript strict mode features
Files:
examples/lambda-api-gateway-streaming/src/client.ts
**/*.{ts,tsx,md,mdx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
Use camelCase for file names (with exceptions like TRPC/RPC/HTTP/JSON acronyms, .config.js, .d.ts, and tests)
Files:
examples/lambda-api-gateway-streaming/src/client.tsexamples/lambda-api-gateway-streaming/README.md
🧠 Learnings (11)
📚 Learning: 2025-09-05T15:16:48.745Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-09-05T15:16:48.745Z
Learning: Applies to **/*.test.ts : Use `ctx.client` from the test resource for making tRPC calls
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Use `ctx.useTRPCClient()` for direct (vanilla) tRPC client access in tests
Applied to files:
examples/lambda-api-gateway-streaming/src/client.tsexamples/lambda-api-gateway-streaming/README.md
📚 Learning: 2025-09-05T15:16:48.745Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-09-05T15:16:48.745Z
Learning: Applies to **/*.test.ts : Import `testServerAndClientResource` from `trpc/client/__tests__/testClientResource`
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:48.745Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-09-05T15:16:48.745Z
Learning: Applies to **/*.test.ts : Configure client options via the `client` callback in `testServerAndClientResource` options
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Create the tRPC React client with createTRPCReact<typeof appRouter>()
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T16:48:06.982Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-09-05T16:48:06.982Z
Learning: Share common functionality through `trpc/server` and keep client/server concerns separate
Applied to files:
examples/lambda-api-gateway-streaming/src/client.tsexamples/lambda-api-gateway-streaming/README.md
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Import getUntypedClient from 'trpc/client' when an untyped client is needed
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : If not using createAppRouter, you may create an inline router using testServerAndClientResource with appropriate server and client link configuration
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Import createTRPCReact from 'trpc/react-query' (legacy API)
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:01.878Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:01.878Z
Learning: Applies to packages/react-query/**/*.test.tsx : Wrap components with a custom App that provides trpc.Provider (legacy) and QueryClientProvider
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
📚 Learning: 2025-09-05T15:16:31.379Z
Learnt from: CR
Repo: trpc/trpc PR: 0
File: .cursor/rules/tanstack-react-query-tests.mdc:0-0
Timestamp: 2025-09-05T15:16:31.379Z
Learning: Applies to packages/tanstack-react-query/**/*.test.tsx : Use `ctx.useTRPC()` for TanStack React Query hooks access in components under test
Applied to files:
examples/lambda-api-gateway-streaming/src/client.ts
🧬 Code graph analysis (1)
examples/lambda-api-gateway-streaming/src/client.ts (3)
examples/lambda-api-gateway-streaming/src/server.ts (1)
AppRouter(48-48)packages/client/src/links/loggerLink.ts (1)
loggerLink(214-268)packages/client/src/links/httpBatchStreamLink.ts (1)
httpBatchStreamLink(23-186)
🪛 LanguageTool
examples/lambda-api-gateway-streaming/README.md
[style] ~12-~12: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...npm install pnpm build pnpm deploy ``` This will deploy the Lambda function and API...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Lint and auto-fix
- GitHub Check: test
- GitHub Check: typecheck
- GitHub Check: build
🔇 Additional comments (1)
examples/lambda-api-gateway-streaming/src/client.ts (1)
1-18: No changes needed.createTRPCClientis the correct public API for typed clients with links likehttpBatchStreamLink. This is the recommended approach for creating a tRPC client with type inference from a router definition (the lower-levelcreateTRPCProxyClientis an internal API). The example is correct as written.
| This will deploy the Lambda function and API Gateway REST API. The API Gateway endpoint URL will be displayed after deployment. | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor doc style: avoid repeating “This will …”. (LanguageTool hint)
Consider rephrasing Line 13 to not start with “This”.
🤖 Prompt for AI Agents
In examples/lambda-api-gateway-streaming/README.md around lines 13 to 14, the
sentence begins with a repeated "This will..." which is stylistically redundant;
rephrase the line to avoid starting with "This" (for example, use an active
phrasing like "Deploy the Lambda function and API Gateway REST API; the API
Gateway endpoint URL will be displayed after deployment." or similar) so the
sentence reads more concise and avoids repetition.
|
This pull request has been locked because we are very unlikely to see comments on closed issues. If you think, this PR is still necessary, create a new one with the same branch. Thank you. |
Closes #7038
🎯 Changes
Add streaming support for AWS API gateway Rest APIs (payload format version 1).
One of the required changes was to fix how we parse the version 1 headers from API Gateway. Previously, we duplicated the headers by processing both
headersandmultiValueHeaders. This duplication prevented streaming from working correctly because tRPC couldn't detect thetrpc-acceptheader properly. The best practice is to usemultiValueHeadersif available, then fall back toheaders, skipping any that have already been added.✅ Checklist
Summary by CodeRabbit
New Features
New Example
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.