oapi-gen
An opinionated (read: simplistic, maybe a bit too much) code generator for Go services from OpenAPI v3.0 specifications, inspired a bit by protocol buffers and their generated gRPC handlers.
Check out the ticket tracker for issues.
Structure
The generated code uses api
as its package name. That's currently hard-coded but might be exposed as a parameter in the future if it becomes necessary.
The generated code consist of type definitions for the component schemas and the request and response bodies form the spec, as well as decoding handlers for all paths in the spec and a net/http.Handler
that muxes requests to the appropriate handler.
Decoding handlers decode the incoming request body and URL parameters into a generated request struct (named after the operation ID of the path, suffixed with Request
). They then call a request handler (provided by you) that takes a context.Context
and a request value as its parameters and returns a response value and, if applicable, an error
. Response structs are generated from the specification for the responses. There is a response struct for each HTTP status code in the spec.
If an operation named updateFoo
has response codes 201 and 404 defined, for example, the generated response structs will be called UpdateFooResponse201
and UpdateFooResponse404
.
If the handler returns a value of type UpdateFooResponse404
, the resulting HTTP status code will be 404, with the JSON-encoded value of the response as its response body.
If you return an error from the handler, this is taken to mean "unexpected error". In that case, the decoding handler wrapper will call the method HandleUnexpectedError
on the request handler and pass it the request context, an net/http.ResponseWriter
, a net/http.(*Request)
and the error. That method can then handle the error as you see fit, for example by logging it somehow and responding with an HTTP 500 on the response writer.
(Current) limitations
- only
application/json
is supported as the encoding for response bodies, and in some places it is implied
application/json
and multipart/form-data
are the only MIME types supported for request bodies, and support for form data is very rudimentary: you get a mime/multipart.Reader
that you need to read yourself
- very limited support for optional/required values:
- optional values are encoded as
omitempty
when encoding responses
- optional values on requests and objects are pointers to their underlying value.
- there is no way to set response headers, or access request headers
- uses
github.com/gorilla/mux
as the request mux, which is not currently maintained (but does what I want and seems OK to use for now)
- there probably ought to be at least one example of how to actually use this thing
- the code is atrocious
- maybe more
Caveat Emptor
I use this thing to generate the api for a particular client project. It supports only the subset of OpenAPI that is required by that project. It may or may not work for you.
If you do use this thing to generate your own code, drop me a line (at gbe@unobtanium.de), so that if (and when) I make breaking changes in the generated code, I can give you a heads up or check back with you if I can support your use case without breaking code you rely on. Otherwise, I will chose the easiest and most sustainable route for my client's project and myself.