Skip to content

Latest commit

 

History

History
156 lines (103 loc) · 6.26 KB

File metadata and controls

156 lines (103 loc) · 6.26 KB

Sample AWS Books API

CRUD API for books backed by MongoDB, with Jest tests, ESLint, and GitHub Actions. Companion code for Building Serverless Node.js Apps on AWS (Cloud Bytes Collection). Canonical copy: this folder inside the serverless-nodejs-dev monorepo — there is no separate Book API tree elsewhere.

Chapter 2 starter: sample-aws-book-api-starter.

Prerequisites

  • Node.js 22+ (see .nvmrc)
  • MongoDB for local runs (Docker recommended)

Setup

nvm use
npm ci

Copy environment defaults (required for LocalStack vars; DB_URL also has a localhost default in serverless.yml):

cp .env.example .env
# after npm run localstack:setup, merge the printed BOOK_EVENTS_TOPIC_ARN lines into .env

Start MongoDB (and optional LocalStack for SNS emulation):

docker compose up -d mongo
# optional, for Chapter 5 local SNS publish:
docker compose up -d localstack
npm run localstack:setup   # prints BOOK_EVENTS_TOPIC_ARN for your .env

Copy .env.example to .env and fill in values from localstack:setup when using LocalStack.

Local API (Serverless Offline)

npm start

Base URL: http://localhost:3000/dev

Method Path
POST /api/books/createBook
GET /api/books/getBook?id=... or ?isbn=...
PUT /api/books/updateBook
DELETE /api/books/deleteBook?id=...

A Postman collection is in misc/Books API.postman_collection.json.

Scheduled daily stats (Chapter 4)

With MongoDB running and DB_URL set:

npm run stats:local

This invokes dailyStats locally (cron(0 6 * * ? *) in AWS). Confirm a new document in the stats collection.

Notifications (Chapter 5)

Local (until deploy): LocalStack + manual notify invoke

LocalStack emulates SNS on port 4566. It does not automatically run notifyNewBook when you publish — that wiring exists only in AWS after deploy. The sample notifies subscribers by logging structured lines (easy to verify in the terminal or CloudWatch). Use this flow locally:

  1. Start stack and configure .env

    docker compose up -d mongo localstack
    npm run localstack:setup
    # copy the printed lines into .env (AWS_ENDPOINT_URL, BOOK_EVENTS_TOPIC_ARN, etc.)
    cp .env.example .env   # if you have not already
  2. SNS publish on create — with .env loaded, npm start and POST /api/books/createBook publishes to LocalStack SNS (confirm with AWS CLI against http://localhost:4566 if you like).

  3. Run the notification handler — add a subscriber in MongoDB (subscribers collection), e.g. { "email": "reader@example.com", "active": true }, then:

    npm run notify:local

    This invokes notifyNewBook with misc/sample-sns-book-created.json. Look for [notifyNewBook] JSON lines in the output.

SNS publish is skipped when BOOK_EVENTS_TOPIC_ARN is unset; CRUD still works.

Or run the full check: npm run verify:local (with npm start in another terminal).

AWS (deploy)

Deploy, add a subscriber, create a book — SNS triggers notifyNewBook automatically. Use sls logs -f notifyNewBook to see the same log lines in CloudWatch.

To send real email later, extend services/notify-subscribers.js (SES, Discord webhooks, etc.) without changing the SNS handler.

Before sls deploy to AWS: comment out or remove AWS_ENDPOINT_URL (and LocalStack keys) from .env so deployed Lambdas do not point at localhost:4566.

Generative AI (Chapter 9)

Two Bedrock patterns ship in the same project:

Pattern Function Trigger Purpose
Async enrichment enrichBook SNS book_created Generate blurb, save on book (does not slow createBook)
Sync assist suggestBlurb POST /api/books/suggestBlurb Return a preview blurb before save

Local default: SKIP_BEDROCK=true in .env returns placeholder text so Jest and verify:local work without model access. For real calls, set SKIP_BEDROCK=false and use inference profile model IDs (e.g. us.anthropic.claude-haiku-4-5-20251001-v1:0 in us-east-1 — bare anthropic.* IDs fail with an on-demand throughput error). Enable the model in the Bedrock console. Keep AWS_ENDPOINT_URL on createBook only so Bedrock does not route to LocalStack.

# with npm start running:
npm run verify:local    # includes suggestBlurb + enrichBook (uses last createBook id)
npm run enrich:local      # or BOOK_ID=<mongo-id> npm run enrich:local

Real Bedrock on your machine (uses ~/.aws or env credentials — not LocalStack test keys):

npm run verify:local          # leaves /tmp/create-book-response.json
npm run bedrock:local         # real Bedrock via invoke local (no npm start restart needed)

bedrock:local uses invoke local --real-aws (not offline HTTP), so SKIP_BEDROCK=true in a running npm start does not matter. For POST /suggestBlurb through offline, set SKIP_BEDROCK=false in .env and restart npm start.

SNS still does not auto-trigger Lambdas under offline. Deploy for full fan-out.

Tests

npm test

Tests use mockingoose and do not require a running database.

Deploy to AWS

export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY_ID"
export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_ACCESS_KEY"
export DB_URL="your-mongodb-connection-string"
npx serverless deploy -v --stage dev

Docker (optional)

The Dockerfile targets a custom base image for full-container workflows. For local development, docker compose up mongo plus npm start on the host is usually enough.

Tooling notes

  • Lambda runtime: nodejs22.x in serverless.yml
  • Serverless Framework 3.40 (no vendor login required)
  • npm overrides patch tar, uuid, and file-type in Serverless’s dependency tree (see starter README). Avoid npm audit fix --force (upgrades to v4).
  • npm audit may list 3 low aws-sdk v2 advisories with no v2 patch; use npm audit --audit-level=moderate in CI if needed.
  • npm ci may show deprecation notices from Serverless’s dependency tree; they do not block local development