{"id":19369408,"url":"https://github.com/bdombro/aws-serverless-fullstack","last_synced_at":"2026-07-18T13:32:15.179Z","repository":{"id":95354733,"uuid":"359018060","full_name":"bdombro/aws-serverless-fullstack","owner":"bdombro","description":"A template to create a low-management, autoscaling NodeJS api + database on AWS.","archived":false,"fork":false,"pushed_at":"2021-05-04T17:50:10.000Z","size":353,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-06-25T19:27:31.677Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bdombro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-18T01:24:19.000Z","updated_at":"2021-09-16T00:57:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"fbf8fc4c-ba66-4d27-9f74-28c3850f7bdf","html_url":"https://github.com/bdombro/aws-serverless-fullstack","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/bdombro/aws-serverless-fullstack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdombro%2Faws-serverless-fullstack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdombro%2Faws-serverless-fullstack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdombro%2Faws-serverless-fullstack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdombro%2Faws-serverless-fullstack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bdombro","download_url":"https://codeload.github.com/bdombro/aws-serverless-fullstack/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdombro%2Faws-serverless-fullstack/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35619777,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-18T02:00:07.223Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T08:11:00.865Z","updated_at":"2026-07-18T13:32:15.151Z","avatar_url":"https://github.com/bdombro.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1\u003e ☠️ AWS-SERVERLESS-FULLSTACK ☠️\u003c/h1\u003e\n\n...is a template to create a low-management, autoscaling NodeJS api + database on AWS\n\nWhat makes it cool:\n\n1. 100% serverless full-stack with Static frontend, NodeJS api and MySQL db\n1. Easy deploy management with AWS SAM + Cloudformation\n1. Run locally, AWS, or anywhere with generic file and db connectors\n1. All Javascript/Typescript\n1. Uses Fastify framework, which is mucho faster than Express\n2. DB ORM and schema management via Typeorm\n3. Type-strict\n\n\u003ch2\u003e Table of Contents 🌍\u003c/h2\u003e\n\n- [Running locally 🏎](#running-locally-)\n- [API ☁](#api-)\n- [DB Schema Management 🗂](#db-schema-management-)\n- [Deploying to AWS as Cloudformation Stack 🏁](#deploying-to-aws-as-cloudformation-stack-)\n- [Known Issues 🐞](#known-issues-)\n- [References and Special Thanks 😘](#references-and-special-thanks-)\n\n## Running locally 🏎\n\nTo run locally, ensure you have docker running and node v14.\n\n```bash\nnpm i\nnpm run db # Start the database in Docker as a daemon\nnpm run dev # Start the API on https://0.0.0.0:3000\n```\n\n## API ☁\n\n\u003ch4\u003eGET /\u003c/h4\u003e\n\nServes static website in src/html\n\n```bash\ncurl https://0.0.0.0:3000\n```\n\n\u003ch4\u003eGET /api/dbtime\u003c/h4\u003e\n\nGets the current time from DB\n\n```bash\ncurl https://0.0.0.0:3000/api/dbtime\n```\n\n\u003ch4\u003ePOST /files/:id\u003c/h4\u003e\n\nUploads a file\n\n```bash\ncurl -X POST https://0.0.0.0:3000/files/1234 --form file=@image.jpg\n```\n\n\u003ch4\u003eGET /files/:id\u003c/h4\u003e\n\nReturns a file\n\n```bash\ncurl https://0.0.0.0:3000/files/1234\n```\n\n\u003ch4\u003eGET /files/:id/meta\u003c/h4\u003e\n\nReturns a file's metadata\n\n```bash\ncurl https://0.0.0.0:3000/files/1234/meta -H 'accept: application/json'\n```\n\n\u003ch4\u003ePOST /api/users\u003c/h4\u003e\n\nCreates a user\n\n```bash\ncurl -X POST \\\n  --url https://0.0.0.0:3000/api/users \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n\t\t\"email\": \"editor3@example.com\",\n\t\t\"roles\": [1],\n\t\t\"givenName\": \"Sally\",\n\t\t\"surname\": \"Editor\",\n\t\t\"password\": \"Yousuck8\"\n\t}'\n```\n\n\u003ch4\u003eGET /api/users\u003c/h4\u003e\n\nGets users\n\n```bash\ncurl https://0.0.0.0:3000/api/users\n```\n\n## DB Schema Management 🗂\n\nYou needs in the database change over time, and it's crazy error-prone to do it manually. Have you ever added a column to a dev environment just to forget to add it to production? This can easily take down your whole app. There must be a better way, right? Yes, thanks to \"migration\" tooling.\n\n\u003e A migration is just a single file with sql queries to update a database schema and apply new changes to an existing database.\n\nAnother part challenge/frustration for developers is avoiding mistakes when accessing the database. Instead of manually updating every SQL query string that may reference the column you just changes, wouldn't it be nice if your tooling did that automatically? That's where Object-Relational-Mappers (ORMs) help. ORMs allow your code to access the database without writing SQL strings.\n\n\u003e ORMs provide abstracted interfaces to the database, which allow you to describe the database schema in one place and have it apply globally.\n\n|_Object_| A table in the database|\n|_Relational_| A relationship between tables (i.e. Users have Blog Posts))|\n|_Mapping_| Glue code that translates (aka _maps_) coding features to SQL query strings based on configuration (aka _model_)|\n\nFor example, this snippet models a user table, gets a user object from the database, update a column, then save it.\n\n```typescript\n@Entity()\nexport default class UserEntity extends BaseEntity {\n\t@PrimaryColumn('varchar', {length: 30})\n\tid: string\n\n\t@Column('varchar', {unique: true, length: 30}) \n\temail: string\n\n\t@Column('varchar', {length: 30}) \n\tname: string\n}\n\nconst user = await UserEntity.findOne({ where: { email: 'foo@bar.com' } })\nuser.name = 'Shirley'\nawait user.save()\n```\n\nThat code actually works, too! It and this project use an ORM called [TypeORM](typeorm.io). Additionally, TypeORM provides type-safety and schema migration tooling (!!!).\n\nThanks to TypeORM's Typescript features, `user.phone = '+1222222222'` will throw an error, because there is no phoneNumber field in the model.\n\n\u003e But whatabout migrations???\n\nTypeORM has two workflows for database schema management: `synchronize` and `migration`.\n\n|_synchronize_|TypeORM will immediately and greedily generate and apply SQL migrations on the fly. So if you changed the name of column in your code, TypeORM will drop the old column and create a new one, destroying any data that was in the old column.|\n|_migration_|You manage the migrations in code, and they are ran automatically.|\n\nThe `synchronize` mode is more convenient, but is obviously too dangerous for a published application. Therefore, this application uses `synchronize` for local development and `migration` for production. __It's up to you as a developer to ensure that you create and test the needed migration files before you deploy(!)__. Luckily for you, TypeORM can to generate migration files for you, and these are usually good-enough.\n\nTo generate a migration file for what's currently in code vs. database:\n```bash\nnpm run typeorm:migration-gen -- NameOfSnapshot\n```\n\n## Deploying to AWS as Cloudformation Stack 🏁\n\nDeploy assumes you have already\n- [set up an AWS account](http://docs.aws.amazon.com/AmazonSimpleDB/latest/DeveloperGuide/AboutAWSAccounts.html)\n- have the latest version of the [AWS CLI](https://aws.amazon.com/cli/) installed\n- have the latest version of the [SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) installed\n\n1. Update the `samconfig.toml` file with your choices\n1. Run `npm i` - this installs the node dependencies\n1. Deploy to AWS using `sam build \u0026\u0026 sam deploy`\n1. View your stacks online at [CloudFormation](https://console.aws.amazon.com/cloudformation/home), or open your API at the URL from the deploy output.\n\nTo delete your stack, run:\n```bash\naws cloudformation delete-stack --stack-name (name of your stack) --region us-east-1\n```\n\nIf your stack is tied to CloudFront, you can bust CloudFront caches by:\n```bash\naws cloudfront list-distributions | grep Id\naws cloudfront create-invalidation --distribution-id \u003cid\u003e --paths \"/static/*\"\n```\n\n\u003ch4\u003eConnecting to a custom domain\u003c/h4\u003e\n\n1. If you haven't, [create an ACM certificate for your domain](https://us-east-1.console.aws.amazon.com/acm/home?region=us-east-1#/). Even if your domain isn't in Route53, it's easy. You'll just need to add a DNS TXT record to your domain to confirm your ownership.\n1. Add your custom domain to [API Gateway](https://us-east-1.console.aws.amazon.com/apigateway/main/publish/domain-names) and connect it to your lambda\n1. Create a CloudFront app with your custom domain name that pulls from your API Gateway. CloudFront basically acts as a reverse proxy with caching.\n\n## Known Issues 🐞\n\nWhen configured to sleep, API calls may timeout (28s) before the database finishes waking up. To tolerate this, the web application needs to retry API calls that fail due to database failures. Here is the expected `503` response from the API on failure:\n\n```json\n{\"message\":\"Service Unavailable\"}\n```\n\n\n## References and Special Thanks 😘\n\n- [Typeorm 3rd Party Docs](https://orkhan.gitbook.io/typeorm/)\n- https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html\n- https://github.com/vendia/serverless-express\n- https://github.com/claudiajs/claudia\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbdombro%2Faws-serverless-fullstack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbdombro%2Faws-serverless-fullstack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbdombro%2Faws-serverless-fullstack/lists"}