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>


Then, install the ogen tool.

go install -v

Generate code

Setup generator

Download petstore example.


Create generate.go file:

package project

//go:generate go run --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

├── 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 (

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) {
defer p.mux.Unlock()

p.pets[] = req
return req, nil

func (p *petsService) DeletePet(ctx context.Context, params petstore.DeletePetParams) (petstore.DeletePetOK, error) {
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) {
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) {
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!

package main

import (

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 {
if err := http.ListenAndServe(":8080", srv); err != nil {

Check that server started by creating pet

curl -X "POST" -H "Content-Type: application/json" --data "{\"name\":\"Cat\"}" http://localhost:8080/pet