The current Prometheus HTTP API client in Go (github.com/prometheus/client_golang/api/prometheus/v1) is entirely hand-written. While it has served the community well, maintaining it manually poses maintenance overhead e.g. fixing bugs, syncing with Prometheus API changes.
Prometheus now officially publishes and serves an OpenAPI specification (OpenAPI 3.1/3.2) at /api/v1/openapi.yaml (see Prometheus API Documentation).
Given that we could leverage this OpenAPI specification to generate a Go API client for a given version. In ideal world, that would be to have a job that automatically regenerates and proposes a PR whenever Prometheus changes spec. This could live in separate, clearly non-stable module (currently it's marked as experimental but it's shipped within stable module).
Challenges/Questions
- How much of breaking changes this generation can produce?
- How much of breaking changes this will be vs our current api/v1 for migration purposes?
- Example: The current client uses custom types like
model.Value (which can be Vector, Matrix, etc.) and model.Time. A generated client will likely map responses to strict JSON-serializable Go structs generated from the OpenAPI schema, which might lose these convenient helper types.
- Is such generated API good enough for functionality purposes (e.g. unknown OpenSpec limitations)? How to assure quality (testing)?
- Performance: The current client uses
github.com/json-iterator/go with highly optimized, custom unsafe decoders for high-performance JSON parsing of Prometheus query results (e.g., optimizing SamplePair and SampleHistogramPair parsing).
- Generated clients typically rely on standard
encoding/json or generic marshaling, which could introduce significant CPU and memory overhead when parsing large query results.
- Mitigation: If using
oapi-codegen, we may need to customize the templates to use json-iterator or inject custom marshaling logic for critical hot-paths like matrix/vector query results.
- Should we even host generated code and ask anyone to generate themselves?
Some potential tools to use (researched with AI)
oapi-codegen (Recommended)
- Repository: github.com/oapi-codegen/oapi-codegen
- Description: A highly popular, Go-native tool designed specifically to generate boilerplates, boilerplate types, and clients from OpenAPI 3.0/3.1 specs.
- Pros:
- Generates highly idiomatic Go code.
- Excellent support for OpenAPI 3.0 and rapidly improving/stable support for OpenAPI 3.1 (via
kin-openapi).
- Highly customizable using Go templates.
- Generates type-safe clients and supports various HTTP client/server frameworks (standard
net/http, Chi, Echo, Gin, etc.).
- Active community and frequent updates.
- Cons:
- Go-specific, meaning any customization templates are Go-only (though this is a pro for us).
- Complex specs with heavy use of
oneOf, anyOf can sometimes lead to verbose or awkward Go helper types.
- OpenAPI Generator
- Website: openapi-generator.tech
- Description: The most widely used multi-language generator, community-forked from the original Swagger Codegen.
- Pros:
- Supports a vast range of languages and frameworks.
- Very mature with a large community.
- Robust handling of complex OpenAPI specifications.
- Cons:
- The generated Go code can feel less idiomatic (often resembles Java-style design patterns translated to Go).
- Requires Java runtime or Docker to run the generator, adding heavy dependencies to the build pipeline.
- Customization requires writing Java/Mustache templates, which is more complex than Go's native templating.
go-swagger
- Repository: github.com/go-swagger/go-swagger
- Description: A powerful and mature tool for Go, but primarily built for Swagger 2.0 (OpenAPI 2.0).
- Pros:
- Extremely mature and battle-tested in older Go projects.
- Cons:
- Lacks native support for OpenAPI 3.0/3.1. Since Prometheus uses OpenAPI 3.1+,
go-swagger is not suitable for this migration.
gnostic
- Repository: github.com/google/gnostic
- Description: Google's OpenAPI compiler that converts OpenAPI specs into Protocol Buffers, which can then be used to generate code.
- Pros:
- Extremely robust parser; great for cross-tool integration.
- Cons:
- Low-level and less focused on generating developer-friendly, idiomatic Go HTTP clients compared to
oapi-codegen.
The current Prometheus HTTP API client in Go (
github.com/prometheus/client_golang/api/prometheus/v1) is entirely hand-written. While it has served the community well, maintaining it manually poses maintenance overhead e.g. fixing bugs, syncing with Prometheus API changes.Prometheus now officially publishes and serves an OpenAPI specification (OpenAPI 3.1/3.2) at
/api/v1/openapi.yaml(see Prometheus API Documentation).Given that we could leverage this OpenAPI specification to generate a Go API client for a given version. In ideal world, that would be to have a job that automatically regenerates and proposes a PR whenever Prometheus changes spec. This could live in separate, clearly non-stable module (currently it's marked as experimental but it's shipped within stable module).
Challenges/Questions
model.Value(which can beVector,Matrix, etc.) andmodel.Time. A generated client will likely map responses to strict JSON-serializable Go structs generated from the OpenAPI schema, which might lose these convenient helper types.github.com/json-iterator/gowith highly optimized, customunsafedecoders for high-performance JSON parsing of Prometheus query results (e.g., optimizingSamplePairandSampleHistogramPairparsing).encoding/jsonor generic marshaling, which could introduce significant CPU and memory overhead when parsing large query results.oapi-codegen, we may need to customize the templates to usejson-iteratoror inject custom marshaling logic for critical hot-paths like matrix/vector query results.Some potential tools to use (researched with AI)
oapi-codegen(Recommended)kin-openapi).net/http, Chi, Echo, Gin, etc.).oneOf,anyOfcan sometimes lead to verbose or awkward Go helper types.go-swaggergo-swaggeris not suitable for this migration.gnosticoapi-codegen.