Building a YAML Schema to Go Model Generator for OpenAI’s API

When working with OpenAI’s API, I needed to generate Go models from their YAML schema specification. Instead of manually creating these models, I built a generator using Go’s text/template package. Here’s how I did it and what I learned along the way.


This content originally appeared on DEV Community and was authored by Jakob Khalil

When working with OpenAI's API, I needed to generate Go models from their YAML schema specification. Instead of manually creating these models, I built a generator using Go's text/template package. Here's how I did it and what I learned along the way.

The Problem

OpenAI provides their API specification in YAML format, but I needed strongly-typed Go models for my application. Manual conversion would be time-consuming and error-prone, especially when the API specs change.

The Solution

I created a generator that:

  1. Parses OpenAI's YAML schema
  2. Generates Go structs with proper types and JSON tags
  3. Handles complex types like oneOf/anyOf
  4. Generates proper marshaling/unmarshaling methods

Let's look at an example of what the generator produces:

// 10:16:output/ChatCompletionRequestUserMessage.go
// Messages sent by an end user, containing prompts or additional context
// information.
type ChatCompletionRequestUserMessage struct {
    Content UserMessageContent `json:"content"`
    Name *string `json:"name,omitempty"`
    Role Role `json:"role"`
}

This was generated from a YAML schema like this:

components:
  schemas:
    ChatCompletionRequestUserMessage:
      description: Messages sent by an end user, containing prompts or additional context information.
      type: object
      required:
        - content
        - role
      properties:
        content:
          $ref: '#/components/schemas/UserMessageContent'
        name:
          type: string
        role:
          $ref: '#/components/schemas/Role'

Key Features

1. OneOf/AnyOf Handling

One of the trickier parts was handling OpenAI's oneOf/anyOf patterns. For example, the UserMessageContent can be either a string or an array:

// 19:22:output/ChatCompletionRequestUserMessage.go
type UserMessageContent struct {
    UserMessageContentString *string
    UserMessageContentArray *[]ChatCompletionRequestUserMessageContentPart
}

The generator creates a struct with both possibilities and implements custom marshaling:

// 37:54:output/ChatCompletionRequestUserMessage.go
func (x UserMessageContent) MarshalJSON() ([]byte, error) {
    rawResult, err := x.Match(
        func(y string) (any, error) {
            return json.Marshal(y)
        },
        func(y []ChatCompletionRequestUserMessageContentPart) (any, error) {
            return json.Marshal(y)
        },
    )
    if err != nil {
        return nil, err
    }
    result, ok := rawResult.([]byte)
    if !ok {
        return nil, fmt.Errorf("expected match to return type '[]byte'")
    }
    return result, nil
}

2. Enum Support

The generator also handles enums elegantly. For example, the ReasoningEffort enum:

// 269:275:output/ChatCompletionRequest.go
type ReasoningEffortEnum string

const (
    ReasoningEffortEnumHigh ReasoningEffortEnum = "high"
    ReasoningEffortEnumLow ReasoningEffortEnum = "low"
    ReasoningEffortEnumMedium ReasoningEffortEnum = "medium"
)

3. Documentation Preservation

Notice how the generator preserves documentation from the YAML schema:

// 10:13:output/ChatCompletionRequestDeveloperMessage.go
// Developer-provided instructions that the model should follow, regardless of
// messages sent by the user. With o1 models and newer, `developer` messages
// replace the previous `system` messages.
type ChatCompletionRequestDeveloperMessage struct {

The Generator Template

Here's a simplified version of the main template I used:

const modelTemplate = `
// THIS IS GENERATED CODE. DO NOT EDIT  
package {{.PackageName}}

import (
    "encoding/json"
    "fmt"
)

{{if .Description}}// {{.Description}}{{end}}
type {{.Name}} struct {
    {{range .Properties}}
    {{.Name}} {{.Type}} ` + "`json:\"{{.JsonTag}},omitempty\"`" + `
    {{end}}
}

{{if .HasOneOf}}
func (x *{{.Name}}) Match(
    {{range .OneOfTypes}}
    fn{{.Name}} func(y {{.Type}}) (any, error),
    {{end}}
) (any, error) {
    {{range .OneOfTypes}}
    if x.{{.Name}} != nil {
        return fn{{.Name}}(*x.{{.Name}})
    }
    {{end}}
    return nil, fmt.Errorf("invalid content: all variants are nil")
}
{{end}}
`

Usage

Using the generator is straightforward:

func main() {
    schema, err := LoadYAMLSchema("openai-schema.yaml")
    if err != nil {
        log.Fatal(err)
    }

    generator := NewGenerator(schema)
    if err := generator.Generate("output/"); err != nil {
        log.Fatal(err)
    }
}

Benefits

  1. Type Safety: Generated models provide compile-time type checking
  2. Maintainability: Easy to regenerate when the API spec changes
  3. Consistency: Ensures all models follow the same patterns
  4. Documentation: Preserves API documentation in Go comments

Conclusion

Building this generator has significantly improved our OpenAI API integration workflow. The generated code is consistent, well-documented, and type-safe. When OpenAI updates their API, we can simply regenerate our models.


This content originally appeared on DEV Community and was authored by Jakob Khalil


Print Share Comment Cite Upload Translate Updates
APA

Jakob Khalil | Sciencx (2025-02-11T23:47:01+00:00) Building a YAML Schema to Go Model Generator for OpenAI’s API. Retrieved from https://www.scien.cx/2025/02/11/building-a-yaml-schema-to-go-model-generator-for-openais-api/

MLA
" » Building a YAML Schema to Go Model Generator for OpenAI’s API." Jakob Khalil | Sciencx - Tuesday February 11, 2025, https://www.scien.cx/2025/02/11/building-a-yaml-schema-to-go-model-generator-for-openais-api/
HARVARD
Jakob Khalil | Sciencx Tuesday February 11, 2025 » Building a YAML Schema to Go Model Generator for OpenAI’s API., viewed ,<https://www.scien.cx/2025/02/11/building-a-yaml-schema-to-go-model-generator-for-openais-api/>
VANCOUVER
Jakob Khalil | Sciencx - » Building a YAML Schema to Go Model Generator for OpenAI’s API. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/02/11/building-a-yaml-schema-to-go-model-generator-for-openais-api/
CHICAGO
" » Building a YAML Schema to Go Model Generator for OpenAI’s API." Jakob Khalil | Sciencx - Accessed . https://www.scien.cx/2025/02/11/building-a-yaml-schema-to-go-model-generator-for-openais-api/
IEEE
" » Building a YAML Schema to Go Model Generator for OpenAI’s API." Jakob Khalil | Sciencx [Online]. Available: https://www.scien.cx/2025/02/11/building-a-yaml-schema-to-go-model-generator-for-openais-api/. [Accessed: ]
rf:citation
» Building a YAML Schema to Go Model Generator for OpenAI’s API | Jakob Khalil | Sciencx | https://www.scien.cx/2025/02/11/building-a-yaml-schema-to-go-model-generator-for-openais-api/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.