### Basic Ogen Code Generation Setup Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/10-code-generation.md Example of setting up and running the Ogen code generator to process an OpenAPI specification and generate Go code. ```go package main import ( "log" "github.com/ogen-go/ogen" "github.com/ogen-go/ogen/gen" "github.com/ogen-go/ogen/gen/genfs" os ) func main() { // Read specification data, err := os.ReadFile("openapi.yaml") if err != nil { log.Fatal(err) } // Parse specification spec, err := ogen.Parse(data) if err != nil { log.Fatal(err) } // Configure generation opts := gen.Options{} opts.Parser.SetLocation("openapi.yaml", gen.RemoteOptions{}) opts.Generator.Package = "myapi" opts.Generator.Out = "./api" opts.Generator.ClientName = "MyClient" // Create generator g, err := gen.NewGenerator(spec, opts) if err != nil { log.Fatal(err) } // Generate code fs := genfs.FormattedSource{ Format: true, Root: "./api", } if err := g.WriteSource(fs, "myapi"); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Example Middleware Chaining Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/5-middleware-api.md Demonstrates how to create and chain custom logging and authorization middleware functions using ChainMiddlewares. Includes setup for request context and error handling. ```go package main import ( "context" "log" "github.com/ogen-go/ogen/middleware" ) // Logging middleware func loggingMiddleware(req middleware.Request, next middleware.Next) (middleware.Response, error) { log.Printf("Request: %s %s", req.OperationName, req.OperationID) resp, err := next(req) log.Printf("Response: %v, Error: %v", resp.Type, err) return resp, err } // Authorization middleware func authMiddleware(req middleware.Request, next middleware.Next) (middleware.Response, error) { // Check authorization authHeader, ok := req.Raw.Header["Authorization"] if !ok { return middleware.Response{}, errors.New("missing authorization header") } // Add auth info to context ctx := context.WithValue(req.Context, "auth", authHeader) req.SetContext(ctx) return next(req) } // Use in server chain := middleware.ChainMiddlewares(loggingMiddleware, authMiddleware) ``` -------------------------------- ### Generate project examples Source: https://github.com/ogen-go/ogen/blob/main/CONTRIBUTING.md Updates the generated code for the project examples. ```console $ make generate examples ``` -------------------------------- ### Ogen Configuration File Example Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/12-cli-reference.md Example of an 'ogen.yaml' configuration file specifying parser and generator settings. ```yaml parser: infer_types: true allow_remote: false depth_limit: 1000 allow_cross_type_constraints: true generator: package: myapi out: ./api clean: true client_name: Client server_name: Server features: router: true tests: false operation_groups: true ``` -------------------------------- ### Install Ogen CLI Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/12-cli-reference.md Installs the ogen CLI tool globally using go install. Ensure your Go environment is set up correctly. ```bash go install -v github.com/ogen-go/ogen/cmd/ogen@latest ``` -------------------------------- ### Build Command for Customization Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/14-configuration-reference.md Example of how to run the Go build command with linker flags to set `apiPackage` and `apiOut` variables. ```bash go run -ldflags "-X main.apiPackage=myapi -X main.apiOut=./generated" generate.go ``` -------------------------------- ### Basic Server Implementation in Go Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/13-patterns-and-examples.md Illustrates how to implement handlers for API endpoints and start an HTTP server. Handlers should match the API interface. ```go package main import ( "context" "log" "net/http" "github.com/myapp/api" ) type Handler struct { // dependencies } func (h *Handler) GetUser(ctx context.Context, params api.GetUserParams) (*api.User, error) { return &api.User{ ID: params.UserID, Name: "Alice", }, nil } func (h *Handler) CreateUser(ctx context.Context, req *api.CreateUserRequest) (*api.User, error) { return &api.User{ ID: "new-id", Name: req.Name, }, nil } func main() { h := &Handler{} server := api.NewServer(h) log.Fatal(http.ListenAndServe(":8080", server)) } ``` -------------------------------- ### Install Ogen CLI Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/README.md Installs the Ogen command-line interface tool using Go modules. ```bash go install github.com/ogen-go/ogen/cmd/ogen@latest ``` -------------------------------- ### JSON API Usage Example Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/3-json-api.md Demonstrates encoding a custom `Product` struct to JSON using `json.Encode` and `json.Marshal`. ```go package main import ( "github.com/ogen-go/ogen/json" "github.com/go-faster/jx" "log" ) type Product struct { ID int64 Name string Price float64 } func (p *Product) Encode(e *jx.Encoder) { e.ObjStart() e.FieldStart("id") e.Int64(p.ID) e.FieldStart("name") e.Str(p.Name) e.FieldStart("price") e.Float64(p.Price) e.ObjEnd() } func main() { p := &Product{ID: 1, Name: "Widget", Price: 9.99} // Encode to JSON data := json.Encode(p) log.Printf("Encoded: %s", string(data)) // Or use Marshal for standard encoding data2, _ := json.Marshal(p) log.Printf("Marshaled: %s", string(data2)) } ``` -------------------------------- ### Accessing Path Parameter Example Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/5-middleware-api.md Demonstrates how to access a path parameter named 'userID' from the Parameters map. ```go userID, ok := params.Path("userID") if !ok { // parameter not found } ``` -------------------------------- ### Makefile Integration for Ogen Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/12-cli-reference.md Set up a Makefile to manage Ogen code generation and building. Includes installing the Ogen binary and running the generation command before building the project. ```makefile .PHONY: generate generate: go install github.com/ogen-go/ogen/cmd/ogen@latest ogen --target ./api --package api openapi.yaml .PHONY: build build: generate go build ./... ``` -------------------------------- ### Example Struct Definition Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/9-openapi-types.md Defines the structure for an Example object in OpenAPI, used to provide examples of field values. It includes fields for summary, description, value, and an external value URL. ```go type Example struct { // Example summary Summary string // Example description Description string // Example value Value RawValue // External example URL ExternalValue string } ``` -------------------------------- ### Updating Request Context Example Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/5-middleware-api.md Shows how to create a new context with an added value and update the request's context using SetContext. ```go ctx = context.WithValue(r.Context, "user_id", userID) r.SetContext(ctx) ``` -------------------------------- ### Injecting Logging Middleware Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/11-advanced-features.md Add custom middleware to the generated server to intercept and process requests. This example shows how to add a logging middleware. ```go import "github.com/ogen/ogen/middleware" loggingMiddleware := func(req middleware.Request, next middleware.Next) (middleware.Response, error) { log.Printf("Operation: %s", req.OperationName) return next(req) } opts := []server.Option{ server.WithMiddleware(loggingMiddleware), } srv := server.NewServer(handler, opts...) ``` -------------------------------- ### Ogen FileSystem Interface Example Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/10-code-generation.md Implement the `FileSystem` interface to abstract file writing operations. The `FormattedSource` provides a standard implementation that applies `gofmt` to the generated files and writes them to a specified root directory. ```go // Standard filesystem writing fs := genfs.FormattedSource{ Format: true, // Apply gofmt Root: "./api", // Output directory } ``` -------------------------------- ### Server-Sent Events Usage Example Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/11-advanced-features.md Demonstrates how to consume events from a Server-Sent Events stream. Ensure to handle errors and close the client when done. ```go client, _ := apiClient.Stream(ctx) for event, err := range client.All(ctx) { if err != nil { log.Printf("Error: %v", err) continue } process(event) } _ = client.Close() ``` -------------------------------- ### Define simple schema for uniqueItems Source: https://github.com/ogen-go/ogen/blob/main/internal/integration/test_complex_uniqueitems/README.md Example YAML schema configuration for nested objects. ```yaml WorkflowStatus: type: object required: [id, name] properties: id: {type: string} name: {type: string} description: {type: string} properties: $ref: '#/components/schemas/StatusProperties' ``` -------------------------------- ### Implement Handler Interfaces in Go Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/11-advanced-features.md Provides an example of how to implement the generated handler interfaces in Go. This involves creating a struct that embeds the interfaces and provides concrete implementations for the methods. ```go type impl struct{} func (impl) ListUsers(ctx context.Context) (*UserList, error) { ... } func (impl) GetUser(ctx context.Context, params GetUserParams) (*User, error) { ... } func (impl) ListPosts(ctx context.Context) (*PostList, error) { ... } server := NewServer(&impl{}) ``` -------------------------------- ### Example Usage of Int Validation (Go) Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/8-validation-api.md Demonstrates how to create and use an `Int` validator to check if a value falls within a specified range. Ensure the `ptrTo` helper function is available. ```go // Generated validation for field with minimum: 0, maximum: 100 validator := validate.Int{ Min: ptrTo(int64(0)), Max: ptrTo(int64(100)), } if err := validator.Validate(75); err != nil { // Error if value out of range } ``` -------------------------------- ### Generated Handler Interfaces for Operation Groups Source: https://github.com/ogen-go/ogen/blob/main/README.md Shows example Go handler interfaces generated for API operations grouped by `x-ogen-operation-group`. ```go // x-ogen-operation-group: Images type ImagesHandler interface { ListImages(ctx context.Context, req *ListImagesRequest) (*ListImagesResponse, error) GetImageByID(ctx context.Context, req *GetImagesByIDRequest) (*GetImagesByIDResponse, error) } // x-ogen-operation-group: Users type UsersHandler interface { ListUsers(ctx context.Context, req *ListUsersRequest) (*ListUsersResponse, error) } type Handler interface { ImagesHandler UsersHandler // All un-grouped operations will be on this interface } ``` -------------------------------- ### Go Client for Large Array Upload Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/14-configuration-reference.md Example Go function demonstrating how to use a streaming decoder for uploading large JSON arrays without loading the entire body into memory. ```go func (c *Client) uploadLargeArray(ctx context.Context, req *UploadRequest) error { // Streams JSON array without loading into memory } ``` -------------------------------- ### Helper Methods for OptNilString in Go Source: https://github.com/ogen-go/ogen/blob/main/README.md Provides convenience methods for checking the state (get, isNull, isSet, isEmpty) of an optional nullable string. ```go func (OptNilString) Get() (v string, ok bool) func (OptNilString) IsNull() bool func (OptNilString) IsSet() bool func (OptNilString) IsEmpty() bool ``` ```go func NewOptNilString(v string) OptNilString ``` -------------------------------- ### Ogen Environment Variables Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/12-cli-reference.md Examples of environment variables that can be used to control Ogen's behavior, such as debug output, Go version, and log level. ```bash # Enable debug output OGEN_DEBUG=1 ``` ```bash # Custom Go version for formatting GO_VERSION=1.25 ``` ```bash # Log level LOG_LEVEL=debug ``` -------------------------------- ### Generated Client Method Signature Source: https://github.com/ogen-go/ogen/blob/main/README.md Example of a Go client method signature generated by Ogen. This shows how to call an API endpoint, including the parameters structure and the method signature. ```go type PetGetByNameParams struct { Name string } // GET /pet/{name} func (c *Client) PetGetByName(ctx context.Context, params PetGetByNameParams) (res Pet, err error) ``` -------------------------------- ### Passing Security Handlers to Server Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/11-advanced-features.md Configure the Ogen Go server with custom security handler implementations for authentication. This example shows how to pass a SecurityHandlers struct to the server constructor. ```go srv := server.NewServer( handler, server.WithSecurityHandlers(&SecurityHandlers{ BearerToken: validateBearer, ApiKey: validateApiKey, }), ) ``` -------------------------------- ### Generated Server Interface Source: https://github.com/ogen-go/ogen/blob/main/README.md Example of a Go server interface generated by Ogen. This interface defines the methods that a server implementation must provide to handle API requests. ```go // Server handles operations described by OpenAPI v3 specification. type Server interface { PetGetByName(ctx context.Context, params PetGetByNameParams) (Pet, error) // ... } ``` -------------------------------- ### Ogen Go Code Generation Pipeline Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/00-START-HERE.md Illustrates the sequence of steps involved in generating Go code from an OpenAPI specification using Ogen. This pipeline starts with parsing the OpenAPI spec and ends with the generated Go source code. ```text OpenAPI Spec (YAML/JSON) ↓ ogen.Parse() ↓ gen.NewGenerator() ↓ generator.WriteSource() ↓ Generated Go Code ``` -------------------------------- ### Test Generated Go API Handler Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/13-patterns-and-examples.md Write unit tests for your generated API handler using standard Go testing practices. This example demonstrates testing the `GetUser` operation by creating a handler instance and asserting the response. ```go import ( "context" "testing" "github.com/myapp/api" "github.com/stretchr/testify/assert" ) func TestGetUser(t *testing.T) { handler := &Handler{} user, err := handler.GetUser(context.Background(), api.GetUserParams{ UserID: "123", }) assert.NoError(t, err) assert.Equal(t, "123", user.ID) } ``` -------------------------------- ### Ogen Code Generation with Custom Features Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/10-code-generation.md Example of configuring Ogen code generation with custom features like schema type inference, remote schema allowance, router generation, tests, and operation groups. ```go opts := gen.Options{} opts.Parser.InferSchemaType = true opts.Parser.AllowRemote = true opts.Generator.Features.Router = true opts.Generator.Features.Tests = true opts.Generator.Features.OperationGroups = true g, _ := gen.NewGenerator(spec, opts) ``` -------------------------------- ### Basic Client Usage in Go Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/13-patterns-and-examples.md Shows how to create a client and make a request to an API endpoint. Ensure the API base URL is correctly provided. ```go package main import ( "context" "log" "github.com/myapp/api" ) func main() { // Create client client, err := api.NewClient("https://api.example.com") if err != nil { log.Fatal(err) } // Make request ctx := context.Background() user, err := client.GetUser(ctx, api.GetUserParams{ UserID: "123", }) if err != nil { log.Fatal(err) } log.Printf("User: %s", user.Name) } ``` -------------------------------- ### Build a Server in Go Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/00-START-HERE.md Implement handler methods for API endpoints and create a new server instance. The server will listen on the specified port. ```go type Handler struct{} func (h *Handler) GetUser(ctx context.Context, params api.GetUserParams) (*api.User, error) { return &api.User{ID: params.ID, Name: "Alice"}, nil } server := api.NewServer(&Handler{}) http.ListenAndServe(":8080", server) ``` -------------------------------- ### Example Custom Email Validator Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/8-validation-api.md An example of a custom validator function that checks if a given string has a valid email format. It performs type assertion and checks for the presence of '@'. ```go func emailValidator(value any, params any) error { s, ok := value.(string) if !ok { return fmt.Errorf("expected string, got %T", value) } if !strings.Contains(s, "@") { return errors.New("invalid email format") } return nil } ``` -------------------------------- ### Build a Client in Go Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/00-START-HERE.md Instantiate a new API client with the base URL and make requests to specific endpoints. Ensure necessary context is provided. ```go client, _ := api.NewClient("https://api.example.com") resp, _ := client.GetUser(ctx, api.GetUserParams{ID: "123"}) ``` -------------------------------- ### Code-Generated Type Implementation Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/3-json-api.md Example of a typical generated type implementing `json.Unmarshaler` and `json.Marshaler` interfaces for optimized JSON handling. ```go type User struct { ID int64 Name string } // Decode implements json.Unmarshaler func (u *User) Decode(d *jx.Decoder) error { return d.ObjBytes(func(d *jx.Decoder, k []byte) error { switch string(k) { case "id": v, err := d.Int64() u.ID = v return err case "name": v, err := d.Str() u.Name = v return err default: return d.Skip() } }) } // Encode implements json.Marshaler func (u *User) Encode(e *jx.Encoder) { e.ObjStart() e.FieldStart("id") e.Int64(u.ID) e.FieldStart("name") e.Str(u.Name) e.ObjEnd() } ``` -------------------------------- ### MediaType Type Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/9-openapi-types.md Defines the structure for a media type within a request or response body, including its schema, examples, and encoding details. ```APIDOC ## MediaType Type ### Description Specifies the schema, examples, and encoding for a particular media type (e.g., `application/json`) within a request or response body. ### Go Struct ```go type MediaType struct { // Schema describing the content Schema *Schema // Example value Example RawValue // Examples with descriptions Examples map[string]*Example // Encoding instructions Encoding map[string]*Encoding } ``` ``` -------------------------------- ### Logging and Authentication Middleware in Go Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/13-patterns-and-examples.md Demonstrates how to create and apply custom middleware for logging request duration and authenticating requests. Ensure necessary imports are present. ```go import ( "log" time "time" "github.com/myapp/api" "github.com/ogen-go/ogen/middleware" ) func loggingMiddleware(req middleware.Request, next middleware.Next) (middleware.Response, error) { start := time.Now() log.Printf("[%s] %s started", req.OperationName, req.Raw.Method, ) resp, err := next(req) log.Printf("[%s] completed in %v, error: %v", req.OperationName, time.Since(start), err, ) return resp, err } func authMiddleware(req middleware.Request, next middleware.Next) (middleware.Response, error) { token, ok := req.Raw.Header["Authorization"] if !ok { return middleware.Response{}, errors.New("missing authorization") } // Validate token and add to context ctx := context.WithValue(req.Context, "auth", token) req.SetContext(ctx) return next(req) } // Apply to server handler := &Handler{} chain := middleware.ChainMiddlewares(loggingMiddleware, authMiddleware) server := api.NewServer( handler, api.WithMiddleware(chain), ) ``` -------------------------------- ### OpenAPI MediaType Struct Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/9-openapi-types.md Defines the structure for a media type within a request body or response, including its schema, examples, and encoding. ```go type MediaType struct { // Schema describing the content Schema *Schema // Example value Example RawValue // Examples with descriptions Examples map[string]*Example // Encoding instructions Encoding map[string]*Encoding } ``` -------------------------------- ### Constructing an OpenAPI Specification Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/9-openapi-types.md This Go snippet demonstrates how to build an OpenAPI specification using the `ogen` library. It includes setting the OpenAPI version, API information, server URLs, and defining a schema for a 'Pet' object with various properties and constraints. ```Go package main import ( "github.com/ogen/ogen" ) func main() { spec := ogen.NewSpec(). SetOpenAPI("3.0.0"). SetInfo(&ogen.Info{ Title: "Pet Store", Version: "1.0.0", Description: "Sample pet store API", }). AddServers(&ogen.Server{ URL: "https://api.example.com", }). AddSchema("Pet", &ogen.Schema{ Type: "object", Description: "A pet in the store", Properties: map[string]*ogen.Schema{ "id": { Type: "integer", Format: "int64", }, "name": { Type: "string", MinLength: 1, MaxLength: 100, }, "status": { Type: "string", Enum: ogen.Enum{Values: []any{"available", "sold"}}, }, }, Required: []string{"id", "name"}, }) _ = spec } ``` -------------------------------- ### Server Creation with Middleware Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/5-middleware-api.md Generated servers accept a middleware option during creation. The middleware is applied to all operations in the server. ```go server := api.NewServer( handler, api.WithMiddleware(chain), ) ``` -------------------------------- ### Set Root Package Path for Imports Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/12-cli-reference.md Configures the root package path for absolute imports, which is particularly useful in monorepo setups. ```bash --root-package myapp ``` -------------------------------- ### Running Ogen with Configuration File Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/14-configuration-reference.md Execute the Ogen CLI tool, specifying the path to your configuration file and the OpenAPI specification. ```bash ogen --config ogen.yaml openapi.yaml ``` -------------------------------- ### Ogen CLI Performance Tip: Use Local Files Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/12-cli-reference.md Run Ogen with local OpenAPI files instead of remote references for faster processing. ```bash # Faster than --allow-remote ogen openapi.yaml ``` -------------------------------- ### Basic Ogen CLI Usage Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/12-cli-reference.md The fundamental command structure for running the ogen CLI. Replace with your OpenAPI specification file. ```bash ogen [flags] ``` -------------------------------- ### Streaming Server-Sent Events (SSE) in Go Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/13-patterns-and-examples.md Shows how to implement a handler for streaming events and how a client can consume these events. Requires the 'context' and 'ogen/sse' packages. ```go import ( "context" "github.com/myapp/api" "github.com/ogen-go/ogen/sse" ) func (h *Handler) StreamEvents(ctx context.Context) (api.EventsStream, error) { // This returns a client that will receive events // Implementation depends on generated code return h.client.StreamEvents(ctx) } // Consumer side func consumeEvents(client *api.Client, ctx context.Context) error { stream, err := client.StreamEvents(ctx) if err != nil { return err } defer stream.Close() for event, err := range stream.All(ctx) { if err != nil { log.Printf("Event error: %v", err) continue } log.Printf("Event: %s", event.Message) } return nil } ``` -------------------------------- ### Example Schema with Const Values Source: https://github.com/ogen-go/ogen/blob/main/README.md This YAML schema defines an ErrorResponse object with 'code' and 'status' fields having constant integer and string values, respectively. ```yaml components: schemas: ErrorResponse: type: object properties: code: type: integer const: 400 status: type: string const: "error" message: type: string ``` -------------------------------- ### OpenAPI oneOf with Field Value Discrimination Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/11-advanced-features.md Example OpenAPI schema using `oneOf` where variants are distinguished by different enum values for the same field (`status`). ```yaml oneOf: - type: object required: [status] properties: status: type: string enum: [active, pending] - type: object required: [status] properties: status: type: string enum: [inactive, deleted] ``` -------------------------------- ### Create and Configure OpenAPI Spec with DSL Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/1-core-api.md Demonstrates using the fluent API (DSL) to programmatically create and configure an OpenAPI Specification object. This is useful for dynamically generating specifications. ```go spec := ogen.NewSpec(). SetOpenAPI("3.0.0"). SetInfo(&ogen.Info{ Title: "Pet Store API", Version: "1.0.0", }). AddServers(&ogen.Server{ URL: "https://api.example.com/v1", }) ``` -------------------------------- ### Run Techempower Benchmark with 20 GOMAXPROCS Source: https://github.com/ogen-go/ogen/blob/main/internal/integration/cmd/README.md Executes the techempower benchmark with GOMAXPROCS set to 20. ```console GOMAXPROCS=20 techempower ``` -------------------------------- ### Generated User Validation Function Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/8-validation-api.md Example of generated Go code for validating a User struct. It includes checks for email length and custom validation rules. ```go func (u *User) Validate() error { var errs []validate.FieldError // Email validation (minLength: 1, maxLength: 255) if len(u.Email) < 1 { errs = append(errs, validate.FieldError{ Name: "email", Error: &validate.MinLengthError{ Len: len(u.Email), MinLength: 1, }, }) } if len(u.Email) > 255 { errs = append(errs, validate.FieldError{ Name: "email", Error: &validate.MaxLengthError{ Len: len(u.Email), MaxLength: 255, }, }) } // Custom validator (x-ogen-validate) if err := validate.Ogen("email", u.Email, nil); err != nil { errs = append(errs, validate.FieldError{ Name: "email", Error: err, }) } if len(errs) > 0 { return &validate.Error{Fields: errs} } return nil } ``` -------------------------------- ### Generated Client with Server Selection Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/11-advanced-features.md Shows the generated Go client code that supports selecting different server configurations based on predefined choices and parameters. ```go type ServerChoice int const ( ServerDefault ServerChoice = iota ServerPrefix ) func (c *Client) SetServer(choice ServerChoice, region string) error { ... } func (c *Client) SetServerRegion(region string) error { ... } ``` -------------------------------- ### Run wrk Load Test with 1000 Connections Source: https://github.com/ogen-go/ogen/blob/main/internal/integration/cmd/README.md Performs a 10-second load test against the JSON endpoint with 6 threads and 1000 connections. ```console $ wrk -d 10s -t 6 -c 1000 http://localhost:8080/json Running 10s test @ http://localhost:8080/json 6 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.03ms 1.31ms 45.87ms 91.33% Req/Sec 132.58k 8.35k 164.28k 75.83% 7915077 requests in 10.05s, 0.99GB read Requests/sec: 787235.61 Transfer/sec: 100.60MB ``` ```console Running 10s test @ http://localhost:8080/json 6 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.37ms 1.21ms 42.10ms 87.44% Req/Sec 122.63k 7.32k 159.16k 71.33% 7319976 requests in 10.05s, 0.91GB read Requests/sec: 728012.89 Transfer/sec: 93.03MB ``` ```console $ wrk -d 10s -t 6 -c 1000 http://localhost:8080/json Running 10s test @ http://localhost:8080/json 6 threads and 1000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 2.40ms 1.24ms 37.46ms 82.28% Req/Sec 70.37k 4.26k 78.03k 75.50% 4199832 requests in 10.05s, 536.71MB read Requests/sec: 417884.38 Transfer/sec: 53.40MB ``` -------------------------------- ### OpenAPI oneOf with Field Type Discrimination Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/11-advanced-features.md Example OpenAPI schema using `oneOf` where variants have the same field name (`id`) but different types (string vs. integer). ```yaml oneOf: - type: object properties: id: type: string - type: object properties: id: type: integer ``` -------------------------------- ### OpenAPI oneOf with Field Name Discrimination Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/11-advanced-features.md Example OpenAPI schema using `oneOf` where variants are distinguished by different required field names (`userId` vs. `orderId`). ```yaml oneOf: - type: object required: [userId] properties: userId: type: string - type: object required: [orderId] properties: orderId: type: string ``` -------------------------------- ### Run Techempower Benchmark with 12 GOMAXPROCS Source: https://github.com/ogen-go/ogen/blob/main/internal/integration/cmd/README.md Executes the techempower benchmark with GOMAXPROCS set to 12. ```console GOMAXPROCS=12 techempower ``` -------------------------------- ### Run wrk Load Test with 50 Connections Source: https://github.com/ogen-go/ogen/blob/main/internal/integration/cmd/README.md Performs a 10-second load test against the JSON endpoint with 6 threads and 50 connections. ```console $ wrk -d 10s -t 6 -c 50 http://localhost:8080/json Running 10s test @ http://localhost:8080/json 6 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 116.32us 141.81us 1.55ms 86.31% Req/Sec 92.37k 5.54k 115.54k 71.29% 5569038 requests in 10.10s, 711.68MB read Requests/sec: 551415.23 Transfer/sec: 70.47MB ``` ```console $ wrk -d 10s -t 6 -c 50 http://localhost:8080/json Running 10s test @ http://localhost:8080/json 6 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 129.13us 113.42us 1.62ms 87.01% Req/Sec 70.09k 2.84k 77.37k 71.78% 4226043 requests in 10.10s, 540.06MB read Requests/sec: 418441.89 Transfer/sec: 53.47MB ``` -------------------------------- ### Run Techempower Benchmark with 6 GOMAXPROCS Source: https://github.com/ogen-go/ogen/blob/main/internal/integration/cmd/README.md Executes the techempower benchmark with GOMAXPROCS set to 6. ```console GOMAXPROCS=6 techempower ``` -------------------------------- ### Ogen CLI Performance Tip: Enable Operation Groups Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/12-cli-reference.md Use the '--features operation-groups' flag to split large specifications, improving performance. ```bash --features operation-groups ``` -------------------------------- ### OpenAPI oneOf with Explicit Discriminator Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/11-advanced-features.md Example OpenAPI schema using `oneOf` with an explicit `discriminator` object. This specifies the `propertyName` to use for discrimination and provides a `mapping` from discriminator values to schema references. ```yaml oneOf: - $ref: '#/components/schemas/Cat' - $ref: '#/components/schemas/Dog' discriminator: propertyName: type mapping: cat: '#/components/schemas/Cat' dog: '#/components/schemas/Dog' ``` -------------------------------- ### Ogen CLI Performance Tip: Disable Unnecessary Features Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/12-cli-reference.md Use the '--features' flag to enable only required features, optimizing generation time. ```bash # Only enable what you need --features router ``` -------------------------------- ### Generated Pet Structure Source: https://github.com/ogen-go/ogen/blob/main/README.md Example of a Go struct generated by Ogen from an OpenAPI schema. It includes various data types, optional and nullable fields, and custom types like UUID and IP addresses. ```go // Pet describes #/components/schemas/Pet. type Pet struct { Birthday time.Time `json:"birthday"` Friends []Pet `json:"friends"` ID int64 `json:"id"` IP net.IP `json:"ip"` IPV4 net.IP `json:"ip_v4"` IPV6 net.IP `json:"ip_v6"` Kind PetKind `json:"kind"` Name string `json:"name"` Next OptData `json:"next"` Nickname NilString `json:"nickname"` NullStr OptNilString `json:"nullStr"` Rate time.Duration `json:"rate"` Tag OptUUID `json:"tag"` TestArray1 [][]string `json:"testArray1"` TestDate OptTime `json:"testDate"` TestDateTime OptTime `json:"testDateTime"` TestDuration OptDuration `json:"testDuration"` TestFloat1 OptFloat64 `json:"testFloat1"` TestInteger1 OptInt `json:"testInteger1"` TestTime OptTime `json:"testTime"` Type OptPetType `json:"type"` URI url.URL `json:"uri"` UniqueID uuid.UUID `json:"unique_id"` } ``` -------------------------------- ### Define Generation Options Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/1-core-api.md The `Options` struct holds configuration for both parsing and generation. It includes fields for parser settings, generator settings, an expand spec string, and a logger. ```go type Options struct { Parser ParseOptions Generator GenerateOptions ExpandSpec string Logger *zap.Logger } ``` -------------------------------- ### OpenAPI oneOf with Type Discrimination Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/11-advanced-features.md Example OpenAPI schema using `oneOf` where variants have different JSON types (string vs. integer). The decoder determines the variant at runtime by checking the JSON type. ```yaml oneOf: - type: string - type: integer ``` -------------------------------- ### Generate Code with Multiple Features and Custom Client Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/12-cli-reference.md Generates Go code with multiple features enabled, a custom client name, and specified output directory and package. ```bash ogen --target ./api --package myapi \ --features router,tests,operation-groups \ --client-name APIClient \ openapi.yaml ``` -------------------------------- ### Generated Client Methods for Server Selection Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/14-configuration-reference.md These Go methods are generated based on the `x-ogen-server-name` extensions, allowing programmatic control over which server the client uses. ```go func (c *Client) SetServer(choice ServerChoice, vars ...string) error func (c *Client) SetServerRegional(region string) error func (c *Client) SetServerDefault() error ``` -------------------------------- ### Validation Error Structure Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/7-error-handling.md Aggregates multiple field validation failures into a single error. Example output: 'invalid: name (len 0 less than minimum 1), age (0 less than minimum 0)'. ```go type Error struct { Fields []FieldError } func (e *Error) Error() string { ... } ``` -------------------------------- ### SSE Data-Only Schema Example Source: https://github.com/ogen-go/ogen/blob/main/README.md This YAML snippet illustrates the default 'data-only' SSE event shape in OpenAPI. It defines the structure for the 'data' field of an SSE event, assuming standard SSE fields are handled separately. ```yaml text/event-stream: schema: type: object properties: message: type: string createdAt: type: string format: date-time ``` -------------------------------- ### Multipart Form File Upload in Go Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/13-patterns-and-examples.md Illustrates how to prepare and upload a file using multipart form data with the Ogen client. This is suitable for APIs that accept file uploads. ```go import ( "io" "github.com/myapp/api" "github.com/ogen-go/ogen/http" ) func uploadFile(client *api.Client, ctx context.Context, filePath string) error { file, err := os.Open(filePath) if err != nil { return err } defer file.Close() stat, _ := file.Stat() mpFile := http.MultipartFile{ Name: stat.Name(), File: file, Size: stat.Size(), } return client.UploadFile(ctx, &api.UploadFileRequest{ File: mpFile, }) } ``` -------------------------------- ### Build-Time Customization with Go Flags Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/14-configuration-reference.md Customize generator options like output path and package name at build time using Go's linker flags (`-ldflags`). ```go var ( apiVersion = "1.0.0" apiPackage = "api" apiOut = "./api" ) func init() { // Override from build flags: -ldflags "-X main.apiOut=/custom/path" } func main() { opts := gen.Options{} opts.Generator.Package = apiPackage opts.Generator.Out = apiOut // Generate... } ``` -------------------------------- ### Test Generated Go API Client Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/13-patterns-and-examples.md Test the generated API client by setting up an `httptest` server with your handler and then creating a client that connects to this test server. This verifies client-server communication. ```go import ( "context" "testing" "github.com/myapp/api" "github.com/stretchr/testify/assert" ) func TestClient(t *testing.T) { // Use httptest server with generated server handler := &Handler{} server := api.NewServer(handler) ts := httptest.NewServer(server) defer ts.Close() client, _ := api.NewClient(ts.URL) user, err := client.GetUser(context.Background(), api.GetUserParams{ UserID: "123", }) assert.NoError(t, err) assert.NotNil(t, user) } ``` -------------------------------- ### SSE Full Event Shape Schema Example Source: https://github.com/ogen-go/ogen/blob/main/README.md This YAML configuration demonstrates the 'full' SSE event shape in OpenAPI. It uses 'oneOf' and 'discriminator' to define multiple possible event structures, mapping 'event' field values to specific schemas. ```yaml text/event-stream: x-ogen-sse-event-shape: full schema: oneOf: - $ref: "#/components/schemas/EventA" - $ref: "#/components/schemas/EventB" discriminator: propertyName: event mapping: event_a: "#/components/schemas/EventA" event_b: "#/components/schemas/EventB" # ... EventA: type: object required: [ event, data ] properties: event: type: string enum: [ event_a ] data: $ref: "#/components/schemas/EventAData" EventB: type: object required: [ event, data ] properties: event: type: string enum: [ event_b ] data: $ref: "#/components/schemas/EventBData" ``` -------------------------------- ### Options Structure for Code Generation Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/10-code-generation.md The `Options` struct holds all configuration for the code generator, including parser settings, generation settings, and output paths. ```go type Options struct { // Parser configuration Parser ParseOptions // Generation configuration Generator GenerateOptions // Path to write expanded spec ExpandSpec string // Logger instance Logger *zap.Logger } ``` -------------------------------- ### Handle Optional and Nullable Fields in Go Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/13-patterns-and-examples.md Demonstrates how to safely access optional and nullable fields from API types. Use `.Get()` for optional fields and `.IsNil()`/`.IsSet()` for nullable fields. Note that optional fields can also be nil. ```go import "github.com/myapp/api" func example(user *api.User) { // Optional field if email, ok := user.Email.Get(); ok { println("Email:", email) } // Nullable field if !user.Nickname.IsNil() { nickname, _ := user.Nickname.Get() println("Nickname:", nickname) } // Optional nullable if user.Bio.IsSet() { if user.Bio.IsNil() { println("Bio is null") } else { bio, _ := user.Bio.Get() println("Bio:", bio) } } } // Creating values userUpdate := &api.UserUpdate{ Name: "Alice", Email: api.NewOptString("alice@example.com"), Bio: api.NewOptNilString("Developer"), } ``` -------------------------------- ### Consume SSE Events with Next Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/6-sse-api.md Use the `Next` method in a loop to consume Server-Sent Events one by one. Handle errors and break the loop on stream termination. ```go package main import ( "context" "log" "time" "github.com/ogen-go/ogen/sse" ) // Generated by ogen type StreamEvent struct { ID string Data string // ... other fields } type SSEClient interface { sse.Client[StreamEvent] } func main() { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() // Assume client is initialized (generated code) var client SSEClient // Consume events using Next for { event, err := client.Next(ctx) if err != nil { log.Printf("Stream error: %v", err) break } log.Printf("Received event %s: %s", event.ID, event.Data) } _ = client.Close() } ``` -------------------------------- ### Work with Sum Types in Go Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/13-patterns-and-examples.md Illustrates how to handle sum types (also known as discriminated unions or tagged unions) by switching on the type field. Use `NewStringID` or `NewIntID` to create instances. ```go import "github.com/myapp/api" func handleID(id api.ID) { switch id.Type { case api.IDTypeString: println("String ID:", id.String) case api.IDTypeInt: println("Int ID:", id.Int) } } // Creating sum type values userID := api.NewStringID("user-123") productID := api.NewIntID(456) ``` -------------------------------- ### Error Handling in Go Handlers Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/13-patterns-and-examples.md Demonstrates how to handle specific errors like 'not found' and general internal server errors using Ogen's error types. Import necessary error packages. ```go import ( "context" "github.com/go-faster/errors" "github.com/myapp/api" "github.com/ogen-go/ogen/ogenerrors" ) func (h *Handler) GetUser(ctx context.Context, params api.GetUserParams) (*api.User, error) { user, err := h.db.GetUser(params.UserID) if err != nil { if errors.Is(err, sql.ErrNoRows) { // Return not found return nil, ogenerrors.ErrNotFound } // Return internal error return nil, ogenerrors.ErrInternalServerError } return user, nil } ``` -------------------------------- ### Generated Client Method Pattern Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/4-http-api.md Illustrates how a generated client method uses Ogen's HTTP utilities to construct and send a POST request with a JSON body. ```go func (c *Client) CreateUser(ctx context.Context, req *CreateUserRequest) (*User, error) { body := bytes.NewBuffer(nil) enc := jx.NewEncoder(body) req.Encode(enc) httpReq, _ := http.NewRequest(ctx, "POST", c.URL) http.SetBody(httpReq, body, "application/json") resp, _ := c.client.Do(httpReq) // ... handle response } ``` -------------------------------- ### Define Generate Options Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/1-core-api.md The `GenerateOptions` struct specifies details for code generation, such as the target package, output directory, and names for generated client and server components. It also includes feature set configuration. ```go type GenerateOptions struct { Package string Out string Clean bool RootPackageName string ClientName string ServerName string Features FeatureSet // ... additional options } ``` -------------------------------- ### WriteSource Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/10-code-generation.md Generates Go source code based on the OpenAPI specification and writes it to the specified filesystem. ```APIDOC ## WriteSource ### Description Generates Go source code and writes it to the provided filesystem using the given package name. ### Signature ```go func (g *Generator) WriteSource(fs FileSystem, packageName string) error ``` ### Parameters - `fs` (FileSystem): An implementation of the FileSystem interface for writing files. - `packageName` (string): The Go package name for the generated code. ### Generated Files - `openapi_types_gen.go`: Contains schema types. - `openapi_client_gen.go`: Contains the client implementation. - `openapi_server_gen.go`: Contains the server interface. - `openapi_routers_gen.go`: Contains the HTTP router (if enabled). - `openapi_validators_gen.go`: Contains validation code. - `openapi_test_gen.go`: Contains unit tests (if enabled). ``` -------------------------------- ### Register Custom Validators in Go Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/8-validation-api.md Register custom validators for formats like 'email' and 'url' at application startup using `validate.RegisterValidator`. Ensure necessary imports like `net/mail` and `net/url` are included. ```go package main import ( "fmt" "github.com/ogen-go/ogen/validate" "net/mail" "net/url" ) func init() { // Register email validator validate.RegisterValidator("email", func(value any, params any) error { s, ok := value.(string) if !ok { return fmt.Errorf("expected string") } _, err := mail.ParseAddress(s) return err }) // Register URL validator validate.RegisterValidator("url", func(value any, params any) error { s, ok := value.(string) if !ok { return fmt.Errorf("expected string") } if _, err := url.Parse(s); err != nil { return fmt.Errorf("invalid URL: %w", err) } // Ensure it has a scheme u, _ := url.Parse(s) if u.Scheme == "" { return fmt.Errorf("URL must have a scheme") } return nil }) } func main() { // Now custom validators are available in generated code // server := api.NewServer(handler) // _ = server } ``` -------------------------------- ### Ogen CLI Performance Tip: Limit Schema Depth Source: https://github.com/ogen-go/ogen/blob/main/_autodocs/12-cli-reference.md Use the '--depth-limit' flag to control schema depth, which can be useful for large specifications. ```bash --depth-limit 500 ```