Lightweight Fastify + Bun backend for the Sekolahku dataset ingestion project. The service exposes API key authenticated endpoints for school management, events (acara), broadcasts (siaran), and data revalidation, with Zod schemas, Swagger docs, and MongoDB persistence.
- Fastify on Bun for high throughput and low overhead.
- Type-safe endpoints powered by TypeScript + Zod schemas.
- School catalog CRUD backed by MongoDB/Mongoose.
- Events (Acara) and Broadcasts (Siaran) management.
- Data revalidation for dynamic dataproc jobs.
- Plugin-driven app startup (security headers, CORS, Swagger, request logging).
- Structured logging with Pino and environment-aware formatting.
- Auto-generated API docs via Swagger UI.
- API key authentication for secure access.
git clone https://github.com/your-org/sekolahku-mod-api.git
cd sekolahku-mod-api
bun installThe project includes school data from the Malaysian Ministry of Education:
SenaraiSekolahWeb_Julai2025 - SenaraiSekolahWeb.csvβ Comprehensive list of schools in Malaysia (July 2025)
Create a .env file matching src/config/env.config.ts expectations:
APP_ENV=development # development | production | test | local
LOG_LEVEL=debug # overrides default per env
PORT=3000
MONGODB_URI=mongodb://localhost:27017/sekolahku
API_KEY=your-secret-api-key # required for authentication| Variable | Required | Default | Description |
|---|---|---|---|
APP_ENV |
No | local |
Runtime environment |
LOG_LEVEL |
No | debug/info |
Pino log level |
PORT |
No | 3000 |
Fastify listen port |
MONGODB_URI |
Yes | β | MongoDB connection string |
API_KEY |
Yes | β | API key for authentication |
bun run dev # watch mode server
bun run start # production start
bun run typecheck # tsc --noEmit
bun run lint # eslint . --ext .ts
bun run lint-fix # eslint . --ext .ts --fix
bun run test # run tests
bun run test:coverage # run tests with coverageGET /healthβ Liveness + Mongo connection status
GET /schoolsβ List schools (requiressekolahku-x-api-keyheader)GET /schools/:idβ Fetch single schoolGET /schools/searchβ Get schools search suggestionsGET /schools/find-nearbyβ Get nearby schools by location and radius
GET /acaraβ List all eventsGET /acara/:idβ Get event by ID
GET /siaranβ List all broadcastsGET /siaran/:idβ Get broadcast by ID
GET /revalidate/:servicePathβ Trigger dynamic dataproc revalidation job
All protected routes require the sekolahku-x-api-key header with a valid API key.
docker build -t sekolahku-mod-api .docker run --rm -p 3000:3000 \
-e APP_ENV=development \
-e PORT=3000 \
-e API_KEY=your-secret-api-key \
-e MONGODB_URI="mongodb://host.docker.internal:27017/sekolahku" \
sekolahku-mod-apidocker run --rm -p 3000:3000 \
-e APP_ENV=production \
-e PORT=3000 \
-e API_KEY=your-secret-api-key \
-e MONGODB_URI="mongodb://mongo/prod" \
-e MULTIPLE_ORIGINS="https://app.sekolahku.gov.my,https://admin.sekolahku.gov.my" \
sekolahku-mod-apiNotes:
- Service listens on
0.0.0.0. MULTIPLE_ORIGINSmust be set whenAPP_ENV=production.
src/
config/ # env + logger + DB connectors
plugins/ # Fastify plugins (env, security, swagger, logging)
middleware/ # auth + error handlers
schemas/ # zod schemas per domain
controllers/ # request handlers
routes/ # Fastify route registrations
models/ # Mongoose models
services/ # business logic services (dataproc, geometry, secrets-manager)
types/ # TypeScript type definitions
utils/ # utility functions
scripts/ # maintenance scripts
bun run test # run all tests
bun run test:coverage # run tests with coverage reportTest files are located in the tests/ directory, including HTTP request tests (.http files) and unit tests (.test.ts files).
- Fork & create feature branch (
git checkout -b feature/xyz) - Commit with lint + typecheck passing
- Open a PR describing changes & testing notes
Distributed under the terms in LICENSE.
Built with β€οΈ using Bun, Fastify, and MongoDB.