Skip to content

feat: add protoc-gen-krakend API gateway config generator#123

Open
SebastienMelki wants to merge 64 commits intomainfrom
gsd/phase-12-annotations-and-core-endpoint-generation
Open

feat: add protoc-gen-krakend API gateway config generator#123
SebastienMelki wants to merge 64 commits intomainfrom
gsd/phase-12-annotations-and-core-endpoint-generation

Conversation

@SebastienMelki
Copy link
Copy Markdown
Owner

@SebastienMelki SebastienMelki commented Feb 25, 2026

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:

  • Configuration drift — the gateway config diverges from the actual API, causing silent request failures at the gateway layer (blocked headers, missing query params, wrong paths)
  • Duplicated source of truth — HTTP routing, header requirements, and query parameters are already defined in proto annotations, but must be re-specified in KrakenD JSON
  • KrakenD zero-trust model amplifies this — by default KrakenD forwards nothing (no headers, no query strings). Every parameter must be explicitly allowlisted. Forgetting one breaks auth, pagination, or filtering silently

The solution: protoc-gen-krakend reads the proto annotations you have already written and generates correct, minimal KrakenD endpoint fragments automatically.

Dual output: .json + .tmpl

The plugin produces two outputs per invocation:

Output Purpose Format
krakend.json Visual verification, PR diffs, schema validation Full KrakenD config with $schema, version, endpoints[]
{service}_endpoints.tmpl Production use with KrakenD Flexible Config Per-service fragments with Go template syntax

Template (.tmpl) features

The .tmpl output conventions are documented in CLAUDE.md under "Flexible Config Template Conventions":

  • Host variables: {{ .vars.user_service_host }} — environment-specific via settings files
  • JWT auth: {{ template "jwt_auth_validator.tmpl" . }} — shared partial maintained by gateway team
  • Recaptcha: {{ include "recpatcha_validator.tmpl" }} — bot protection via shared partial
  • Header partials: {{ include "trading_input_headers.tmpl" }} — centralized header management
  • Backend defaults: sd:static, disable_host_sanitize:false, return_error_code:true
  • Timeout: Only emitted for method-level overrides; service timeout via root settings
  • QoS: Rate limiting, circuit breaker, cache in .json only — gateway team manages these separately

Proto annotations

Two annotation levels:

service UserService {
  option (sebuf.krakend.gateway_config) = {
    host: ["http://users-backend:8080"]
    timeout: "3s"
    jwt: { alg: JWT_ALGORITHM_RS256, jwk_url: "..." }
    input_headers_partial: "trading_input_headers.tmpl"  // header partial for .tmpl
  };

  rpc CreateUser(CreateUserRequest) returns (User) {
    option (sebuf.http.config) = { path: "/users", method: HTTP_METHOD_POST };
    option (sebuf.krakend.endpoint_config) = {
      recaptcha: true  // bot protection for .tmpl
    };
  };
}

What is included

  • Phase 12: Proto annotations, plugin scaffold, core endpoint generation, header/query forwarding, route validation
  • Phase 13: Rate limiting, JWT auth with claim propagation, circuit breaker, caching, concurrent calls
  • Phase 14: Proto documentation, krakend-gateway example, README/CLAUDE.md updates
  • Quick task 4: .tmpl Flexible Config generation

Files overview

