Use oapi-codegen by first installing the CLI tool, then running it against your OpenAPI specification file to generate Go client, server, and model code. You can customize the output using flags or a YAML configuration file to specify which packages to generate and where to place them.
Install the tool via Go modules and run it directly from your project directory. For a quick start, use the CLI flags to generate a client and server stubs from a swagger.yaml file:
go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest
oapi-codegen -generate types,client,server -package api swagger.yaml > api/generated.go
This command generates type definitions, a typed HTTP client, and server interface stubs in a single file. The -package flag sets the Go package name, while the -generate flag controls the output types. If you need more control, such as splitting files or adding custom headers, create a .oapi-codegen.yaml config file:
package: api
output: api/generated.go
generate:
types: true
client: true
server: true
strict-server: false
Then run the generator with the config flag:
oapi-codegen -config .oapi-codegen.yaml swagger.yaml
Once generated, implement the server interface in your code. The tool creates an interface (e.g., ServerInterface) that you must implement to handle requests. Here is a minimal example of implementing a handler:
type serverImpl struct{}
func (s *serverImpl) GetUsers(w http.ResponseWriter, r *http.Request) {
// Your business logic here
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode([]User{{ID: 1, Name: "Alice"}})
}
func main() {
server := &serverImpl{}
handler := api.HandlerFromMux(server)
http.ListenAndServe(":8080", handler)
}
For the client side, the generated code provides a typed client that handles serialization and URL construction automatically:
client, err := api.NewClient("http://localhost:8080", nil)
if err != nil {
log.Fatal(err)
}
users, err := client.GetUsers(context.Background())
if err != nil {
log.Fatal(err)
}
Always run go generate in your build pipeline if you integrate this into your workflow, ensuring the generated code stays in sync with your API spec. If your spec changes, simply re-run the command to update the Go files.