Go-based bridge & caching microservice for headless WordPress architectures. Unifies WPGraphQL, WordPress REST, and external APIs behind a single fast endpoint — the differentiator from typical WordPress-only developers.
Author: Midas Moradi · Pairs with headless-wp-nextjs-starter and headless-wp-blog
flowchart TB
subgraph Clients["Multi-Channel Clients"]
NEXT["Next.js / SSG"]
MOBILE["Mobile App"]
OTHER["3rd-Party Consumers"]
end
subgraph Bridge["Go Bridge Service :8081"]
API["REST API /v1/*"]
CACHE["TTL Memory Cache"]
UNIFY["Unification Layer"]
API --> CACHE --> UNIFY
end
subgraph Sources["Upstream Data Sources"]
GQL["WPGraphQL\nWordPress CMS"]
REST["WP REST API\nCategories / Posts"]
EXT["External API\nEnrichment"]
end
NEXT --> API
MOBILE --> API
OTHER --> API
UNIFY --> GQL
UNIFY --> REST
UNIFY --> EXT
GQL -.->|cache miss| CACHE
REST -.->|cache miss| CACHE
EXT -.->|cache miss| CACHE
sequenceDiagram
participant C as Client
participant B as Go Bridge
participant K as Cache
participant W as WPGraphQL
participant R as WP REST
C->>B: GET /v1/feed
B->>K: lookup feed:unified
alt cache hit
K-->>B: cached JSON
B-->>C: 200 + X-Cache: HIT
else cache miss
B->>W: GraphQL posts query
B->>R: GET /categories
W-->>B: posts payload
R-->>B: categories payload
B->>K: store TTL 120s
B-->>C: 200 unified JSON
end
| Without bridge | With Go bridge |
|---|---|
| Frontend calls 3+ APIs directly | Single unified /v1/feed |
| Duplicate caching logic per client | Central TTL cache + X-Cache headers |
| Tight coupling to WordPress schema | Adapter layer per source |
| Hard to add mobile / partners | One API contract for all channels |
This matches the resume stack: "Go-based caching/bridge services unifying multiple data sources" for decoupled WordPress platforms.
- Multi-source adapters — WPGraphQL, WordPress REST, external enrichment API
- TTL memory cache — thread-safe with hit/miss telemetry
- Unified feed — merges WordPress + external data in one response
- Source proxy —
GET /v1/source/{source}/{path}with cache headers - Ops endpoints — health, cache stats, authenticated cache purge
- Zero external Go deps — stdlib only (
net/httprouting, Go 1.22+) - Docker ready — single binary, ~15MB image
git clone https://github.com/midasmoradi/headless-wp-bridge.git
cd headless-wp-bridge
cp .env.example .env
go run ./cmd/bridgeOr with Docker:
docker compose up --buildService listens on http://localhost:8081
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Service + upstream health + cache stats |
/v1/feed |
GET | Unified multi-source feed (cached) |
/v1/source/{source}/{path} |
GET | Proxy a single source (wpgraphql, wprest, external) |
/v1/cache |
DELETE | Purge cache (X-Bridge-Key header required) |
# Unified feed
curl http://localhost:8081/v1/feed
# GraphQL posts via bridge cache
curl -i http://localhost:8081/v1/source/wpgraphql/posts
# WordPress REST categories
curl http://localhost:8081/v1/source/wprest/categories?per_page=5
# Health + cache telemetry
curl http://localhost:8081/health
# Purge cache
curl -X DELETE http://localhost:8081/v1/cache -H "X-Bridge-Key: dev-bridge-key"{
"wordpress": {
"posts": { "data": { "posts": { "nodes": [] } } },
"categories": []
},
"enrichment": { "id": 1, "title": "..." },
"meta": {
"cached": { "posts": false, "categories": true, "external": true },
"sources": ["wpgraphql", "wprest", "external"],
"ttl_sec": 120
}
}| Variable | Default | Description |
|---|---|---|
BRIDGE_ADDR |
:8081 |
Listen address |
CACHE_TTL_SECONDS |
120 |
Default cache TTL |
WP_GRAPHQL_URL |
http://localhost:8080/graphql |
WPGraphQL endpoint |
WP_REST_URL |
http://localhost:8080/wp-json/wp/v2 |
WordPress REST base |
EXTERNAL_API_URL |
jsonplaceholder.typicode.com |
Enrichment API |
BRIDGE_API_KEY |
dev-bridge-key |
Cache purge auth |
CORS_ORIGIN |
http://localhost:3000 |
Allowed frontend origin |
headless-wp-bridge/
├── cmd/bridge/main.go # Entry point
├── internal/
│ ├── bridge/service.go # Unification + cache orchestration
│ ├── cache/memory.go # TTL cache store
│ ├── source/ # Upstream adapters
│ │ ├── graphql.go
│ │ ├── rest.go
│ │ └── external.go
│ ├── httpapi/ # Routes + middleware
│ └── config/
├── Dockerfile
└── docker-compose.yml
flowchart LR
WP["WordPress\n+ WPGraphQL"] --> BRIDGE["Go Bridge\n(cache + unify)"]
BRIDGE --> NEXT["Next.js Frontend"]
BRIDGE --> APP["Mobile / Partners"]
Point your Next.js data layer at http://bridge:8081/v1/feed instead of calling WordPress directly — especially useful when combining CMS content with CRM, search, or third-party enrichment APIs.
go test ./...
go build -o bin/bridge ./cmd/bridge| Repository | Role |
|---|---|
| headless-wp-nextjs-starter | Next.js + WPGraphQL boilerplate |
| headless-wp-blog | Full headless blog demo |
MIT — see LICENSE.