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.
Problem
Operation.ResponseStream/RequestStreamare only ever set from the OpenAPI 3.2 sequential-mediakeywords (
operation/content.go:fillSequential, readingitemSchema/itemEncoding). Every SSE andNDJSON 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
No diagnostic. The media type itself survives on
Content.MediaType, so nothing is lost — butnothing is modelled either, and a downstream
plan.StreamPlanhas nothing to read, soemitter-design.md'sLowerStreamingstep can never fire for a 3.0/3.1 spec.The corpus does not catch this because
testdata/conformance/openapi/sequential-media.yamlisopenapi: 3.2.0and exercises only theitemSchemaform.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/RequestStreamwithProvenance.Inferrednaming the heuristic. oapi-codegen'sdefault 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:
itemSchemadeclaration must win over the inference, and the two must not both fire.StreamDetailneeds a documented answer for what the event type is when it is inferred ratherthan declared — for
text/event-streamthe schema under the media type is the event, not thewhole body, which is the opposite of how a non-streaming content is read.
Acceptance
text/event-stream, produce a populatedResponseStreammarkedInferred.itemSchemadeclaration alongside a matching media type does not double-apply.