fix: route lambda sub-paths via API Gateway proxy + shared dispatcher#257
Draft
nourshoreibah wants to merge 4 commits into
Draft
fix: route lambda sub-paths via API Gateway proxy + shared dispatcher#257nourshoreibah wants to merge 4 commits into
nourshoreibah wants to merge 4 commits into
Conversation
The REST API exposed only single-segment resources (/auth, /projects, ...)
with per-method integrations and no {proxy+}, so any sub-path (/auth/login,
/projects/123/members) matched no resource and API Gateway returned 403 — the
lambda never ran. Even bare paths 404'd inside the lambda because handlers were
written for the dev-server's prefix-stripped shape while API Gateway forwards
the full path. Separately, shared file: deps were never bundled into the deploy
zip (latent MODULE_NOT_FOUND).
Changes:
- infrastructure/aws/api_gateway.tf: greedy {proxy+} + ANY per lambda (forwards
full path, routes OPTIONS preflight, fixes missing PUT); deployment redeploy
trigger. Removes the per-method map.
- shared/lambda-http (@branch/lambda-http): dispatch({prefix,routes}) route-table
router with :param matching + path canonicalization (one table works behind
API Gateway's full path and the dev-server's stripped path); centralizes
json()/CORS, OPTIONS, /health, 404, 500.
- All 6 handlers converted to route tables with full prefixed patterns; business
logic preserved.
- esbuild bundling: each lambda's package script bundles handler + shared deps
into one dist/handler.js (@aws-sdk external); CI builds lambda-http. Fixes the
shared-dep packaging gap.
- lambda-cli.js emits route-table entries; openapi specs normalized to full
prefixed paths (+ fixed pre-existing donors dup key / reports YAML colon).
- next.config.ts: dev rewrites no longer strip the service prefix.
- AGENTS.md (root, backend, lambdas, infra, frontend) updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Each service Dockerfile copied + built shared/lambda-auth into /shared so its file: dep resolved; @branch/lambda-http (new runtime dep) needs the same or the container can't resolve it. Add the lambda-http copy+build to the 5 repo-root services, and switch auth's build context to the repo root (it was ./lambdas/auth, which can't see ../../../../shared) with a matching Dockerfile. Verified: docker compose build + up for auth and projects — /auth/health, /auth/login (routed, 400 not 404), /projects health/list/:id/members all 200, unknown path -> 404. Shared dev-server (npm run dev) verified separately. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Auto-formatted .tf files with terraform fmt - Updated README.md with terraform-docs Co-authored-by: nourshoreibah <nourshoreibah@users.noreply.github.com>
Contributor
Terraform Plan 📖
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The backend was unreachable through API Gateway — the root cause behind the frontend not working end-to-end (separate from the Amplify deploy PR #256).
/auth,/projects, …) with per-method integrations and no{proxy+}./auth/login,/projects/123/membersmatched no resource → API Gateway returned 403; the lambda never ran./login,/), but API Gateway forwards the full path → 404 inside the lambda.packagezipped onlydist/, so@branch/lambda-auth(afile:runtime dep) wasn't in the deploy zip → latentMODULE_NOT_FOUND.What
infrastructure/aws/api_gateway.tf— greedy{proxy+}+ANYper lambda (forwards the full path, routes OPTIONS preflight to the existing CORS handler, fixes the missing PUT). Deploymenttriggershash so route changes redeploy the stage. Removes the per-method map.shared/lambda-http(@branch/lambda-http) —dispatch(event, { prefix, routes }): a route-table router with:parammatching and path canonicalization so one table works behind API Gateway (full path) and the dev-server (stripped). Centralizesjson()/CORS, OPTIONS,/health, 404, 500.packagescript bundles the handler + shared packages + node deps into onedist/handler.js(@aws-sdk/*external, provided by node20). Fixes the packaging gap for lambda-auth too. CI (lambda-deploy,lambda-tests) buildslambda-httpfirst; the 6 Dockerfiles + compose updated likewise.tools/lambda-cli.jsemits route-table entries (notif-blocks); scaffolds dispatch-based handlers./donorskey and an unquoted-colon YAML error in reports).next.config.tsdev rewrites no longer strip the service prefix.Verification
@branch/lambda-httpbuilds; all 6 handlers typecheck and esbuild-bundle to small self-contained zips.fetch failede2e tests that need the running dev-server (CI starts it) — no logic failures.npm run dev):/projects/health200, OPTIONS 200, sub-path routed, unknown → 404 (canonical path).auth+projects+ postgres):/auth/health200,/auth/loginrouted (400, not 404),/projectshealth/list/:id/membersall 200, unknown → 404.terraform fmtclean; all 6 openapi specs parse.Notes / follow-ups
NONE; lambdas keep their own Cognito authz.🤖 Generated with Claude Code