Quick start
ogen is a powerful and fast OpenAPI v3 code generator for Go.
Prepare environment
Create Go module.
go mod init <project>
Installation
Then, install the ogen
tool.
go install -v github.com/ogen-go/ogen/cmd/ogen@latest
Generate code
Setup generator
Download petstore example.
wget https://raw.githubusercontent.com/ogen-go/web/main/examples/petstore.yml
Create generate.go
file:
<project>/generate.go
package project
//go:generate go run github.com/ogen-go/ogen/cmd/ogen --target petstore --clean petstore.yml
Then go to the root directory of your module, and run:
go generate ./...
ogen
will generate new folder with several files
petstore
├── oas_cfg_gen.go
├── oas_client_gen.go
├── oas_defaults_gen.go
├── oas_handlers_gen.go
├── oas_interfaces_gen.go
├── oas_json_gen.go
├── oas_param_dec_gen.go
├── oas_param_gen.go
├── oas_req_dec_gen.go
├── oas_req_enc_gen.go
├── oas_res_dec_gen.go
├── oas_res_enc_gen.go
├── oas_router_gen.go
├── oas_schemas_gen.go
├── oas_server_gen.go
├── oas_validators_gen.go
Using generated server
To get started, implement Handler
interface generated by ogen
tool.
// Handler handles operations described by OpenAPI v3 specification.
type Handler interface {
// AddPet implements addPet operation.
//
// Add a new pet to the store.
//
// POST /pet
AddPet(ctx context.Context, req Pet) (Pet, error)
// DeletePet implements deletePet operation.
//
// DELETE /pet/{petId}
DeletePet(ctx context.Context, params DeletePetParams) (DeletePetOK, error)
// GetPetById implements getPetById operation.
//
// Returns a single pet.
//
// GET /pet/{petId}
GetPetById(ctx context.Context, params GetPetByIdParams) (GetPetByIdRes, error)
// UpdatePet implements updatePet operation.
//
// POST /pet/{petId}
UpdatePet(ctx context.Context, params UpdatePetParams) (UpdatePetOK, error)
}
package main
import (
"context"
"sync"
petstore "<project>/petstore"
)
type petsService struct {
pets map[int64]petstore.Pet
id int64
mux sync.Mutex
}
func (p *petsService) AddPet(ctx context.Context, req petstore.Pet) (petstore.Pet, error) {
p.mux.Lock()
defer p.mux.Unlock()
p.pets[p.id] = req
p.id++
return req, nil
}
func (p *petsService) DeletePet(ctx context.Context, params petstore.DeletePetParams) (petstore.DeletePetOK, error) {
p.mux.Lock()
defer p.mux.Unlock()
delete(p.pets, params.PetId)
return petstore.DeletePetOK{}, nil
}
func (p *petsService) GetPetById(ctx context.Context, params petstore.GetPetByIdParams) (petstore.GetPetByIdRes, error) {
p.mux.Lock()
defer p.mux.Unlock()
pet, ok := p.pets[params.PetId]
if !ok {
// Return Not Found.
return &petstore.GetPetByIdNotFound{}, nil
}
return &pet, nil
}
func (p *petsService) UpdatePet(ctx context.Context, params petstore.UpdatePetParams) (petstore.UpdatePetOK, error) {
p.mux.Lock()
defer p.mux.Unlock()
pet := p.pets[params.PetId]
pet.Status = params.Status
if val, ok := params.Name.Get(); ok {
pet.Name = val
}
p.pets[params.PetId] = pet
return petstore.UpdatePetOK{}, nil
}
Run server
Now, we are ready to run our server!
main.go
package main
import (
"log"
"net/http"
petstore "<project>/petstore"
)
func main() {
// Create service instance.
service := &petsService{
pets: map[int64]petstore.Pet{},
}
// Create generated server.
srv, err := petstore.NewServer(service)
if err != nil {
log.Fatal(err)
}
if err := http.ListenAndServe(":8080", srv); err != nil {
log.Fatal(err)
}
}
Check that server started by creating pet
curl -X "POST" -H "Content-Type: application/json" --data "{\"name\":\"Cat\"}" http://localhost:8080/pet
{"name":"Cat"}