quote-of-the-day-api-docs/architecture/tad.md

5.9 KiB

Tech Architecture Document

Stack

Layer Technology Version / Notes
Runtime Node.js LTS ≥ 20
Language TypeScript Strict mode; compiled to ES2020+; output to dist/
Framework Express.js v4 or v5
Validation Inline guard functions (or lightweight library such as zod) Applied in route handlers before touching the store
Testing Jest + ts-jest or Vitest Runnable via npm test
Linting ESLint (TypeScript-aware ruleset) Runnable via npm run lint
Build tooling tsc (TypeScript compiler) tsconfig.json with strict: true
Package manager npm Standard package.json / package-lock.json

Components

graph TD
    Client["HTTP Client\n(browser / CLI / app)"]

    subgraph "Express Application"
        Router["Express Router\n(routes/quotes.ts)"]
        HealthRoute["Health Route\nGET /health"]
        Validator["Input Validator\n(validation.ts)"]
        Store["Quote Store\n(store.ts)"]
        ErrorHandler["Global Error Handler\n(middleware/error.ts)"]
    end

    Client -- "HTTP request" --> Router
    Router --> HealthRoute
    Router --> Validator
    Validator -- "valid" --> Store
    Validator -- "invalid → 400" --> Client
    Store -- "quote data" --> Router
    Router -- "JSON response" --> Client
    ErrorHandler -- "500 response" --> Client

Component descriptions

Component Responsibility
server.ts Entry point. Creates the Express app, registers middleware (JSON body parser, routes, error handler), and starts the HTTP listener on process.env.PORT || 3000.
routes/quotes.ts Defines all four REST routes (GET /health, GET /quote, GET /quotes, POST /quotes). Delegates to the validator and store; formats JSON responses.
store.ts In-memory quote repository. Exports getAll(), getRandom(), and add(quote). Initialised at module load with five seed quotes. This is the unit-tested module.
validation.ts Pure functions that inspect request bodies and return either a typed Quote object or a descriptive error string. No side effects.
middleware/error.ts Express error-handling middleware (four-argument signature). Catches any unhandled error, logs it server-side, and returns { error: "Internal server error" } with HTTP 500 — never leaking stack traces.

Data Model

The single domain object used throughout the service:

Quote {
  text   : string   // non-empty; the body of the quote
  author : string   // non-empty; attribution
}

The in-memory store holds an array of Quote objects (Quote[]). There is no stable ID field in v1; if DELETE/PUT endpoints are added in a later phase an auto-incremented numeric index or UUID should be introduced.

Seed data — five Quote objects are hard-coded in store.ts and loaded at process startup. No migration, seeding script, or external database is required.


Integrations

There are no external integrations in this version of the service. All data is held in process memory.

Integration point Status
Database / cache Out of scope (NFR-9)
External quote APIs Out of scope
Authentication / identity provider Out of scope (Assumption 3)
Message broker / event bus Out of scope

The GET /health endpoint is designed to integrate with load-balancer liveness probes and monitoring systems (e.g. AWS ALB health checks, Kubernetes liveness probes, UptimeRobot) without any additional configuration.


Non-Functional Requirements (Architectural Implications)

Ref Requirement Architectural decision
NFR-1 TypeScript strict mode, Node.js ≥ 20 tsconfig.json with "strict": true, "target": "ES2020"; CI/CD should pin the Node version via .nvmrc or engines in package.json.
NFR-2 Express.js v4 or v5 Single dependency; middleware chain provides natural extension points for future auth or rate-limit layers.
NFR-3 Input validation; 400 with error field Validation extracted to validation.ts (pure, testable); route handlers call it before mutating the store.
NFR-4 application/json responses express.json() middleware for request parsing; all route handlers call res.json(...).
NFR-5 HTTP 500 without stack leaks Centralised error-handling middleware catches everything; console.error on the server, sanitised body to the client.
NFR-6 Unit tests via npm test store.ts and validation.ts are pure modules with no Express dependency — easy to unit-test in isolation.
NFR-7 npm run lint exits cleanly ESLint configured with @typescript-eslint rules; no warnings allowed on the committed codebase.
NFR-8 Cold-start ≤ 3 s In-memory store eliminates DB connection overhead; Express startup is sub-second on any modern hardware.
NFR-9 No persistence required Intentional; simplifies the architecture and removes infrastructure dependencies for this phase.

Risks

# Risk Likelihood Impact Mitigation
R-1 Data loss on restart Certain (by design) Low for this phase Accepted per Assumption 1; documented clearly so consumers are not surprised.
R-2 Memory growth under heavy POST /quotes load Low (dev/demo context) Low Array growth is unbounded; if the service is ever exposed publicly, add a maximum-store-size guard or migrate to a persistent store.
R-3 No authentication — open write access Medium if publicly deployed Medium Acceptable for a development/demo service per Assumption 3; must be addressed before any production exposure.
R-4 Single process — no fault isolation Low Low In-scope by design (Assumption 2); the global error handler prevents a single bad request from crashing the process.
R-5 TypeScript / Express version drift Low Low Pin exact versions in package.json; run npm audit in CI.