Content Negotiation
Last updated
Was this helpful?
Last updated
Was this helpful?
Content-Type: *
Sometimes a server application needs to serve different representations of a resource at the same URI. Of course this can be done by hand, manually checking the Accept
request header and push the requested form of the content. However, as your app manages more resources and different kind of representations this can be very painful, as you may need to check for Accept-Charset
, Accept-Encoding
, put some server-side priorities , handle the errors correctly and e.t.c.
There are some web frameworks in Go already struggle to implement a feature like this but they don't do it correctly:
they don't handle accept-charset at all
they don't handle accept-encoding at all
they don't send error status code (406 not acceptable) as RFC proposes and more...
But, fortunately for us, Iris always follows the best practises and the Web standards.
Based on:
Implemented on:
The Context method which is responsible to render specific mime types based on the client's Accept
header is the Negotiate
one.
Before Negotiate
method fired, the handler MUST declare what mime types the server supports to render with safety. We can do that using the Negotiation
priorities builder.
Negotitation
priorities builderThe Context method which returns the builder is the Negotiation
one.
It returns:
The Accept
struct field can be used to customize the client's Accept header manually, e.g. when the client does not contain an "application/json" mime type on its Accept
header value.
In short, it contains the following methods:
The Build
is called automatically on Negotiate
method but it it's exported for a custom implementation of negotiation by the end-developer if ever required.
The Negotiation is a context method which sets and returns the negotiation builder, so it can be used inside a middleware too.
To declare what mime types server can render and match versus the client's Accept
header you can do that:
The above will tell the server that we can accept JSON, XML and HTML mime types, optionally encoding by Gzip if the client supports. So far nothing is rendered to the client, learn about the Negotiate
method below.
Negotiate
methodThe Context.Negotiate
method used for serving different representations of a resource at the same URI. It returns context.ErrContentNotSupported
when not matched mime types.
The "v" can be any value of struct (JSON, JSONP, XML, YAML, MsgPack, Protobuf) or
string(TEXT, HTML)
or []byte(Markdown, Binary)
or []byte
with any matched mime type.
If the "v" is nil, the Context.Negotitation()
builder's content will be used instead, otherwise "v" overrides builder's content (server mime types are still retrieved by its registered, supported, mime list)
Set mime type priorities by [Negotiation().MIME.Text.JSON.XML.HTML...]https://pkg.go.dev/github.com/kataras/iris/v12/context#NegotiationBuilder.JSON).
The iris.N
is a struct which can be passed on the Context.Negotiate
method. It contains fields which should be filled based on the Context.Negotiation()
server side values. If no matched mime then its "Other" field will be sent, which should be a string or []byte. It completes the ContentSelector
interface.
If the given interface{}
value is not a type which implements one the above then the Negotiate
method will render that based on the request's Accept
header value matching the declared priorities.
Note that if the given v interface{}
is nil then it will uses the contents declared by the Negotiation
builder itself.
When the client accepts JSON and XML and HTML responses from a specific server's endpoint and the server can render all of them:
That's all, read the examples for a comprehensive understanding in practise.
Read more about .
The NegotitationBuilder
has the necessary methods to help you prioritize mime types, charsets and encoding. .
The Context.Negotiate
method accepts an interface{}
which can be any Go value or a or a such as the structure (see below).
The "v" can be a single struct value.
The "v" can be any value completes the interface.
The "v" can be any value completes the interface.
Set charset priorities by .
Set encoding algorithm priorities by .
Modify the accepted by .