Quick Start
Building a Specification
Construct specs using struct literals. Start with the root OpenAPI type and populate the fields you need:
package main
import (
"github.com/zoobz-io/openapi"
)
func main() {
spec := &openapi.OpenAPI{
OpenAPI: "3.1.0",
Info: openapi.Info{
Title: "Bookstore API",
Version: "1.0.0",
Description: "API for managing books",
},
Servers: []openapi.Server{
{URL: "https://api.bookstore.example.com"},
},
Paths: map[string]openapi.PathItem{
"/books": {
Get: &openapi.Operation{
Summary: "List books",
OperationID: "listBooks",
Responses: map[string]openapi.Response{
"200": {Description: "Book list"},
},
},
},
},
}
_ = spec
}
Reading Existing Specs
Parse JSON or YAML specs into Go types:
// From JSON
data, _ := os.ReadFile("api.json")
spec, err := openapi.FromJSON(data)
if err != nil {
log.Fatal(err)
}
// From YAML
data, _ := os.ReadFile("api.yaml")
spec, err := openapi.FromYAML(data)
if err != nil {
log.Fatal(err)
}
// Access fields directly
fmt.Println(spec.Info.Title)
for path, item := range spec.Paths {
if item.Get != nil {
fmt.Printf("GET %s: %s\n", path, item.Get.Summary)
}
}
Writing Specs
Serialize specs to JSON or YAML:
// To JSON
jsonBytes, err := spec.ToJSON()
os.WriteFile("api.json", jsonBytes, 0644)
// To YAML
yamlBytes, err := spec.ToYAML()
os.WriteFile("api.yaml", yamlBytes, 0644)
// Or use standard marshallers directly
json.NewEncoder(os.Stdout).Encode(spec)
yaml.NewEncoder(os.Stdout).Encode(spec)
Working with Schemas
Schemas represent JSON Schema objects. Use NewSchemaType to set the type field:
// Simple types
stringSchema := &openapi.Schema{
Type: openapi.NewSchemaType("string"),
}
// Nullable types (OpenAPI 3.1 style)
nullableString := &openapi.Schema{
Type: openapi.NewSchemaTypes([]string{"string", "null"}),
}
// Object with properties
userSchema := &openapi.Schema{
Type: openapi.NewSchemaType("object"),
Properties: map[string]*openapi.Schema{
"id": {Type: openapi.NewSchemaType("integer")},
"email": {Type: openapi.NewSchemaType("string"), Format: "email"},
},
Required: []string{"id", "email"},
}
// Array of references
usersSchema := &openapi.Schema{
Type: openapi.NewSchemaType("array"),
Items: &openapi.Schema{Ref: "#/components/schemas/User"},
}
Using References
Reference reusable components with the Ref field:
spec := &openapi.OpenAPI{
// ... info, paths ...
Components: &openapi.Components{
Schemas: map[string]*openapi.Schema{
"Error": {
Type: openapi.NewSchemaType("object"),
Properties: map[string]*openapi.Schema{
"code": {Type: openapi.NewSchemaType("integer")},
"message": {Type: openapi.NewSchemaType("string")},
},
},
},
Responses: map[string]*openapi.Response{
"NotFound": {
Description: "Resource not found",
Content: map[string]openapi.MediaType{
"application/json": {
Schema: &openapi.Schema{Ref: "#/components/schemas/Error"},
},
},
},
},
},
}
// Reference in an operation
operation := &openapi.Operation{
Responses: map[string]openapi.Response{
"404": {Ref: "#/components/responses/NotFound"},
},
}
Security Schemes
Define authentication methods in components:
spec.Components = &openapi.Components{
SecuritySchemes: map[string]*openapi.SecurityScheme{
"bearerAuth": {
Type: "http",
Scheme: "bearer",
BearerFormat: "JWT",
},
"apiKey": {
Type: "apiKey",
Name: "X-API-Key",
In: "header",
},
},
}
// Apply globally
spec.Security = []openapi.SecurityRequirement{
{"bearerAuth": {}},
}
// Or per-operation
operation.Security = []openapi.SecurityRequirement{
{"apiKey": {}},
}