Expose Thanos APIs to OpenAPI/protobuf and expose on website and UIs

Status
accepted
Owner
@Hangzhi

Expose Thanos APIs to OpenAPI/protobuf and expose on website and UIs

This design doc is proposing a design for Thanos HTTP API defined in protobuf and OpenAPI.

Motivations

To improve Thanos usage for users, we would like to define our HTTP APIs in protobuf/OpenAPI and expose those in the repository. OpenAPI is a language for describing REST APIs with a widely-used tooling ecosystem. With OpenAPI, developers can generate live documentation, validate APIs and even generate client and server stubs from OpenAPI to use our APIs efficiently. Also, the auto-generated documentation problem prevent documentation errors (Prometheus#7192, Prometheus#5567). Protocol Buffers (a.k.a., protobuf) is well-known as a mechanism for serializing structured data, and it’s usually used to define gRPC APIs. Also, protobuf specification could be used to define REST API. We hope to use protobuf to define our APIs for consistency, while we also want to leverage the tooling ecosystem of OpenAPI.

So, we want to define REST APIs in protobuf, generate OpenAPI definition from protobuf with gnostic. This would allow users to use tools for documentation, validation, type checking, and even interface code generation to use our APIs efficiently.

Similarly, we want to reuse this work in Prometheus.

Pitfalls of the current solution

  • Documentation, Server code, and client code boilerplate needs to be written manually.
  • Hand-written interface code is expensive to write and hard to maintain.
  • It’s hard to discover the current API programmatically.
  • When modifying the API, it is very difficult to know if this breaks downstream users.

Goals

  • Define all APIs in protobuf.
  • Be able to generate OpenAPI3 from protobuf.
  • Auto-generate documentation with OpenAPI3 specification.
  • Generate server code from API specification (OpenAPI3 or protobuf).

Non-Goals

  • Don’t mix gRPC with HTTP APIs in the same protobuf package

How

  • Define Thanos APIs in protobuf specification.
  • Generate OpenAPI from protobuf with gnostic extension.
  • Generate documentation from OpenAPI with Swagger.
  • Generate server and client API stubs from OpenAPI with Swagger.

Alternatives

Define HTTP RESTful API only in OpenAPI. Not in protobuf.

  1. Pros:

    1. There are might be some complexity, edge case and extra tooling to make the 3-step process (proto -> OpenAPI -> documentation to work.
  2. Cons:

    1. We write API definitions in protobuf for consistency. OpenAPI is less consistent compared to protobuf in a project built on Golang.
    2. Protobuf definition is more concise to write.

Define APIs in gRPC and have RESTful APIs alongside with grpc - gateway

  1. Pros:
    1. We can have gRPC and RESTful APIs at the same time.
    2. We have gRPC APIs like rules API.
  2. Cons:
    1. There are might be some complexity, edge cases and extra tooling to make the process (define gRPC API and get RESTful APIs with grpc-gateway) work.
    2. We need to redefine our API service in gRPC since most of Thanos APIs and Prometheus APIs are RESTful APIs.
    3. We need to run another sidecar (complexity of running the system).
    4. Semantics of gRPC and HTTP might be different and surprising for end user.
    5. We want to reuse in Prometheus and Prometheus does not support gRPC (gRPC dependency was removed from codebase).
    6. Same port library is not maintained. (cmux)

Action Plan

  • Experiments in rules API.
  • Define all HTTP APIs in Protobuf.
  • Generate documentation, client code, and server stubs from OpenAPI specification.