Content types
Consumer and Producer (interfaces page) are the seam
through which every wire format plugs in.
The runtime ships a handful of built-in factories for the formats most OpenAPI specs use; anything else is a function call away.
Built-in factories
All factories return ready-to-use Consumer / Producer values. They are
side-effect free — call them as many times as you like.
| Format | Consumer factory | Producer factory | Common MIME |
|---|---|---|---|
| JSON | runtime.JSONConsumer() | runtime.JSONProducer() | application/json |
| XML | runtime.XMLConsumer() | runtime.XMLProducer() | application/xml, text/xml |
| Plain text | runtime.TextConsumer() | runtime.TextProducer() | text/plain |
| CSV | runtime.CSVConsumer(opts…) | runtime.CSVProducer(opts…) | text/csv |
| Byte stream | runtime.ByteStreamConsumer(opts…) | runtime.ByteStreamProducer(opts…) | application/octet-stream, any unparsed binary type |
| YAML | yamlpc.YAMLConsumer() | yamlpc.YAMLProducer() | application/yaml, application/x-yaml |
YAML lives in a sub-package
(github.com/go-openapi/runtime/yamlpc)
to keep the YAML dependency optional.
The CSV and bytestream factories accept option functions (e.g.
runtime.ClosesStream to make a stream consumer close the underlying
reader). See the godoc
for the full option list.
Registering codecs on a server
The server side keeps two map[mediaType]Consumer / …Producer lookups,
populated at API construction time. For an untyped API:
api := untyped.NewAPI(spec)
api.RegisterConsumer(runtime.JSONMime, runtime.JSONConsumer())
api.RegisterProducer(runtime.JSONMime, runtime.JSONProducer())
api.RegisterConsumer("application/vnd.acme.v1+json", runtime.JSONConsumer())
api.RegisterProducer("application/vnd.acme.v1+json", runtime.JSONProducer())Full source: docs/examples/core/contenttypes/main.go
Code generated by go-swagger calls these for you, one entry per consumes
and produces value declared in the spec.
Registering codecs on a client
client.Runtime exposes per-content-type maps via Consumers and
Producers on the runtime value. Generated clients populate them; for
direct use:
rt := client.New("api.example.com", "/v1", []string{"https"})
rt.Consumers[runtime.JSONMime] = runtime.JSONConsumer()
rt.Producers[runtime.JSONMime] = runtime.JSONProducer()Full source: docs/examples/core/contenttypes/main.go
Writing a custom Consumer / Producer
A consumer is a function. The runtime never inspects its concrete type —
implementing Consumer (or supplying a ConsumerFunc) is enough.
| |
Full source: docs/examples/customcodec/uint32.go
Register the resulting Consumer under whatever MIME types should dispatch to it.
Selection rules
How the runtime chooses which consumer / producer to use for a given request — including wildcards, MIME parameters, and the asymmetric matching rule — is documented in tutorials / media-type selection and surfaced site-side under standalone / content negotiation.
Client-side override: ContentTyper
A request body value can declare its own Content-Type by implementing
runtime.ContentTyper:
When a body payload set via SetBodyParam is a stream and ContentType()
returns a non-empty value, that value wins over the operation’s consumes
default. Same goes for individual file values inside a multipart upload.
The full algorithm is in
tutorials / media-type selection.