Services Overview
GospeLib is composed of eight backend services, each owning a distinct domain. All external traffic enters through the Gateway — no other service is exposed directly to clients.
Service Catalog
| Service | Port | Language | Framework | Responsibility |
|---|---|---|---|---|
| Gateway | 8080 | Go | Chi v5 | API gateway — JWT validation, rate limiting, reverse proxy |
| Content | 8100 | Python 3.12 | FastAPI | Scripture graph queries (FalkorDB) |
| Auth | 8200 | Go | Chi v5 | Clerk wrapper, user sync, JWT middleware |
| Billing | 8300 | Go | Chi v5 | Stripe subscriptions, entitlements |
| AI | 8400 | Python 3.12 | FastAPI | LLM passage explanation, study questions |
| Notifications | 8500 | Go | Chi v5 | Push (APNs/FCM), email (Resend), Redis Streams |
| Plugin Registry | 8500 | Python 3.12 | FastAPI | Plugin manifest registry, discovery, versioning |
| Ingest | — | Python 3.12 | Click CLI | 14-stage data pipeline (corpus → FalkorDB) |
info
The Ingest service is a CLI tool, not an HTTP service — it has no port.
Request Flow
Browser / Mobile App
│
▼
Gateway (:8080)
├── JWT validation
├── Rate limiting
├── Entitlement check
└── Reverse proxy ──► Content (:8100)
──► Auth (:8200)
──► Billing (:8300)
──► AI (:8400)
──► Notifications (:8500)
All inter-service communication uses direct HTTP. The gateway injects X-Request-ID and X-User-Id headers into every proxied request.
Middleware Stack
Every request through the gateway passes through an ordered middleware chain:
RequestID → RealIP → OpenTelemetry → Logger → Recoverer → CORS → RateLimiter
└── Auth group: ValidateJWT → InjectUserClaims → Entitlement
See Gateway > Middleware Stack for details.
Dependency Rules
- Apps (web, admin, mobile) import all
@gospelib/*packages @gospelib/sdkimports only@gospelib/types- Services never import TypeScript packages at runtime — they are standalone processes
Response Envelope
All services follow a shared response envelope format:
// Success
{ "data": T, "meta": { "next_cursor": "...", "total": 42 } }
// Error
{ "error": { "code": "PASSAGE_NOT_FOUND", "message": "...", "request_id": "..." } }
Pagination is cursor-based via next_cursor in meta.
Async Communication
Services communicate asynchronously via Redis Streams with consumer groups:
| Stream | Producer | Consumer |
|---|---|---|
gl:events:notifications | Any service | Notifications |
gl:events:users | Auth | Billing, Notifications |
gl:events:ingest | Ingest | Content |
Service Directory Structures
Go Services (Gateway, Auth, Billing, Notifications)
services/<name>/
├── cmd/server/main.go # Entry point
├── internal/
│ ├── config/config.go # Env-var config with defaults
│ ├── handler/<resource>.go # HTTP handlers (+ _test.go)
│ ├── middleware/ # HTTP middleware
│ ├── service/<resource>.go # Business logic
│ ├── repository/<resource>.go # Data access
│ └── model/<resource>.go # Domain types
├── api/openapi.yaml
├── go.mod / go.sum
└── Dockerfile
Python Services (Content, AI)
services/<name>/src/gospelib_<name>/
├── __init__.py
├── main.py # create_app() → FastAPI
├── config.py # pydantic-settings BaseSettings
├── routes/ # APIRouter per resource
├── models/ # Pydantic models
├── services/ # Business logic
├── db/ # Database clients
└── utils/
Related Pages
- Architecture > Service Communication — detailed communication patterns
- Architecture > Security — authentication and authorization flow
- Getting Started > Port Map — quick-reference port table
- Platform — the user-facing product these services power