Skip to main content

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"}