Skip to main content

Examples

This page collects small, focused examples. For a complete runnable project, see the Getting started guide and the ogen-go/example repository.

Real-world specifications

ogen is tested against a large set of real-world OpenAPI documents. Each of these is generated in CI from the examples directory:

APISpec
GitHubapi.github.com.json
Kubernetesk8s.json
OpenAIopenai.openapi.yaml
Telegram Bot APItelegram_bot_api.json
Firecrackerfirecracker.json
Petstore (expanded)petstore-expanded.yml

Generation is driven by go:generate directives. A typical one looks like:

generate.go
package api

//go:generate go tool ogen --clean --config .ogen.yml --target api github.json

Larger specs like GitHub and Kubernetes rely on type inference and skipping not-yet-supported operations:

.ogen.yml
parser:
infer_types: true
generator:
ignore_not_implemented: ["all"]

See Config for the full list of options.

Optional and nullable fields

ogen avoids pointers for optional and nullable values. Given this schema:

components:
schemas:
Pet:
type: object
required: [id, name]
properties:
id:
type: integer
format: int64
name:
type: string
nickname:
type: string
nullable: true
tag:
type: string
format: uuid

ogen generates wrappers instead of pointers:

type Pet struct {
ID int64 `json:"id"`
Name string `json:"name"`
Nickname OptNilString `json:"nickname"` // optional + nullable
Tag OptUUID `json:"tag"` // optional uuid.UUID
}

Each wrapper comes with helpers:

pet := Pet{ID: 1, Name: "Cat"}
pet.Tag = NewOptUUID(uuid.New())

if v, ok := pet.Tag.Get(); ok {
fmt.Println("tag:", v)
}

pet.Nickname = NewOptNilString("Kitty")
pet.Nickname.SetToNull() // encodes as JSON null

Sum types from oneOf

A oneOf with a discriminator becomes a Go sum type:

components:
schemas:
Animal:
oneOf:
- $ref: "#/components/schemas/Cat"
- $ref: "#/components/schemas/Dog"
discriminator:
propertyName: kind
mapping:
cat: "#/components/schemas/Cat"
dog: "#/components/schemas/Dog"

The generated type carries the active variant and helper constructors:

type Animal struct {
Type AnimalType // "Cat" or "Dog"
Cat Cat
Dog Dog
}

func NewCatAnimal(v Cat) Animal
func NewDogAnimal(v Dog) Animal

Switch on the variant when handling a response:

switch a.Type {
case CatAnimal:
fmt.Println("meow:", a.Cat.Name)
case DogAnimal:
fmt.Println("woof:", a.Dog.Name)
}

ogen can also infer the discriminator automatically when none is defined — by type, by unique field names, or by enum values. See the sum types reference for details.

Server-Sent Events

For text/event-stream responses, ogen generates an SSE client:

paths:
/events:
get:
operationId: streamEvents
responses:
'200':
description: Event stream
content:
text/event-stream:
schema:
type: object
properties:
message:
type: string
createdAt:
type: string
format: date-time

The generated client exposes an iterator over events and handles reconnection automatically:

stream, err := client.StreamEvents(ctx)
if err != nil {
return err
}
defer stream.Close()

for ev, err := range stream.All(ctx) {
if err != nil {
return err
}
fmt.Println(ev.Data.Message)
}

Securing requests

Security schemes become a SecuritySource interface you implement once. For an API secured with a bearer token:

components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
security:
- bearerAuth: []
type securitySource struct {
token string
}

func (s securitySource) BearerAuth(ctx context.Context, operationName api.OperationName) (api.BearerAuth, error) {
return api.BearerAuth{Token: s.token}, nil
}

client, err := api.NewClient(server, securitySource{token: os.Getenv("TOKEN")})

The token is then attached to every request that requires it.