Skip to content

[RFD]: choose HTTP API/client framework #113

@rainest

Description

@rainest

Decision Goal

We choose a framework for building HTTP APIs and clients

Category

Code Quality

Stakeholders / Affected Areas

Affects developers. Cross-cutting concerns with Architecture and Tooling areas.

Decision Needed By

A framework should simplify implementation of #107 and OpenCHAMI/community#34, and OpenCHAMI/community#27

Problem Statement

AFAIK current API handlers are hand-written (e.g. https://github.com/OpenCHAMI/power-control/blob/v2.7.0/internal/api/power-status.go or https://github.com/OpenCHAMI/smd/blob/v2.19.0/internal/hmsds/hmsds-api.go) and don't follow a common design. They can differ in significant ways (in the prior two examples, SMD's much more closely coupled to its storage engine).

Manually writing and maintaining generic CRUD endpoints and schemas for resources is tedious and error-prone. We should care mostly about writing structs, and have tooling automatically update API code and schemas on our behalf.

The same applies to API clients, which are often written per-service (e.g. https://github.com/OpenCHAMI/power-control/blob/v2.7.0/internal/hsm/state_manager.go) rather than imported from the struct owner. There's some effort to move away from that (e.g. OpenCHAMI/smd#74) but it's not yet using a framework.

Proposed Solution

I am not that familiar with framework options--I come from Kubernetes land, where those choices are largely made for you. This RFD is actively looking for other options or experience, but to start I'm using the time-honored "use reddit as a community survey" approach for a baseline. Options include:

  • The OpenAPI generator. Starts with OpenAPI specs and generates Go code.
  • Huma, which can target Chi or net/http, looks like it can help with OpenAPI manifest generation from structs, and supports several JSON patch standards.
  • Goa, which uses a bespoke DSL (but generates OpenAPI), and probably targets Chi (it doesn't say in the readme, but it does require Chi).
  • Fuego, which indirectly targets Chi and generates OpenAPI.

Alternatives Considered

I've had some discussion with Alex re using the Kubernetes SIG API Machinery tools (client-go, CRD implementation generators, etc.).

These do provide a very streamlined experience (write your struct and nothing else, receive a magically-generated client and server from the heavens) that I'd love to have again, but I doubt they've ever been used outside Kubernetes, or realistically can be. https://github.com/kubernetes/apimachinery states as much:

There are NO compatibility guarantees for this repository. It is in direct support of Kubernetes, so branches will track Kubernetes and be compatible with that repo. As we more cleanly separate the layers, we will review the compatibility guarantee.

They're also going to be tied to centralized API server model, whereas we have services each hosting their own APIs and managing their own data.

Barring someone showcasing prior art to the contrary, I don't expect this is a realistic option.

Other Considerations

Alex raised concerns around metaprogramming creating an additional layer of complexity that can be difficult to manage. I'll note that I'm not proposing we write our own templates: we should very much expect that the framework's done the heavy lifting of writing generator/generic code for us, and that other framework users have helped framework authors hammer out most of the bugs.

This doesn't rule out the chance that we'll encounter bugs, and we should consider whether frameworks provide break-out mechanisms if we need to substitute hand-authored code for generated bits if need be.


Re OpenCHAMI/community#27 we'll want to consider how we'd manage generating code for and serving multiple versions of the same resource. I don't know of the frameworks handling version conversion offhand, but they'd probably at least handle the front end endpoint code before handing it off to some version conversion code.

Related Docs / PRs

This was adapted from #107 (comment)

OpenCHAMI/community#34
OpenCHAMI/community#27
#107

Metadata

Metadata

Assignees

No one assigned

    Labels

    rfdRequest for Discussion

    Type

    No type

    Projects

    Status

    Todo

    Status

    In Progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions