feat: add protoc-gen-krakend API gateway config generator#123
feat: add protoc-gen-krakend API gateway config generator#123SebastienMelki wants to merge 57 commits intomainfrom
Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add proto/sebuf/krakend/krakend.proto with GatewayConfig (ext 51001) and EndpointConfig (ext 51002) - Generate krakend/krakend.pb.go with E_GatewayConfig and E_EndpointConfig extensions - Update Makefile proto target to include krakend proto generation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add cmd/protoc-gen-krakend/main.go following openapiv3 entry point pattern
- Add internal/krakendgen/types.go with Endpoint and Backend structs
- Plugin reads CodeGeneratorRequest, iterates services, outputs {Service}.krakend.json
- JSON types use omitempty for timeout, input_headers, input_query_strings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Create 12-01-SUMMARY.md with execution results - Update STATE.md with position, metrics, and decisions - Update ROADMAP.md with plan progress - Mark ANNO-01, ANNO-02, ANNO-03 requirements complete Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Read sebuf.krakend.gateway_config for service-level host/timeout - Read sebuf.krakend.endpoint_config for method-level overrides - Read sebuf.http.config/service_config for routing (path, method, base_path) - Method-level endpoint_config overrides service-level gateway_config - Missing gateway_config fails with clear error message - Timeout omitted when not annotated at any level - Output encoding always "json" on every endpoint Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Call krakendgen.GenerateService for each service in proto files - Marshal endpoints to pretty-printed JSON with 2-space indent - Write per-service files with trailing newline - Propagate generator errors to protoc via plugin.Error - Empty services (no HTTP RPCs) produce [] not null - Fix: only require gateway_config when service has HTTP-annotated RPCs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add deriveInputHeaders helper that extracts header names via CombineHeaders - Integrate into GenerateService loop to populate InputHeaders on each endpoint - Returns nil when no headers annotated (omitempty omits from JSON) - Output sorted for deterministic golden file comparison Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add deriveInputQueryStrings helper that extracts param names via GetQueryParams - Integrate into GenerateService loop to populate InputQueryStrings on each endpoint - Returns nil when no query annotations exist (omitempty omits from JSON) - Output sorted for deterministic golden file comparison - Verified end-to-end: headers, query strings, and omission all work correctly Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
🔍 CI Pipeline Status✅ Lint: success 📊 Coverage Report: Available in checks above |
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Detect duplicate (path, method) tuples at generation time - Detect static vs parameterized segment conflicts via path trie - Error messages include service name, endpoint indices, and conflicting paths - Validation runs after endpoint generation, before returning from GenerateService Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…r KrakenD - 9 test protos covering: core routing, timeouts, host config, header forwarding, query forwarding, combined forwarding, and 3 error cases - 7 golden files for byte-for-byte regression detection - TestKrakenDGoldenFiles validates successful generation with UPDATE_GOLDEN support - TestKrakenDValidationErrors validates duplicate routes, static/param conflicts, and missing gateway_config produce clear error messages - Full project test suite passes (10/10 packages) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ages, namespace constants, extend structs - Wrap .krakend.json output in full KrakenD config object with $schema and version 3 - Add proto messages for rate limiting, JWT, circuit breaker, and cache - Create namespace constants file with unit tests for all 5 KrakenD namespaces - Add ExtraConfig and ConcurrentCalls fields to Endpoint and Backend structs - Update all 7 existing golden files to new wrapped format Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rage - Add resolve/build functions for endpoint and backend rate limiting - Integrate extra_config generation into GenerateService pipeline - Create rate_limit_service.proto test case with service defaults and method overrides - Add RateLimitService golden file covering qos/ratelimit/router and qos/ratelimit/proxy - Method-level rate limit fully overrides service-level (no field merge) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…gation - Add buildAuthValidatorConfig for auth/validator namespace config - Add buildPropagateClaims for array-of-arrays claim format - Add getJWTPropagatedHeaderNames for input_headers augmentation - Update buildEndpointExtraConfig to include JWT from service-level config - Auto-add propagated claim headers to input_headers with dedup and sort Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Create jwt_auth_service.proto exercising full JWT config - Generate JWTAuthService.krakend.json golden file - Verify auth/validator namespace with propagate_claims array-of-arrays - Verify propagated claim headers auto-added to input_headers - Add test case to TestKrakenDGoldenFiles (8 golden + 3 validation = 11 total) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ation - Add resolveCircuitBreaker, validateCircuitBreaker, buildCircuitBreakerConfig - Add resolveCache, validateCache, buildHTTPCacheConfig - Add resolveConcurrentCalls as top-level endpoint field (not extra_config) - Integrate validation in GenerateService (fail-fast on invalid config) - Wire circuit breaker and cache into buildBackendExtraConfig Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…cuit breaker, cache, concurrent calls - Add circuit_breaker_service.proto with service/method-level override - Add cache_concurrent_service.proto with caching and concurrent calls - Add full_gateway_service.proto combining ALL gateway features - Add invalid_circuit_breaker.proto and invalid_cache.proto for validation errors - Generate golden files for all three new services - Add validation error test cases for circuit breaker and cache Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…plan Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…m, fix cache oneOf bug - Add RateLimitStrategy and JWTAlgorithm enums to krakend.proto - Change strategy field from string to RateLimitStrategy enum - Change alg field from string to JWTAlgorithm enum - Add rateLimitStrategyToString and jwtAlgorithmToString mapping functions - Add cache validation rejecting shared combined with max_items/max_size - Update test protos to use enum values instead of string literals - Fix CacheConcurrentService test proto removing shared+max_items conflict Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…files - Add TestKrakenDSchemaValidation running krakend check -lc on all 12 golden files - Test skips gracefully when krakend CLI is not installed - Validates every generated config against KrakenD's official JSON schema Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…akenD links Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add protoc-gen-krakend as sixth generator in generators table - Add KrakenD API Gateway section with proto annotations and JSON output examples - Add krakend install command to Quick setup - Add KrakenD Gateway Example link to Next steps - Add KrakenD to Built on Great Tools section Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add protoc-gen-krakend as sixth plugin in project overview - Document krakendgen architecture, annotations, and generated output - Add KrakenD gateway annotations section with proto examples - Add extension numbers 51001/51002 to registry table - Document RateLimitStrategy and JWTAlgorithm enum types - Add KrakenD testing commands (golden files, schema validation) - Update project structure with krakend entries Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…file - UserService proto: JWT auth (RS256), IP rate limiting, backend rate limiting, headers, query params - ProductService proto: circuit breaker, caching (shared/sized), concurrent calls, header rate limiting - Method-level overrides: UpdateUser (header strategy), GetProduct (sized cache), CreateProduct (aggressive CB) - Makefile with generate/partials/validate/compose/clean targets using protoc directly Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Flexible Config template (krakend.tmpl) composes per-service endpoint partials - Settings file lists services for template range loops - README covers all KrakenD annotations with inline references to proto files - Flexible Config integration guide: generate -> partials -> compose workflow - Feature distribution table and step-by-step guide for adding new services - .gitignore for generated artifacts (generated/, gateway/partials/, buf.lock) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- SUMMARY.md with task commits, deviations, and self-check - STATE.md updated: all phase 14 plans complete, progress 100% - ROADMAP.md updated: phase 14 marked complete (3/3 plans) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generation now fails with a clear error when strategy is HEADER or PARAM but no key is specified. IP strategy does not require a key. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #123 +/- ##
========================================
- Coverage 2.64% 2.48% -0.16%
========================================
Files 45 47 +2
Lines 7082 7531 +449
========================================
Hits 187 187
- Misses 6892 7341 +449
Partials 3 3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…-service files The generator now merges all service endpoints into one ready-to-use krakend.json, matching the DX of every other sebuf plugin (one protoc invocation = usable output). Cross-service route conflict validation is now performed at generation time. The krakend-gateway example is simplified: removed the Flexible Config partials/template workflow (jq, krakend.tmpl, settings/) and added a runnable Go backend with Docker Compose so the gateway demo works end-to-end. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add exhaustive switch cases for UNSPECIFIED enum values - Extract helpers to reduce cognitive complexity in GenerateService and checkSegmentConflicts - Eliminate err shadow declarations throughout generator.go - Fix magic number (use const for KrakenD schema version) - Suppress gosec G115 for guaranteed ASCII byte conversions - Suppress gochecknoglobals for package-level namespace registry Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Auto-fix from golangci-lint. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
How to use
|
| Proto annotation | KrakenD output |
|---|---|
sebuf.http.config (path + method) |
endpoint, method, url_pattern |
sebuf.http.service_headers + method_headers |
input_headers (auto-derived, no wildcards) |
sebuf.http.query on request fields |
input_query_strings (auto-derived) |
sebuf.krakend.gateway_config (service-level) |
host, timeout, rate limit, JWT, circuit breaker, cache, concurrent calls |
sebuf.krakend.endpoint_config (method-level) |
Per-RPC overrides for any of the above |
The proto becomes the single source of truth. Add an endpoint or header annotation once, run buf generate, and the gateway config updates automatically. Route conflicts (duplicate paths, static vs parameterized collisions like /users/me vs /users/{id}) are caught at generation time, not at gateway startup.
How to use it
Step 1: Add krakend annotations to your proto
At the service level, set defaults for all endpoints:
import "sebuf/krakend/krakend.proto";
service UserService {
option (sebuf.krakend.gateway_config) = {
host: ["http://users-backend:8080"]
timeout: "3s"
rate_limit: { max_rate: 100, client_max_rate: 20, strategy: RATE_LIMIT_STRATEGY_IP }
jwt: {
alg: JWT_ALGORITHM_RS256
jwk_url: "https://auth.example.com/.well-known/jwks.json"
audience: ["https://api.example.com"]
issuer: "https://auth.example.com/"
cache: true
propagate_claims: [
{claim: "sub", header: "X-User"},
{claim: "org_id", header: "X-Org-ID"}
]
}
circuit_breaker: { interval: 60, timeout: 10, max_errors: 3 }
backend_rate_limit: { max_rate: 80, capacity: 100 }
};
}Optionally override per-RPC:
rpc UpdateUser(UpdateUserRequest) returns (User) {
option (sebuf.http.config) = { path: "/users/{id}", method: HTTP_METHOD_PUT };
option (sebuf.krakend.endpoint_config) = {
rate_limit: {
max_rate: 50
client_max_rate: 10
strategy: RATE_LIMIT_STRATEGY_HEADER
key: "X-API-Key" // Per-API-key throttling for writes
}
};
}Step 2: Add plugin to buf.gen.yaml
plugins:
- local: protoc-gen-krakend
out: gatewayStep 3: Generate
buf generate
# Output: gateway/krakend.json — a complete, valid KrakenD configThat's it. The output is a standalone krakend.json with $schema, version: 3, and all endpoints from all services combined. You can point KrakenD directly at it, or use it as a partial in KrakenD Flexible Config to compose with other settings.
What gets auto-derived (the best part)
You don't need to manually list forwarded headers or query params. The generator reads existing sebuf.http annotations:
- Headers:
service_headersrequired header names +method_headersrequired header names + JWTpropagate_claimsmapped headers → all merged, deduped, sorted →input_headers - Query strings: Fields with
(sebuf.http.query)annotation on the request message →input_query_strings
Example: if ListUsersRequest has fields page, per_page, status annotated with (sebuf.http.query), the generated endpoint automatically includes:
"input_query_strings": ["page", "per_page", "status"]No manual sync needed.
Features supported
| Feature | Where configured | KrakenD namespace |
|---|---|---|
| Rate limiting (endpoint) | rate_limit |
qos/ratelimit/router |
| Rate limiting (backend) | backend_rate_limit |
qos/ratelimit/proxy |
| JWT authentication | jwt (service-level only) |
auth/validator |
| JWT claim propagation | jwt.propagate_claims |
auto-added to input_headers |
| Circuit breaker | circuit_breaker |
qos/circuit-breaker |
| HTTP caching (shared) | cache: { shared: true } |
qos/http-cache |
| HTTP caching (sized) | cache: { max_items, max_size } |
qos/http-cache |
| Concurrent calls | concurrent_calls: N |
top-level endpoint field |
| Timeout | timeout: "3s" |
top-level endpoint field |
| Multi-host load balancing | host: ["h1", "h2"] |
backend host array |
All features can be set at service level (gateway_config) and overridden per-RPC (endpoint_config), except JWT which is service-level only (auth should be consistent across all endpoints in a service).
Generation-time validation
The plugin catches errors at build time instead of gateway startup:
- Duplicate routes: Two RPCs resolving to the same
METHOD /path→ generation error - Static vs parameterized conflicts:
/users/meand/users/{id}on the same method → generation error - Invalid cache config:
shared: truewithmax_items/max_size(KrakenD's oneOf constraint) → generation error - Missing rate limit key:
RATE_LIMIT_STRATEGY_HEADERwithout specifyingkey→ generation error
Running the example
There's a full working example in examples/krakend-gateway/ with two services (UserService + ProductService), Docker Compose, and a real KrakenD gateway:
# From repo root
make build
cd examples/krakend-gateway
make demo # generates config, builds backend, starts KrakenD + backend
make test # curls the gateway endpoints
make docker-downDocumentation
- KrakenD Gateway Example README — Full walkthrough with architecture diagram, annotation reference, and feature matrix
- Proto annotation definitions — Heavily commented proto file with usage examples for every field
- README KrakenD section — Overview in the main project README
TL;DR
Write your API in proto with sebuf annotations → run buf generate → get a validated, production-ready krakend.json with JWT, rate limiting, circuit breakers, caching, and all headers/query params correctly forwarded. No manual KrakenD JSON maintenance. The proto is the single source of truth.
- Replace byte() casts with unicode.ToLower in camelToSnake to avoid gosec G115 vs nolintlint conflict across golangci-lint versions - Run buf format on proto files (trailing whitespace, missing EOF newlines, comment alignment) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The krakend check -lc flag fetches the JSON schema from krakend.io, which can timeout in CI or on slow networks. Switch to syntax-only validation (-c) by default. Full online schema lint can be enabled with KRAKEND_LINT=1 when needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Drop protoc 3.19.0 and 3.20.0 which arduino/setup-protoc@v3 can no
longer resolve from GitHub releases ("unable to get latest version")
- Use protoc 25.1 and 28.3 (current stable versions)
- Add fail-fast: false so all matrix versions run independently
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
protoc-gen-go@latest now requires Go >= 1.23. The proto compatibility job was using Go 1.21 which is too old. Upgrade to 1.24 to match the main CI workflow. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Adds
protoc-gen-krakend— a new protoc plugin that generates KrakenD API gateway endpoint configurations directly from protobuf service definitions.Why this matters
The problem: KrakenD configuration is handwritten JSON that must stay perfectly in sync with your backend API definitions. Every time you add an endpoint, change a path parameter, add a required header, or introduce a query filter, you must manually update the gateway config. This creates:
sebuf.http.config,sebuf.http.service_headers,sebuf.http.query), but must be re-specified in KrakenD JSONinput_headersandinput_query_strings. Forgetting one breaks authentication, pagination, or filtering silentlyThe solution:
protoc-gen-krakendreads the proto annotations you've already written and generates correct, minimal KrakenD endpoint fragments automatically:sebuf.http.config→ endpoint path and HTTP methodsebuf.http.service_headers+method_headers→input_headers(auto-derived, never wildcards)sebuf.http.query→input_query_strings(auto-derived from request message fields)sebuf.krakend.gateway_config→ backend host and default timeoutsebuf.krakend.endpoint_config→ per-RPC overridesThe benefit: Proto definitions remain the single source of truth. Add an endpoint or header annotation once, regenerate, and the gateway config updates automatically. Route conflicts (duplicate paths, static vs parameterized collisions) are caught at generation time, not at gateway startup.
What's included (Phase 12 — in progress)
sebuf.krakend), plugin scaffold, KrakenD JSON typesWhat's coming next (Phases 13-14)
Test plan
make buildproducesbin/protoc-gen-krakendgo vet ./cmd/protoc-gen-krakend/... ./internal/krakendgen/...passesmake lint-fixpasses./scripts/run_tests.sh --fast— full project test suite passes with no regressions🤖 Generated with Claude Code