Skip to content

Repository files navigation

serverless-fullstack-aws

A serverless fullstack notes application built with SST (Serverless Stack v1) on AWS. Users can sign up, create and manage personal notes with file attachments, and pay for a subscription via Stripe — all on a fully serverless backend.

This is a portfolio / learning project from 2022, built to exercise SST and the surrounding AWS serverless stack end-to-end (infra-as-code, auth, API, storage, frontend hosting, CI/CD). It is intentionally preserved at the SST v1 era — SST v2 and Ion (Pulumi-based) came later and would be the choice for greenfield work today.

Seed Status


What it does

  • Email-based sign-up / sign-in via Cognito User Pool
  • Authenticated REST API for CRUD on notes (one DynamoDB table, per-user partition)
  • Per-user private S3 prefix for note attachments, scoped via Cognito Identity Pool IAM policy
  • Stripe-backed billing endpoint for paid features
  • React SPA hosted on CloudFront + S3, wired to the API via AWS Amplify

Tech stack

Layer Choice
IaC SST v1 (@serverless-stack/resources 1.2) on top of AWS CDK 2.24
Compute AWS Lambda (Node.js 16, ESM bundle)
API API Gateway HTTP API with IAM authorizer
Auth Amazon Cognito (User Pool + Identity Pool)
Data DynamoDB (single-table, composite key userId + noteId)
Files S3 with per-user CORS-enabled bucket
Frontend React 18, React Router 6, React-Bootstrap, AWS Amplify, Stripe Elements
CI/CD Seed (seed.yml)
Region eu-central-1 (Frankfurt)

Architecture

                 +---------------------------+
                 |   React SPA (S3 + CDN)    |
                 |   AWS Amplify client      |
                 +-----+---------------+-----+
                       |               |
              Cognito sign-in     SigV4-signed fetch
                       |               |
                 +-----v-----+   +-----v---------------+
                 |  Cognito  |   |  API Gateway (IAM)  |
                 |  User +   |   |  /notes  /billing   |
                 |  Identity |   +-----+---------------+
                 |  Pools    |         |
                 +-----+-----+         v
                       |        +------+------+    +-----------+
                       +------->| Lambdas     |--->| DynamoDB  |
                       IAM      | (Node 16)   |    | NotesTable|
                       scoped   +------+------+    +-----------+
                       to S3           |
                       prefix          v
                                +------+------+
                                |  Stripe API |
                                +-------------+

                       +-----------------+
                       | S3 Uploads      |
                       | private/{sub}/* |
                       +-----------------+

Four SST stacks compose the app:

  • StorageStack — DynamoDB NotesTable and S3 Uploads bucket
  • ApiStack — HTTP API with six routes, IAM-authorized, Lambdas with DynamoDB + Stripe env wired in
  • AuthStack — Cognito User Pool + Identity Pool; authenticated users get IAM permission to call the API and read/write only their own S3 prefix (private/${cognito-identity.amazonaws.com:sub}/*)
  • FrontendStackReactStaticSite construct; injects API URL, region, bucket and Cognito IDs into the React build env

API

Method Path Handler
POST /notes backend/functions/create.js
GET /notes backend/functions/list.js
GET /notes/{id} backend/functions/get.js
PUT /notes/{id} backend/functions/update.js
DELETE /notes/{id} backend/functions/delete.js
POST /billing backend/functions/billing.js

All routes use the iam authorizer; the React client signs requests through Amplify using temporary credentials from the Cognito Identity Pool.

Running locally

Requires Node 16, an AWS account, and AWS credentials in your environment.

# install
npm install
npm install --prefix frontend

# live Lambda dev (SST Live Lambda Dev)
npm start

# in a second terminal, run the React app against the dev stack
npm start --prefix frontend

Set STRIPE_SECRET_KEY in your environment before deploying if you want /billing to work.

Deploying

npm run deploy           # deploys stage "production" to eu-central-1
npm run remove           # tears the stack down

Seed (seed.yml) runs npm install in frontend/ before each build and deploys on push.

Status and caveats

  • Built mid-2022 against SST v1 (@serverless-stack/cli@1.2) and AWS CDK 2.24. Both have moved on — SST v2 and SST Ion changed the construct API meaningfully.
  • Node 16 Lambda runtime is now deprecated by AWS; a current re-deploy would need bumping to Node 20+ and updating dependencies.
  • Originally followed the structure of the SST Guide notes-app tutorial, then extended with Stripe billing, per-user S3 scoping and the multi-stack split above.
  • Kept public as a reference of how a small SST v1 fullstack app fits together end-to-end.

Repo layout

stacks/        SST/CDK stack definitions (Storage, Api, Auth, Frontend)
backend/       Lambda handlers + utils, vitest tests
frontend/      React SPA (CRA, Amplify, Bootstrap)
seed.yml       Seed CI build config
sst.json       SST app config (name, region, entry)

Author

Vasilii (Basil) Pozdeev — Senior Cloud Architect / DevOps freelancer, Breda, NL. Focus: Kubernetes, AWS, Azure, platform engineering and serverless.

About

Building a fullstack app using SST tangled with a bunch of AWS services (lambda, api gateway, cognito etc..)

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages