diff --git a/api/docs/CHANGELOG.md b/api/docs/CHANGELOG.md index 162f7e2709..d293ba699f 100644 --- a/api/docs/CHANGELOG.md +++ b/api/docs/CHANGELOG.md @@ -17,6 +17,8 @@ keywords: "API, Docker, rcli, REST, documentation" * `GET /info` now includes an `NRI` field. If the Node Resource Interface (NRI) is enabled, this field contains information describing it. +* `GET /events` now also supports [`application/jsonl`](https://jsonlines.org/) + when negotiating content-type. * Deprecated: The `POST /grpc` and `POST /session` endpoints are deprecated and will be removed in a future version. diff --git a/api/swagger.yaml b/api/swagger.yaml index a1cd3eff60..610dc778d8 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -10463,6 +10463,7 @@ paths: operationId: "SystemEvents" produces: + - "application/jsonl" - "application/x-ndjson" - "application/json-seq" responses: diff --git a/api/types/types.go b/api/types/types.go index a89befdda4..bb5aa41a83 100644 --- a/api/types/types.go +++ b/api/types/types.go @@ -10,9 +10,12 @@ const ( // MediaTypeJSON is the MIME-Type for JSON objects. MediaTypeJSON = "application/json" - // MediaTypeNDJSON is the MIME-Type for Newline Delimited JSON objects streams. + // MediaTypeNDJSON is the MIME-Type for Newline Delimited JSON objects streams (https://github.com/ndjson/ndjson-spec). MediaTypeNDJSON = "application/x-ndjson" + // MediaTypeJSONLines is the MIME-Type for JSONLines objects streams (https://jsonlines.org/). + MediaTypeJSONLines = "application/jsonl" + // MediaTypeJSONSequence is the MIME-Type for JSON Text Sequences (RFC7464). MediaTypeJSONSequence = "application/json-seq" ) diff --git a/client/internal/json-stream.go b/client/internal/json-stream.go index 552978f9a1..07d07bd7e3 100644 --- a/client/internal/json-stream.go +++ b/client/internal/json-stream.go @@ -17,7 +17,7 @@ func NewJSONStreamDecoder(r io.Reader, contentType string) DecoderFn { switch contentType { case types.MediaTypeJSONSequence: return json.NewDecoder(NewRSFilterReader(r)).Decode - case types.MediaTypeJSON, types.MediaTypeNDJSON: + case types.MediaTypeJSON, types.MediaTypeNDJSON, types.MediaTypeJSONLines: fallthrough default: return json.NewDecoder(r).Decode diff --git a/client/system_events.go b/client/system_events.go index 748e012086..b33e02aa3d 100644 --- a/client/system_events.go +++ b/client/system_events.go @@ -46,6 +46,7 @@ func (cli *Client) Events(ctx context.Context, options EventsListOptions) Events headers := http.Header{} headers.Add("Accept", types.MediaTypeJSONSequence) + headers.Add("Accept", types.MediaTypeJSONLines) headers.Add("Accept", types.MediaTypeNDJSON) resp, err := cli.get(ctx, "/events", query, headers) if err != nil { diff --git a/daemon/server/httputils/json-seq.go b/daemon/server/httputils/json-seq.go index 624247b2d4..f5f33c77cf 100644 --- a/daemon/server/httputils/json-seq.go +++ b/daemon/server/httputils/json-seq.go @@ -21,7 +21,7 @@ func NewJSONStreamEncoder(w io.Writer, contentType string) EncoderFn { json: jsonEncoder, } return jseq.Encode - case types.MediaTypeNDJSON, types.MediaTypeJSON: + case types.MediaTypeNDJSON, types.MediaTypeJSON, types.MediaTypeJSONLines: fallthrough default: return jsonEncoder.Encode diff --git a/daemon/server/router/system/system_routes.go b/daemon/server/router/system/system_routes.go index 0d2d4f0ca6..9b8ccb4b90 100644 --- a/daemon/server/router/system/system_routes.go +++ b/daemon/server/router/system/system_routes.go @@ -311,6 +311,7 @@ func (s *systemRouter) getEvents(ctx context.Context, w http.ResponseWriter, r * } contentType := httputil.NegotiateContentType(r, []string{ + types.MediaTypeJSONLines, types.MediaTypeNDJSON, types.MediaTypeJSONSequence, }, types.MediaTypeJSON) // output isn't actually JSON but API used to this content-type diff --git a/vendor/github.com/moby/moby/api/types/types.go b/vendor/github.com/moby/moby/api/types/types.go index a89befdda4..bb5aa41a83 100644 --- a/vendor/github.com/moby/moby/api/types/types.go +++ b/vendor/github.com/moby/moby/api/types/types.go @@ -10,9 +10,12 @@ const ( // MediaTypeJSON is the MIME-Type for JSON objects. MediaTypeJSON = "application/json" - // MediaTypeNDJSON is the MIME-Type for Newline Delimited JSON objects streams. + // MediaTypeNDJSON is the MIME-Type for Newline Delimited JSON objects streams (https://github.com/ndjson/ndjson-spec). MediaTypeNDJSON = "application/x-ndjson" + // MediaTypeJSONLines is the MIME-Type for JSONLines objects streams (https://jsonlines.org/). + MediaTypeJSONLines = "application/jsonl" + // MediaTypeJSONSequence is the MIME-Type for JSON Text Sequences (RFC7464). MediaTypeJSONSequence = "application/json-seq" ) diff --git a/vendor/github.com/moby/moby/client/internal/json-stream.go b/vendor/github.com/moby/moby/client/internal/json-stream.go index 552978f9a1..07d07bd7e3 100644 --- a/vendor/github.com/moby/moby/client/internal/json-stream.go +++ b/vendor/github.com/moby/moby/client/internal/json-stream.go @@ -17,7 +17,7 @@ func NewJSONStreamDecoder(r io.Reader, contentType string) DecoderFn { switch contentType { case types.MediaTypeJSONSequence: return json.NewDecoder(NewRSFilterReader(r)).Decode - case types.MediaTypeJSON, types.MediaTypeNDJSON: + case types.MediaTypeJSON, types.MediaTypeNDJSON, types.MediaTypeJSONLines: fallthrough default: return json.NewDecoder(r).Decode diff --git a/vendor/github.com/moby/moby/client/system_events.go b/vendor/github.com/moby/moby/client/system_events.go index 748e012086..b33e02aa3d 100644 --- a/vendor/github.com/moby/moby/client/system_events.go +++ b/vendor/github.com/moby/moby/client/system_events.go @@ -46,6 +46,7 @@ func (cli *Client) Events(ctx context.Context, options EventsListOptions) Events headers := http.Header{} headers.Add("Accept", types.MediaTypeJSONSequence) + headers.Add("Accept", types.MediaTypeJSONLines) headers.Add("Accept", types.MediaTypeNDJSON) resp, err := cli.get(ctx, "/events", query, headers) if err != nil {