Skip to content

openapi: SSE and NDJSON streaming is invisible below OpenAPI 3.2 #250

Description

@OmarAlJarrah

Problem

Operation.ResponseStream / RequestStream are only ever set from the OpenAPI 3.2 sequential-media
keywords (operation/content.go:fillSequential, reading itemSchema/itemEncoding). Every SSE and
NDJSON API written against 3.0 or 3.1 declares streaming solely by media type, so the IR carries no
streaming signal at all for what is, today, almost all of them.

Reproduction

openapi: 3.1.0
info: {title: Probe, version: "1"}
paths:
  /events:
    get:
      responses:
        '200':
          description: stream
          content:
            text/event-stream:
              schema: {type: object, properties: {msg: {type: string}}}
$ morphic compile probe.yaml
OP get_events | responseStream = null

No diagnostic. The media type itself survives on Content.MediaType, so nothing is lost — but
nothing is modelled either, and a downstream plan.StreamPlan has nothing to read, so
emitter-design.md's LowerStreaming step can never fire for a 3.0/3.1 spec.

The corpus does not catch this because testdata/conformance/openapi/sequential-media.yaml is
openapi: 3.2.0 and exercises only the itemSchema form.

Proposed direction

Media-type-implies-streaming is an inference, not a declaration, so it belongs in injectable
per-compiler policy per invariant 6: a default-on, disable-able list of media-type patterns that sets
ResponseStream/RequestStream with Provenance.Inferred naming the heuristic. oapi-codegen's
default list is the obvious starting set — text/event-stream, application/jsonl,
application/x-ndjson — with users able to extend it (pkg/codegen/configuration.go,
defaultStreamingContentTypes).

Two details worth settling in the same change:

  • A 3.2 itemSchema declaration must win over the inference, and the two must not both fire.
  • StreamDetail needs a documented answer for what the event type is when it is inferred rather
    than declared — for text/event-stream the schema under the media type is the event, not the
    whole body, which is the opposite of how a non-streaming content is read.

Acceptance

  • A 3.0 and a 3.1 conformance case, each declaring text/event-stream, produce a populated
    ResponseStream marked Inferred.
  • The inference is off when disabled, and the case then produces the current output.
  • An itemSchema declaration alongside a matching media type does not double-apply.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions