refactor: retire /workflows endpoint, use X-Service: workflow instead
CI / CI (pull_request) Successful in 3m12s

Remove deprecated /workflows HTTP endpoint in favor of unified X-Service
header routing. All workflow operations now route through:

  X-Service: workflow
  X-Resource: {action} (start, describe, signal, query, etc)

This consolidates routing patterns and allows users to specify domain/
namespace via request payload instead of path prefixes.

Changes:
- Remove internal/proxy/workflows.go (484 lines of predefined workflows)
- Remove internal/proxy/workflows_test.go
- Remove /workflows handler from proxy.ServeHTTP()
- Update README.md to document X-Service routing pattern
- Add migration note: use X-Service: workflow instead of /workflows

WorkflowAdapter in serviceadapter/ handles X-Service: workflow requests
and forwards to Temporal gRPC API. Users can now specify domain/namespace
in request payload for multi-tenant workflow access.

Related: #26
This commit is contained in:
Admin Bot
2026-09-14 08:18:36 +09:00
parent cc9a32f53a
commit b0f608f145
4 changed files with 30 additions and 778 deletions
+28 -29
View File
@@ -38,22 +38,22 @@ Production API gateway for the homelab cluster. Single entry point (`api.riotpia
│ (routing, auth, limits) │
└──────┬───────────────────────┘
┌──────┴──────────────────────────────────┐
│ │
/v1/* /workflow /sqs /
(LLM) (Temporal gRPC) (Queues) (X-Service)
│ │
▼ ▼
llm-serving temporal:7233 kmsvc/Kafka IAM, S3
(vLLM, Ollama) (WorkflowService) Memory
(TEI) (gRPC bridge) (poimen)
┌──────┴──────────────────────────────────
/v1/* X-Service header routing /
(LLM) (workflow, sqs, s3, iam, memory) /
│ │
▼ ▼
llm-serving temporal:7233 kmsvc/Kafka, MinIO,
(vLLM, Ollama) (gRPC) Authentik, poimen-memory
(TEI)
```
**Design principles:**
- ✅ Single hostname, multiple path prefixes
- ✅ HTTP REST gateway → gRPC Temporal bridge
- ✅ Single hostname, unified X-Service + X-Resource header routing
- ✅ HTTP REST gateway → gRPC Temporal bridge (via X-Service: workflow)
- ✅ Bearer token auth via Authentik (JWT + RBAC)
- ✅ Streaming unbuffered (SSE, WebSocket)
- ✅ Streaming unbuffered (SSE, WebSocket, HTTP/2 multiplexing)
- ✅ Per-route timeouts & rate limits
- ✅ No cluster credentials held by gateway
@@ -61,16 +61,16 @@ llm-serving temporal:7233 kmsvc/Kafka IAM, S3
## Services & Capabilities
| Service | Prefix | Upstream | Status |
| Service | Method | Upstream | Status |
|---------|--------|----------|--------|
| **LLM Chat** | `/v1/chat/completions` | llm-serving (vLLM) | ✅ Live |
| **Embeddings** | `/v1/embeddings` | llm-serving (TEI) | ✅ Live |
| **Reranking** | `/v1/rerank` | llm-serving (TEI) | ✅ Live |
| **Workflows** | `/workflow` | Temporal gRPC (7233) | ✅ Live (START, DESCRIBE, SIGNAL, QUERY, etc) |
| **Queues** | `/` + `X-Service: sqs` | kmsvc/Kafka | ⏳ Ready (ServiceAdapter) |
| **Memory** | `/` + `X-Service: memory` | poimen-memory | ✅ Live |
| **IAM** | `/` + `X-Service: iam` | Authentik API | ✅ Live |
| **S3** | `/` + `X-Service: s3` | MinIO | ✅ Live |
| **LLM Chat** | `POST /v1/chat/completions` | llm-serving (vLLM) | ✅ Live |
| **Embeddings** | `POST /v1/embeddings` | llm-serving (TEI) | ✅ Live |
| **Reranking** | `POST /v1/rerank` | llm-serving (TEI) | ✅ Live |
| **Workflows** | `X-Service: workflow` + `X-Resource: {action}` | Temporal gRPC (7233) | ✅ Live (START, DESCRIBE, SIGNAL, QUERY, etc) |
| **Queues** | `X-Service: sqs` + `X-Resource: {action}` | kmsvc/Kafka | ✅ Live |
| **Memory** | `X-Service: memory` + `X-Resource: {action}` | poimen-memory | ✅ Live |
| **IAM** | `X-Service: iam` + `X-Resource: {action}` | Authentik API | ✅ Live |
| **S3** | `X-Service: s3` + `X-Resource: {action}` | MinIO | ✅ Live |
---
@@ -102,18 +102,17 @@ curl -X POST https://api.riotpiao.com/v1/chat/completions \
}'
```
**Workflow:**
**Workflow (via X-Service header):**
```bash
curl -X POST https://api.riotpiao.com/workflow \
curl -X POST https://api.riotpiao.com/ \
-H "Authorization: Bearer $TOKEN" \
-H "X-Service: workflow" \
-H "X-Resource: start" \
-d '{
"action": "START_WORKFLOW",
"namespace": "default",
"payload": {
"workflow_id": "my-workflow",
"workflow_type": "MyWorkflow",
"task_queue": "default"
}
"workflow_id": "my-workflow",
"workflow_type": "MyWorkflow",
"task_queue": "default"
}'
```