Skip to content

zoobz-io/openapi

Repository files navigation

OpenAPI

CI Status codecov Go Report Card CodeQL Go Reference License Go Version Release

OpenAPI 3.1 as native Go types. Build, read, and write API specifications with full type safety.

OpenAPI in Go

The OpenAPI specification becomes Go structs—each type mirrors the spec exactly:

spec := &openapi.OpenAPI{
    OpenAPI: "3.1.0",
    Info: openapi.Info{
        Title:   "Users API",
        Version: "1.0.0",
    },
    Paths: map[string]openapi.PathItem{
        "/users/{id}": {
            Get: &openapi.Operation{
                OperationID: "getUser",
                Parameters: []openapi.Parameter{{
                    Name:     "id",
                    In:       "path",
                    Required: true,
                    Schema:   &openapi.Schema{Type: openapi.NewSchemaType("string")},
                }},
                Responses: map[string]openapi.Response{
                    "200": {Description: "User found"},
                },
            },
        },
    },
}

No wrapper functions. No builder patterns. Just the specification as data.

Install

go get github.com/zoobz-io/openapi

Requires Go 1.24 or higher.

Quick Start

package main

import (
    "encoding/json"
    "fmt"
    "os"

    "github.com/zoobz-io/openapi"
    "gopkg.in/yaml.v3"
)

func main() {
    // Build a specification
    spec := &openapi.OpenAPI{
        OpenAPI: "3.1.0",
        Info: openapi.Info{
            Title:       "Pet Store",
            Version:     "1.0.0",
            Description: "A sample pet store API",
        },
        Paths: map[string]openapi.PathItem{
            "/pets": {
                Get: &openapi.Operation{
                    Summary:     "List all pets",
                    OperationID: "listPets",
                    Responses: map[string]openapi.Response{
                        "200": {
                            Description: "A list of pets",
                            Content: map[string]openapi.MediaType{
                                "application/json": {
                                    Schema: &openapi.Schema{
                                        Type:  openapi.NewSchemaType("array"),
                                        Items: &openapi.Schema{Ref: "#/components/schemas/Pet"},
                                    },
                                },
                            },
                        },
                    },
                },
            },
        },
        Components: &openapi.Components{
            Schemas: map[string]*openapi.Schema{
                "Pet": {
                    Type: openapi.NewSchemaType("object"),
                    Properties: map[string]*openapi.Schema{
                        "id":   {Type: openapi.NewSchemaType("integer")},
                        "name": {Type: openapi.NewSchemaType("string")},
                    },
                    Required: []string{"id", "name"},
                },
            },
        },
    }

    // Output as JSON
    json.NewEncoder(os.Stdout).Encode(spec)

    // Or YAML
    yaml.NewEncoder(os.Stdout).Encode(spec)

    // Read existing specs
    data, _ := os.ReadFile("api.yaml")
    var existing openapi.OpenAPI
    yaml.Unmarshal(data, &existing)
    fmt.Println(existing.Info.Title)
}

Why OpenAPI?

  • Direct mapping: Types match the OpenAPI 3.1 specification exactly—no translation layer
  • Full coverage: Every spec construct supported, from basic paths to discriminators and callbacks
  • Dual format: JSON and YAML serialization work identically via struct tags
  • Zero magic: Standard Go marshalling, no reflection tricks or code generation
  • Minimal footprint: Single dependency (yaml.v3), pure data structures

Documentation

  • Overview — Design philosophy and scope
  • Quick Start — Common usage patterns
  • Types — Type hierarchy and relationships

Contributing

Contributions welcome. See CONTRIBUTING.md for guidelines.

License

MIT