Skip to main content

Developer

💻 APIs & Apps · FastAPI/Express · React/Next.js · SQL Server · Docker · AWS
🎯 Why this matters now

The 10‑Year Health Plan pushes Hospital → Community, Analogue → Digital, and Sickness → Prevention. Developers make this real by turning ideas into secure services, APIs, and usable interfaces for staff and patients. This path emphasises security by default, simple deploys, and reuse of existing NHS data.


👤 Role snapshot​

You turn requirements into running code — bridging NHS systems, creating internal tools, and exposing secure APIs that others can build on.

See also: FastAPI · Express.js · React · Next.js · SQL Server · Docker · AWS · VS Code · GitHub · Secrets & .env

🎯 Outcomes to target (aligned to the Plan)​

SecurityReliabilityUsabilitySpeedCost
  • Security: least‑privilege DB access, secrets outside code, audit logs
  • Reliability: health checks, structured logs, error alerts
  • Usability: fast UI, accessible components, clear error states
  • Speed: scaffold → deploy in hours; short feedback cycles
  • Cost: right-size infra; reuse SQL views and Parquet outputs

⚙️ 90‑minute quickstart​

Goal: ship a secure, minimal API that reads from SQL Server and a tiny UI that calls it.

1) Backend API (pick one)​

main.py
import os, urllib.parse
from fastapi import FastAPI, Header, HTTPException
from sqlalchemy import create_engine, text
from dotenv import load_dotenv; load_dotenv()

API_KEY = os.getenv("API_KEY")

def require_key(x_api_key: str | None = Header(default=None)):
if not API_KEY or x_api_key != API_KEY:
raise HTTPException(status_code=401, detail="Unauthorized")

params = urllib.parse.quote_plus(
"DRIVER={ODBC Driver 18 for SQL Server};"
f"SERVER={os.getenv('SQLSERVER_SERVER')};"
f"DATABASE={os.getenv('SQLSERVER_DATABASE')};"
"Trusted_Connection=Yes;Encrypt=Yes;"
)
engine = create_engine(f"mssql+pyodbc:///?odbc_connect={params}")

app = FastAPI()

@app.get("/health")
def health():
return {"status":"ok"}

@app.get("/kpi", dependencies=[require_key])
def kpi():
sql = text("""
SELECT TOP 50 practice_id, total_appointments, attendance_rate, median_wait_minutes
FROM dbo.vw_PracticeKPI ORDER BY total_appointments DESC
"""
)

with engine.begin() as con:
rows = con.execute(sql).mappings().all()
return list(rows)
.env (local only — do not commit)
SQLSERVER_SERVER=YOURSERVER
SQLSERVER_DATABASE=NHS_Analytics
API_KEY=change_me
Dockerfile.fastapi
FROM python:3.11-slim
WORKDIR /app
COPY main.py ./
RUN pip install fastapi uvicorn[standard] sqlalchemy pyodbc python-dotenv
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Security tip: start with an API key and rotate it; add OAuth2/NHS Login later. Always use parameterised queries and least‑privilege DB users.

2) Minimal frontend (Next.js page)​

app/page.tsx
"use client";
import { useEffect, useState } from "react";

type Row = { practice_id: string; total_appointments: number; attendance_rate: number; median_wait_minutes: number };

export default function Page() {
const [rows, setRows] = useState<Row[]>([]);
useEffect(() => {
fetch(process.env.NEXT_PUBLIC_API_URL + "/kpi", {
headers: { "x-api-key": process.env.NEXT_PUBLIC_API_KEY as string }
})
.then(r => r.json())
.then(setRows)
.catch(console.error);
}, []);

return (
<main style={{padding:16}}>
<h2>NHS KPI (Demo)</h2>
<table>
<thead><tr><th>Practice</th><th>Appointments</th><th>Attendance</th><th>Median wait (min)</th></tr></thead>
<tbody>
{rows.map((r,i)=>(
<tr key={i}><td>{r.practice_id}</td><td>{r.total_appointments}</td><td>{(r.attendance_rate*100).toFixed(1)}%</td><td>{r.median_wait_minutes}</td></tr>
))}
</tbody>
</table>
</main>
);
}
.env.local (Next.js)
NEXT_PUBLIC_API_URL=http://localhost:8000
NEXT_PUBLIC_API_KEY=change_me

▶️ Run​

# FastAPI (Python)
uvicorn main:app --reload --port 8000

# Express (Node)
npm install && npm start

# Docker (choose one Dockerfile)
docker build -f Dockerfile.fastapi -t nhs-api:dev .
docker run -p 8000:8000 --env-file .env nhs-api:dev

🗓️ Week‑one build (repeatable, safe)​

Day 1 — Contracts & schema

  • Reuse existing SQL views (e.g., vw_PracticeKPI); define request/response schema in README.

Day 2 — Security & logs

  • API key; structured JSON logs; correlation IDs; health check endpoint.

Day 3 — Frontend & UX

  • Next.js page with loading/empty/error states; accessible table components.

Day 4 — CI/CD

  • GitHub Actions: lint, test, build container, push to registry; deploy to dev.

Day 5 — Infra & monitoring

  • Secrets via platform store; HTTPS; metrics + alerts (5xx rate, latency, DB errors).

🧰 Open‑source augmentations (pick 2–3)​

Terraform
Infra as code for repeatable environments.
Sentry / OpenTelemetry
Error monitoring and traces.
Playwright / Jest / pytest
Unit + e2e tests in CI.
Unleash (feature flags)
Safely roll out features.
MLflow (optional)
Model tracking if your app serves ML.

See also: FastAPI · Express · React · Next.js · Docker · AWS · GitHub · Secrets & .env


🛡️ IG & safety checklist​

  • Keep secrets out of code; use environment/secret stores.
  • Enforce least‑privilege DB access; parameterised queries only.
  • Log access with correlation IDs; avoid PHI in logs.
  • Apply small‑number suppression in responses where appropriate.
  • Use HTTPS/TLS, and store DPIA/approvals with the repo.

📏 Measuring impact​

  • Reliability: uptime, 5xx rate, p95 latency.
  • Security: successful secret scans, dependency updates, blocked unauthorised calls.
  • Speed: lead time to change, mean time to restore.
  • Adoption: weekly active users/endpoints; integrations onboarded.
  • Cost: monthly infra cost; container size; CPU/memory baselines.

📚 References & next​

See also: Learn → Developer · Build → Overview

What’s next?

You’ve completed the Persona — Developer stage. Keep momentum: