Skip to content

Strict-server templates: fiber and iris variants have drifted from stdhttp #2331

@mromaszewicz

Description

@mromaszewicz

Summary

The three strict-server interface templates —
pkg/codegen/templates/strict/strict-interface.tmpl (stdhttp/chi/gorilla),
pkg/codegen/templates/strict/strict-fiber-interface.tmpl, and
pkg/codegen/templates/strict/strict-iris-interface.tmpl — share the same
overall structure (range over operations → render RequestObject /
ResponseObject interface / per-content-type Visit*Response method), but
several features present in strict-interface.tmpl are missing from one or
both of the others. This reports the divergences; no fix strategy is
implied.

Some differences are unavoidable framework-API differences (receiver types,
header setter API, status-code API, JSON helpers) and are not listed below.
The items below appear to be drift — places where a fix or feature landed
in one template and wasn't mirrored into the others.

Divergences

1. Nullable / optional response-header serialization

strict-interface.tmpl renders each response header through a three-way
switch over .IsNullable / .IsOptional / default so that unspecified
nullable values and nil optional pointers are skipped:

{{if .IsNullable -}}
    if response.Headers.{{.GoName}}.IsSpecified() {
        w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}}.MustGet()))
    }
{{else if .IsOptional -}}
    if response.Headers.{{.GoName}} != nil {
        w.Header().Set("{{.Name}}", fmt.Sprint(*response.Headers.{{.GoName}}))
    }
{{else -}}
    w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}}))
{{end -}}

strict-fiber-interface.tmpl and strict-iris-interface.tmpl render every
response header unconditionally, with no nullable/optional handling:

ctx.Response().Header.Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}}))

(Same pattern in both the typed-body Visit*Response bodies and the
no-content Visit*Response bodies.) A nil optional header pointer will
stringify to <nil>; an unspecified nullable header will be set with an
empty/zero value.

Likely introduced with #2301 ("support optional/nullable response
headers"), which did not update fiber/iris.

2. Response-header struct field types

In the generated {{$opid}}{{$statusCode}}ResponseHeaders struct,
strict-interface.tmpl uses {{.GoTypeDef}} (pointer/nullable-aware),
while strict-fiber-interface.tmpl and strict-iris-interface.tmpl use
{{.Schema.TypeDecl}} (raw type, no pointer/nullable awareness). This is
the same drift as item 1, on the type side.

3. $ref Text responses

strict-interface.tmpl treats $ref Text responses the same as $ref
Multipart responses in its fixed-status-code + ref-type branch:

{{ if and (not $hasHeaders) ($fixedStatusCode) (.IsSupported) (or (eq .NameTag "Multipart") (eq .NameTag "Text")) -}}
    type {{$receiverTypeName}} {{$ref}}{{.NameTagOrContentType}}Response

strict-fiber-interface.tmpl only checks Multipart there, so $ref Text
responses fall through to a different code path.

strict-iris-interface.tmpl has an earlier short-circuit at the top of
its Contents range:

{{if eq .NameTag "Text" -}}
    type {{$receiverTypeName}} string
{{else if and $fixedStatusCode $isRef -}}
    ...

which unconditionally emits type X string for any Text response —
ignoring $ref, $fixedStatusCode, and $hasHeaders. Neither
fiber's nor iris's shape matches the stdhttp branch.

Related prior change: #2225 ("generate correct type for $ref text
responses").

4. $ref name qualification

  • strict-interface.tmpl: {{$ref := .Ref | ucFirstWithPkgName -}}
  • strict-iris-interface.tmpl: {{$ref := .Ref | ucFirstWithPkgName -}}
  • strict-fiber-interface.tmpl: {{$ref := .Ref | ucFirst -}}

Fiber alone lacks the package-name-aware helper, so external-ref
response types rendered in this template will not carry the package
qualifier.

Scope

These are observations from a side-by-side read of the three files. I'm
not proposing a fix direction in this issue — just surfacing where the
templates have drifted so someone picking this up has the anchors.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions