Stage 7 · Master
Testing Strategy
API Testing with Postman and Newman
The current Meridian Postman collection is a health-check smoke suite; later it expands at the gateway as real business routes appear.
What Can Be Tested over HTTP Today
The real HTTP surface of Meridian is intentionally small today. gateway, identity-service, community-service, and billing-service each expose only GET /healthz. That means the current Postman/Newman suite should behave like an honest smoke test, not like a fictional CRUD contract. It can prove that the processes boot, the ports match .env.example, and the JSON health response stays stable. It should not pretend that tenants, residents, invoices, or complaints already have public routes.
The gateway does not yet proxy identity-service, community-service, or billing-service business routes. This lesson therefore uses /healthz as its concrete present-tense example and treats richer request folders as the future shape of the collection once those routes exist.
Collection Structure
api/postman/meridian.postman_collection.jsoncreateResponsibility: Defines the shared request folders and test scripts for gateway and service health endpoints, then later for business routes proxied through the gateway.
Why now: API smoke tests should be versioned in the repository, not left in one developer's Postman workspace.
Connects to: Starts from the /healthz endpoints in apps/gateway/cmd/gateway/main.go and the three service cmd entrypoints.
api/postman/meridian.local.postman_environment.jsoncreateResponsibility: Stores base URLs and ports for a local stack started from .env.example defaults.
Why now: Environment-specific values should stay out of the request definitions so the same collection can run locally and in CI.
Connects to: Uses GATEWAY_PORT, IDENTITY_SERVICE_PORT, COMMUNITY_SERVICE_PORT, and BILLING_SERVICE_PORT from .env.example.
Gateway-First Smoke Tests
Because gateway is the only public entrypoint, the first request in the collection should target http://localhost:8080/healthz by default. Local-only folders can still hit the internal services directly to confirm all four binaries boot during development, but the public contract begins with the gateway. That distinction matters later when authentication, tenant resolution, and rate limiting are introduced at the edge.
pm.test("gateway health responds 200", function () {
pm.response.to.have.status(200);
});
const body = pm.response.json();
pm.test("gateway health shape is stable", function () {
pm.expect(body.service).to.eql("gateway");
pm.expect(body.status).to.eql("ok");
});This is intentionally small. The running binary either responds with the expected health contract or it does not. That is enough for the scaffold phase.
{
"info": {
"name": "Meridian API",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Gateway",
"item": [{ "name": "GET /healthz" }]
},
{
"name": "Local Service Health",
"item": [
{ "name": "identity-service /healthz" },
{ "name": "community-service /healthz" },
{ "name": "billing-service /healthz" }
]
}
]
}The collection begins as smoke coverage over what the repo actually serves. That keeps the artifact truthful and still useful in CI.
How the Suite Grows
When the gateway starts proxying business routes, the collection should add folders by bounded context rather than by ad hoc request order: Identity, Community, and Billing. identity-service folders will eventually cover tenant and membership flows; community-service folders will cover residents, units, announcements, and complaints; billing-service folders will cover invoices and payments. Each request should still run through the gateway base URL so the live contract includes whatever auth, tenant resolution, rate limiting, and response envelope logic the public edge owns.
| Phase | Concrete requests | Purpose |
|---|---|---|
| Scaffolding | gateway /healthz and optional direct service /healthz | Boot smoke and JSON-shape stability |
| Gateway routing | gateway -> /identity/*, /community/*, /billing/* | Proxy correctness and header forwarding |
| Business logic | tenant, complaint, invoice, payment workflows | End-to-end contract testing through the only public entrypoint |
The Decision
- The current collection is an honest health-check smoke suite because /healthz is the only real HTTP contract today.
- gateway remains the default target because it is the only public entrypoint by design.
- Direct internal service requests are useful for local diagnostics, but they are not the frontend contract.
- Business-route folders are added only when those routes exist, and they still run through the gateway rather than bypassing it.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.