ogen-go / ogen

OpenAPI v3 code generator for go
https://ogen.dev
Apache License 2.0
1.45k stars 86 forks source link

Servers: Variables do not support non-enums #1272

Closed atombender closed 4 months ago

atombender commented 4 months ago

Given a server list like this:

servers:
- url: https://{hostPort}/v{version}
  x-ogen-server-name: development
  variables:
    version:
      description: API version
      default: UNKNOWN  # Ogen requires a dummy default here
    hostPort:
      description: Host and port
      default: UNKNOWN  # Ogen requires a dummy default here

This will generate the following validation code:

func (s DevelopmentServer) Build() (string, error) {
    zeroOr := func(s string, def string) string {
        if s == "" {
            return def
        }
        return s
    }
    s.HostPort = zeroOr(s.HostPort, "UNKNOWN")
    // Validate "hostPort"
    switch s.HostPort {
    default:
        return "", errors.Errorf("param %q: unexpected value %q", "hostPort", s.HostPort)
    }
    ...

This means it's not possible to create structs with arbitrary data:

srv := DevelopmentServer{
    HostPort: "localhost:8080",
    Version: "2024-06-29",
}

as this will fail with:

param "hostPort": unexpected value "localhsot:8080":

This is in violation of the OpenAPI spec, which says the enum is optional (emphasis mine):

An enumeration of string values to be used if the substitution options are from a limited set

The validation template should just skip non-set values, e.g.:

    {{- if $p.Spec.Enum }}
    // Validate {{ quote $p.Spec.Name }}
    switch s.{{ $p.Name }} {
    {{- range $e := $p.Spec.Enum }}
    case {{ quote $e }}:
    {{- end }}
    default:
        return "", errors.Errorf("param %q: unexpected value %q", {{ quote $p.Spec.Name }}, s.{{ $p.Name }})
    }
    {{- end }}