Skip to content

Consider moving to OpenAPI based HTTP API #1998

@bwplotka

Description

@bwplotka

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

  1. How much of breaking changes this generation can produce?
  2. 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.
  1. Is such generated API good enough for functionality purposes (e.g. unknown OpenSpec limitations)? How to assure quality (testing)?
  2. 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.
  3. Should we even host generated code and ask anyone to generate themselves?

Some potential tools to use (researched with AI)

  1. 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.
  1. 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.
  1. 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.
  1. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions