A Node.js REST API backed by PostgreSQL and Redis. Designed as the application layer for the BeyondSquare DevOps case study — the business logic is intentionally minimal so the infrastructure patterns are the focus.
| Method | Path | Description | Dependencies |
|---|---|---|---|
GET |
/health |
Liveness check — returns 200 if the process is running |
None |
GET |
/ready |
Readiness check — verifies PostgreSQL and Redis connectivity | PostgreSQL, Redis |
GET |
/items |
List all items from the database | PostgreSQL |
POST |
/items |
Create a new item | PostgreSQL |
GET |
/items/:id |
Get a single item by ID | PostgreSQL |
DELETE |
/items/:id |
Delete an item by ID | PostgreSQL |
# Liveness
curl http://localhost:3000/health
# {"status":"alive"}
# Readiness (both dependencies healthy)
curl http://localhost:3000/ready
# {"status":"ready","checks":{"postgres":true,"redis":true}}
# Readiness (PostgreSQL unavailable)
# {"status":"not ready","checks":{"postgres":false,"redis":true}}
# → HTTP 503
# List items
curl http://localhost:3000/items
# [{"id":1,"name":"example","created_at":"2026-08-24T..."}]| Variable | Required | Default | Description |
|---|---|---|---|
PORT |
No | 3000 |
Port the server listens on |
DATABASE_URL |
Yes | — | PostgreSQL connection string, e.g. postgresql://user:pass@postgres:5432/beyondsquare |
REDIS_URL |
Yes | — | Redis connection string, e.g. redis://redis:6379 |
NODE_ENV |
No | development |
Set to production in the AWS overlay |
In Kubernetes, non-secret values are injected via ConfigMap (k8s/base/configmap.yaml) and secrets via Secret (k8s/base/secret.yaml).
Docker Compose (simplest):
# From repo root
docker compose up
# API available at http://localhost:3000kind (local Kubernetes):
kind create cluster --config kind-config.yaml
kubectl apply -k k8s/base
kubectl port-forward svc/beyondsquare-api 3000:80
curl http://localhost:3000/healthStandalone (Node.js directly):
cd app
npm install
# Set env vars or create a .env file
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/beyondsquare \
REDIS_URL=redis://localhost:6379 \
node index.jsThe API initializes the schema on startup (up to 5 retries with backoff). Schema:
CREATE TABLE IF NOT EXISTS items (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);No migration framework is used — the schema init is idempotent (CREATE TABLE IF NOT EXISTS). For a production system, use a migration tool (Flyway, Liquibase, node-pg-migrate).
Built from app/Dockerfile. The image is pushed to ECR as beyondsquare-api and tagged with the Git commit SHA by the GitHub Actions deploy workflow.
# Build locally
docker build -t beyondsquare-api:local ./app
# Run against local Compose stack
docker run --rm \
--network beyondsquare_default \
-e DATABASE_URL=postgresql://postgres:postgres@postgres:5432/beyondsquare \
-e REDIS_URL=redis://redis:6379 \
-p 3000:3000 \
beyondsquare-api:local