`HttpApiSchema` streams: declare every media type a stream can be sent as

Cerrado
#9,909 0 comentarios 0 reacciones 1 asignado Ver en GitHub

Los mantenedores suelen responder en 1 día

@effect-bot ya está trabajando en esto.

Desde el 25/10/2026.

  • #9941 de @effect-bot — fusionado

Evaluación

Este issue todavía no se ha evaluado.

Descripción

docker-made-me-do-it enhancement

Problem

Some APIs send one stream under one of several media types, depending on the resource or the API version:

  • Docker's container logs answer 200 with application/vnd.docker.raw-stream when the container has a TTY, and with application/vnd.docker.multiplexed-stream otherwise.
  • Docker's GET /events is NDJSON sent as application/json up to API 1.51, and as application/jsonl from API 1.52 (measured on Docker 29).

OpenAPI describes this directly: a response's content maps each media type to its schema, and Docker's own API document lists both stream types under the logs' 200. A stream schema has exactly one contentType, though. So the generated OpenAPI document lists one media type the API may not send. For logs, declared as StreamUint8Array, it lists application/octet-stream, which the API never sends:

HttpApiEndpoint.get("logs", "/containers/:id/logs", {
  params: { id: Schema.String },
  success: HttpApiSchema.WithHeaders(HttpApiSchema.StreamUint8Array(), {
    "content-type": Schema.Literals([
      "application/vnd.docker.raw-stream",
      "application/vnd.docker.multiplexed-stream"
    ])
  })
})
// OpenAPI: 200 → content: { "application/octet-stream": … }

Declaring two stream successes instead isn't allowed ("Multiple streaming success responses are not supported", HttpApiEndpoint.ts L1403), and would need a way for a handler to pick one.

Proposal

Let StreamUint8Array and StreamNdjson take a list of media types:

success: HttpApiSchema.WithHeaders(
  HttpApiSchema.StreamUint8Array({
    contentType: ["application/vnd.docker.raw-stream", "application/vnd.docker.multiplexed-stream"]
  }),
  {
    "content-type": Schema.Literals(["application/vnd.docker.raw-stream", "application/vnd.docker.multiplexed-stream"])
  }
)

HttpApiSchema.StreamNdjson({ schema: EventMessage, contentType: ["application/jsonl", "application/json"] })
  • OpenAPI: each media type is listed under the status, with the same stream schema.
  • Client: unchanged. A status with one stream alternative is decoded whatever its Content-Type today, so any of the listed types is read the same way.
  • Server: the first media type is the default. A handler that sets a content-type declared with WithHeaders sends that one. This already works today: a handler's header replaces the stream's default Content-Type (tested with NodeHttpServer).
  • Payloads: a streaming request payload with several media types accepts any of them.

It's still one stream per status, so there's no new handler API and no union of stream types.

Scope

In scope: StreamUint8Array and StreamNdjson, as successes and as payloads.

Out of scope: StreamSse (always text/event-stream), and several stream schemas for one status.

Open questions

  • Should the server check that a handler's content-type is one of the listed types, or leave that to the declared header's schema?
Lenguaje dominante
TypeScript
Estrellas
16.7k
Forks
808
Merge medio
10 h 21 min
PR fusionados (30 d)
834

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de Effect-TS/effect

Todos los issues de Effect-TS/effect

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.