Path What
proto/sebuf/krakend/krakend.proto Annotation definitions (gateway_config, endpoint_config, enums)
krakend/krakend.pb.go Generated Go code from proto
cmd/protoc-gen-krakend/main.go Plugin entry point — writes .json + per-service .tmpl
internal/krakendgen/generator.go Core generation: reads annotations, builds Endpoint structs
internal/krakendgen/tmpl_generator.go Template generation: Endpoint -> .tmpl fragment
internal/krakendgen/types.go Endpoint/Backend structs with template metadata
internal/krakendgen/testdata/golden/*.json 11 JSON golden files
internal/krakendgen/testdata/golden/*.tmpl 12 template golden files
examples/krakend-gateway/ Full example with Flexible Config

Test plan

  • make build produces bin/protoc-gen-krakend
  • make lint-fix — 0 issues
  • 11 JSON golden file tests pass (zero regression)
  • 12 template golden file tests pass
  • 6 validation error tests pass (duplicate routes, missing config, invalid QoS)
  • KrakenD schema validation tests pass (krakend check -c)
  • 10 unit tests for template generator (snake_case, host vars, JWT, recaptcha, partials)
  • ./scripts/run_tests.sh --fast — all 10 packages pass

Generated with Claude Code

SebastienMelki and others added 17 commits February 25, 2026 13:42
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>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 25, 2026

🔍 CI Pipeline Status

Lint: success
Test: success
Coverage: success
Build: success
Integration: success


📊 Coverage Report: Available in checks above
🔗 Artifacts: Test results and coverage reports uploaded

SebastienMelki and others added 12 commits February 25, 2026 15:28
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>
SebastienMelki and others added 11 commits February 25, 2026 17:11
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
Copy link
Copy Markdown

codecov Bot commented Feb 25, 2026

Codecov Report

❌ Patch coverage is 18.95652% with 466 lines in your changes missing coverage. Please review.
✅ Project coverage is 4.08%. Comparing base (610ccbd) to head (e8d8ad2).

Files with missing lines Patch % Lines
internal/krakendgen/generator.go 0.00% 360 Missing ⚠️
internal/krakendgen/validation.go 0.00% 94 Missing ⚠️
internal/krakendgen/tmpl_generator.go 89.65% 8 Missing and 4 partials ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##            main    #123      +/-   ##
========================================
+ Coverage   3.05%   4.08%   +1.03%     
========================================
  Files         47      50       +3     
  Lines       7803    8373     +570     
========================================
+ Hits         238     342     +104     
- Misses      7561    8023     +462     
- Partials       4       8       +4     
Flag Coverage Δ
unittests 4.08% <18.95%> (+1.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

SebastienMelki and others added 4 commits February 26, 2026 01:14
…-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>
@SebastienMelki
Copy link
Copy Markdown
Owner Author

How to use protoc-gen-krakend

Hey! Here's a detailed walkthrough of what this plugin does and how to integrate it into our workflow.

The problem it solves

KrakenD operates on a zero-trust model — by default it forwards nothing to backends. No headers, no query strings, no parameters. Every single one must be explicitly allowlisted in input_headers and input_query_strings in the KrakenD JSON config. On top of that, every endpoint path, HTTP method, timeout, rate limit config, JWT config, etc. must also be manually specified.

This means today we maintain two sources of truth: the proto definitions (which define the actual API) and the KrakenD JSON config (which must mirror it exactly). When someone adds a header annotation, a query parameter, or a new endpoint to a proto, they also have to remember to update the KrakenD config. If they forget, the gateway silently drops headers or blocks requests — no build error, no warning, just broken auth or missing pagination at runtime.

What protoc-gen-krakend does

It reads the annotations we've already written in our proto files and generates correct KrakenD JSON automatically:

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: gateway

Step 3: Generate

buf generate
# Output: gateway/krakend.json — a complete, valid KrakenD config

That'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_headers required header names + method_headers required header names + JWT propagate_claims mapped 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/me and /users/{id} on the same method → generation error
  • Invalid cache config: shared: true with max_items/max_size (KrakenD's oneOf constraint) → generation error
  • Missing rate limit key: RATE_LIMIT_STRATEGY_HEADER without specifying key → 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-down

Documentation

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.

@SebastienMelki SebastienMelki marked this pull request as ready for review February 26, 2026 13:18
SebastienMelki and others added 7 commits February 26, 2026 15:20
- 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>
…ons-and-core-endpoint-generation

# Conflicts:
#	.planning/STATE.md
Add KrakenD Flexible Config template generation to protoc-gen-krakend.
The plugin now produces per-service .tmpl files with Go template syntax
for production KrakenD deployments, alongside the existing .json output
for visual verification.

Template features aligned with CONTRACT_DRIVEN_GATEWAY.md spec:
- Fragment format (bare endpoint objects, no array wrapper)
- Host variables: {{ .vars.user_service_host }}
- JWT: {{ template "jwt_auth_validator.tmpl" . }}
- Recaptcha: {{ include "recpatcha_validator.tmpl" }} (new annotation)
- Header partials: {{ include "xxx_input_headers.tmpl" }} (new annotation)
- Always includes: sd:static, disable_host_sanitize:false, return_error_code
- Timeout only emitted for method-level overrides
- QoS configs (rate limit, circuit breaker, cache) omitted from .tmpl

New proto annotations:
- GatewayConfig.input_headers_partial (field 9)
- EndpointConfig.recaptcha (field 8)

12 template golden files, 10 unit tests, zero regression on JSON output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…e syntax for Flexible Config

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@SebastienMelki
Copy link
Copy Markdown
Owner Author

SebastienMelki commented Mar 16, 2026

DevOps Review Guide

Hey! This PR adds KrakenD Flexible Config template generation to protoc-gen-krakend. Here is what to look at and how to verify it matches our gateway patterns.

What changed for you

The plugin now generates two files when you run protoc:

  1. krakend.json — same as before, full static config for diffing and krakend check validation
  2. {service}_endpoints.tmplnew, one per service, ready to drop into your Flexible Config setup

Key files to review

Start here — the template conventions are documented in CLAUDE.md under "Flexible Config Template Conventions". Verify the generator output matches those rules.

Then check the generated output matches your patterns:

  • internal/krakendgen/testdata/golden/full_gateway_service.krakend.tmpl — the most complete example (JWT + headers + concurrent calls). Compare with your existing hand-written templates.
  • internal/krakendgen/testdata/golden/jwt_auth_service.krakend.tmpl — JWT-protected service with claim propagation headers
  • internal/krakendgen/testdata/golden/simple_service.krakend.tmpl — minimal service (no JWT, no extras)

The template generator code:

  • internal/krakendgen/tmpl_generator.go — ~200 lines, straightforward string building. This is where the output format is defined.

The new proto annotations (for you to use):

  • proto/sebuf/krakend/krakend.proto — look for input_headers_partial (field 9 on GatewayConfig) and recaptcha (field 8 on EndpointConfig)

What to verify

  1. Template structure — Does the generated .tmpl look like your existing hand-written KrakenD templates? Check:

    • "sd": "static" on every backend
    • "disable_host_sanitize": false on every backend
    • "backend/http": { "return_error_code": true } always in backend extra_config
    • "encoding": "json" and "output_encoding": "json" present
  2. Host variables{{ .vars.user_service_host }} derived from proto service name. Would these names work in your settings/*/vars.json files?

  3. JWT directive{{ template "jwt_auth_validator.tmpl" . }} (with dot context). Is this the right directive for your JWT partial? (vs {{ include }})

  4. Recaptcha directive{{ include "recpatcha_validator.tmpl" }} (no dot context). Matches the spelling in your existing partials.

  5. Header partials — When input_headers_partial: "trading_input_headers.tmpl" is set on the service, the generator emits {{ include "trading_input_headers.tmpl" }} instead of inline headers. When not set, it falls back to explicit "input_headers": [...]. Is this the right default?

  6. Timeout behavior — Service-level timeout is NOT emitted in .tmpl (it lives in your root settings). Only method-level overrides show up. Correct?

  7. QoS absence — Rate limiting, circuit breaker, and cache configs are intentionally not in the .tmpl output (they are in .json for reference). The gateway team manages these outside of generated code. Is this the right split?

How to test locally

make build

# Generate for any proto with KrakenD annotations
protoc --plugin=protoc-gen-krakend=./bin/protoc-gen-krakend \
       --krakend_out=./output \
       --proto_path=examples/krakend-gateway/proto \
       --proto_path=proto \
       examples/krakend-gateway/proto/services/user_service.proto

# Check output
cat output/user_service_endpoints.tmpl
cat output/krakend.json

What is NOT in scope yet

  • JSON-schema validation (validation/json-schema blocks) — deferred, will discuss separately
  • Martian header injection (modifier/martian) — low priority per spec
  • Custom extra_config passthrough — if you need arbitrary extra_config keys in .tmpl, that is a follow-up

SebastienMelki and others added 4 commits March 16, 2026 13:11
…T_DRIVEN_GATEWAY.md

The template generation spec from CONTRACT_DRIVEN_GATEWAY.md is now
documented in CLAUDE.md under "Flexible Config Template Conventions".
Updated KrakenD Gateway Annotations example to show input_headers_partial
and recaptcha annotations. Updated plugin description and core components.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix typo from original examples: "recpatcha" -> "recaptcha" in
generator output, proto comments, types, tests, golden files, and docs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fixes buf lint failure on PR #123.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant