- Notifications
You must be signed in to change notification settings - Fork4
Run Next.js, tRPC, and Prisma on AWS Lambda
License
aws-samples/trpc-nextjs-ssr-prisma-lambda
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Important
This repository is being archived. For a more modern and improved fullstack web application sample that uses Next.js App Router, please refer toserverless-full-stack-webapp-starter-kit instead.
This is a starter kit for a modern fullstack webapp on AWS. Features including:
- ✅ Next.js app with both server / client side rendering
- ✅ tRPC backend for end-to-end type safety
- ✅ Prisma to access your relational database easily
- ✅ React Hook Form with tRPC validation
- ✅ Lambda with Lambda Web Adapter for true serverless computing
- ✅ CloudFront for caching
- ✅ AWS CDK for one-click deployment
This sample deploys your Next.js application to AWS Lambda container environment. WithAWS Lambda Web Adapter, you can run the app transparently with Lambda and API Gateway pattern.
The advantage of using AWS Lambda is that it is fully serverless; you only pay when it received the actual requests. It is especially ideal for prototyping phase because you can use it with the minimal cost. At the same time, it is also ideal for production workload because it scales out in a few seconds according to the amount of requests.
All of the infrastructure parts are deployed in a single command with AWS Cloud Development Kit, allowing you to try this sample effortlessly.
You need the following tools to deploy this sample:
Then run the following commands:
cd cdknpm cinpx cdk bootstrapnpx cdk deploy
Initial deployment usually takes about 20 minutes. You can also usenpx cdk deploy
command to deploy the app when you make changes to the code.
After a successful deployment, you will get a CLI output like the below:
✅ CdkStack✨ Deployment time: 940.79sOutputs:CdkStack.DatabaseBastionHostBastionHostId1600F37C = i-0xxxxxxxxxxxxxxCdkStack.DatabaseDatabaseSecretsCommandF4A622EB = aws secretsmanager get-secret-value --secret-id DatabaseClusterSecretD1FB63-xxxxxxxx --region ap-northeast-1CdkStack.DatabasePortForwardCommandC3718B89 = aws ssm start-session --region ap-northeast-1 --target i-0xxxxxxxxxxxxxx --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"portNumber":["3306"], "localPortNumber":["3306"], "host": ["cdkstack-databasecluster5b53a178-4ont9k5raja4.cluster-xxxxxxxxx.ap-northeast-1.rds.amazonaws.com"]}'CdkStack.MigrationFunctionName = CdkStack-WebAppMigrationRunner4FF0034F-wpE8B46If1umCdkStack.WebAppCloudFrontUrlBAD6B277 = https://xxxxxxxxxxxx.cloudfront.netCdkStack.WebAppMigrationCommandA625F170 = aws lambda invoke --function-name CdkStack-WebAppMigrationRunner4FF0034F-wpE8B46If1um --cli-binary-format raw-in-base64-out --payload '{"command":"deploy"}' response.jsonStack ARN:arn:aws:cloudformation:ap-northeast-1:123456789012:stack/CdkStack/ecf45e70-a0a5-11ee-8ca1-0a8ebf670439
You can now try the sample app on your browser by opening the URL inCdkStack.WebAppCloudFrontUrlBAD6B277
output. Let's try to post some comments.
You can use this sample as a starter kit to develop a fullstack serverless webapp. Here are some tips to interact with this sample.
By default, a database migration is executed every time you runcdk deploy
during CloudFormation deployment.
You can disable the behavior by commenting out the below code inwebapp.ts:
+ // comment out the trigger+ /* const trigger = new Trigger(this, "MigrationTrigger", { handler: migration, }); trigger.node.addDependency(database.cluster);+ */
Instead you can run a database migration manually. This is especially ideal if you want to separate a DB migration process from application deployment.
You can invoke the migration Lambda handler by the following command (CdkStack.WebAppMigrationCommandA625F170
in the stack CLI output):
aws lambda invoke --function-name CdkStack-WebAppMigrationRunner4FF0034F-wpE8B46If1um --cli-binary-format raw-in-base64-out --payload'{"command":"deploy"}' response.json
Or you can run any SQL query from the bastion server by SSM port forwarding (CdkStack.DatabasePortForwardCommandC3718B89
):
aws ssm start-session --target i-xxxxxx --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters'{"portNumber":["3306"], "localPortNumber":["3306"], "host": ["cdkstack-databasecluster5b53a178-4ont9k5raja4.cluster-xxxxxx.ap-northeast-1.rds.amazonaws.com"]}'
The connection info for the Aurora database can be retrieved with the following command (CdkStack.DatabaseDatabaseSecretsCommandF4A622EB
):
aws secretsmanager get-secret-value --secret-id DatabaseClusterSecretD1FB63-xxxxxx --region ap-northeast-1
Then you can connect your Aurora server by any tools like Sequel Ace, or by the following command:
mysql -u admin -p [PASSWORD]
Because this sample uses a standard directory structure following tRPC official documents, you can basically followthe document to make changes to tRPC implementation.
The quick summary about where each tRPC definition example files is:
- server.ts: tRPC app router definition
- routers/**/index.ts: the definition of each child router
- common/types: the zod definition of router input, which can be referenced from both backend and frontend
- components/post.tsx: example implementation of tRPC client with React Hook Form
To save Lambda cost and increase performance, it is important to use CloudFront to deliver contents that can be cached without accessing Lambda origin.
By default caching is enabled in some path patterns. Openwebapp.ts and you can find this line:
constcachedPathPatterns=['/_next/static/*','/favicon.ico','/api/trpc/*'];
Add any path patterns you want to enable cache in CloudFront.
To actually use cache in CloudFront, you have to sendCache-Control
response header from your app. See this document for more details:Managing how long content stays in the cache (expiration).
Files in_next/static
path should have appropriateCache-Control
headers by default.
For tRPC paths, you can setCache-Control
header in[trpc].ts
selectively for each path.
For Next.js public files, you can setCache-Control
header innext.config.js
for each file.
To avoid incurring future charges, clean up the resources when you no longer need them.
You can remove the AWS resources deployed by this sample running the following command:
cd cdknpx cdk destroy --force
SeeCONTRIBUTING for more information.
This library is licensed under the MIT-0 License. See the LICENSE file.
About
Run Next.js, tRPC, and Prisma on AWS Lambda
Topics
Resources
License
Code of conduct
Security policy
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.
Contributors4
Uh oh!
There was an error while loading.Please reload this page.