Skip to content

Content negotiation

snowly edited this page Feb 19, 2020 · 5 revisions

有时服务器应用程序需要在同一URI上提供资源的不同表示形式。 当然,这可以手动完成,手动检查“接受”请求标头并推送请求的内容形式。但是,随着你的应用管理更多的资源和不同类型的表示形式,这可能会非常痛苦 ,因为你可能需要检查 Accept-Charset, Accept-Encoding,放置一些服务器端优先级,正确处理错误以及进行其他操作。

GO 中有一些Web框架已经添加了实现这样的功能,但是它们没有正确实现:

  • 它们根本不处理接受字符集
  • 它们根本不处理接受编码
  • 它们 不会像RFC所建议的那样发送错误状态代码(不接受406)以及更多...

但是,对我们来说幸运的是,Iris 始终遵循最佳实践和Web标准。

基于:

实施于:

示例

type testdata struct {
	Name string `json:"name" xml:"Name"`
	Age  int    `json:"age" xml:"Age"`
}

使用 "gzip" 编码算法呈现资源为 application/json 或者 text/xml 或者 application/xml 格式。

  • 如果 accept 为空,当客户端的 accept 头包含它们其中的一个
  • 或 JSON(第一个声明的)
  • 和当客户端的 accept-encoding 头包含"gzip"或为空时。
app.Get("/resource", func(ctx iris.Context) {
	data := testdata{
		Name: "test name",
		Age:  26,
	}

        ctx.Negotiation().JSON().XML().EncodingGzip()

	_, err := ctx.Negotiate(data)
	if err != nil {
		ctx.Writef("%v", err)
	}
})

在中间件中定义它们,并在最终处理程序中使用 Negotiate(nil)。

ctx.Negotiation().JSON(data).XML(data).Any("content for */*")
ctx.Negotiate(nil)
app.Get("/resource2", func(ctx iris.Context) {
	jsonAndXML := testdata{
		Name: "test name",
		Age:  26,
	}

	ctx.Negotiation().
		JSON(jsonAndXML).
		XML(jsonAndXML).
		HTML("<h1>Test Name</h1><h2>Age 26</h2>")

	ctx.Negotiate(nil)
})

阅读完整的示例。

文档

Context.Negotiation 方法创建一次,然后返回协商生成器以构建特定内容的服务器端可用优先级内容类型,字符集和编码算法。

Context.Negotiation() *context.NegotiationBuilder

Context.Negotiation 方法用于在同一 URI 上提供资源的不同表示形式。 当没有匹配到任何 mime 类型时候,它返回 context.ErrContentNotSupported

Context.Negotiate(v interface{}) (int, error)