相同资源的不同 RESTful 表示 [英] Different RESTful representations of the same resource

查看:17
本文介绍了相同资源的不同 RESTful 表示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序在 /foo 中有一个资源.通常,它由 HTTP 响应负载表示,如下所示:

My application has a resource at /foo. Normally, it is represented by an HTTP response payload like this:

{"a": "some text", "b": "some text", "c": "some text", "d": "some text"}

客户端并不总是需要这个对象的所有四个成员.客户端告诉服务器它在表示中需要什么的 RESTfully 语义 方式是什么?例如如果它愿意:

The client doesn't always need all four members of this object. What is the RESTfully semantic way for the client to tell the server what it needs in the representation? e.g. if it wants:

{"a": "some text", "b": "some text", "d": "some text"}

它应该如何GET呢?一些可能性(如果我误解了 REST,我正在寻找更正):

How should it GET it? Some possibilities (I'm looking for correction if I misunderstand REST):

  • GET/foo?sections=a,b,d.
    • 查询字符串(毕竟称为 query 字符串)似乎意味着找到与此条件匹配的资源并告诉我有关它们的信息",而不是根据此自定义向我表示此资源".
    • GET /foo?sections=a,b,d.
      • The query string (called a query string after all) seems to mean "find resources matching this condition and tell me about them", not "represent this resource to me according to this customization".
      • 打破 URI 不透明,违反 HATEOAS.
      • 似乎打破了资源(URI 的唯一含义是标识一个资源)和表示之间的区别.但这是有争议的,因为它与表示 /widget/ 资源的可呈现列表的 /widgets 一致,我从来没有遇到过问题.
      • Breaks URI opacity, violating HATEOAS.
      • Seems to break the distinction between resource (the sole meaning of a URI is to identify one resource) and representation. But that's debatable because it's consistent with /widgets representing a presentable list of /widget/<id> resources, which I've never had a problem with.
      • 增加开销,如果 /foo 有数百个组件而客户端需要其中 100 个,这可能会变成一场噩梦.
      • 如果我想支持 /foo 的 HTML 表示,我必须使用 Ajax,如果我只想要一个可以被极简浏览器抓取、呈现等的 HTML 页面,这是有问题的.
      • 为了维护 HATEOAS,它还需要指向那些子资源"的链接以存在于其他表示中,可能在 /foo: {"a": {"url": "/foo/a", "content": "some text"}, ...}
      • Multiplies overhead, which can become a nightmare if /foo has hundreds of components and the client needs 100 of those.
      • If I want to support an HTML representation of /foo, I have to use Ajax, which is problematic if I just want a single HTML page that can be crawled, rendered by minimalist browsers, etc.
      • To maintain HATEOAS, it also requires links to those "sub-resources" to exist within other representations, probably in /foo: {"a": {"url": "/foo/a", "content": "some text"}, ...}
      • 不可添加书签且不可缓存.
      • HTTP 没有为 GET 定义正文语义.这是合法的 HTTP,但我如何保证某些用户的代理不会从 GET 请求中剥离正文?
      • 我的REST 客户端 不会让我将正文放在 GET 请求中,因此我无法将其用于测试.
      • Unbookmarkable and uncacheable.
      • HTTP does not define body semantics for GET. It's legal HTTP but how can I guarantee some user's proxy doesn't strip the body from a GET request?
      • My REST client won't let me put a body on a GET request so I can't use that for testing.
      • 如果可能,我宁愿避免使用自定义标题.
      • 不可添加书签且不可缓存.
      • 笨重;需要来回和一些看起来很奇怪的代码.
      • 不可标记和不可缓存,因为 /foo/requests/1 只是一个别名,只能使用一次,并且只保留到被请求为止.
      • Clunky; requires back-and-forth and some weird-looking code.
      • Unbookmarkable and uncacheable since /foo/requests/1 is just an alias that would only be used once and only kept until it is requested.

      推荐答案

      我决定了以下几点:

      支持少数成员组合:我会为每个组合命名.例如如果文章有作者、日期和正文成员,/article/some-slug 将返回所有成员,/article/some-slug/meta 将仅返回作者和日期.

      Supporting few member combinations: I'll come up with a name for each combination. e.g. if an article has members for author, date, and body, /article/some-slug will return all of it and /article/some-slug/meta will just return the author and date.

      支持多种组合:我将用连字符分隔成员名称:/foo/a-b-c.

      Supporting many combinations: I'll separate member names by hyphens: /foo/a-b-c.

      无论哪种方式,如果组合不受支持,我都会返回 404.

      Either way, I'll return a 404 if the combination is unsupported.

      来自REST的定义:

      资源 R 是随时间变化的隶属函数 MR(t),对于时间 t 映射到一组等效的实体或值.集合中的值可以是资源表示和/或资源标识符.

      a resource R is a temporally varying membership function MR(t), which for time t maps to a set of entities, or values, which are equivalent. The values in the set may be resource representations and/or resource identifiers.

      表示是 HTTP 正文,标识符是 URL.

      A representation being an HTTP body and an identifier being a URL.

      这很关键.标识符只是与其他标识符和表示相关联的值.这与标识符→表示映射不同.服务器可以将它想要的任何标识符映射到任何表示,只要两者都由相同的资源关联即可.

      This is crucial. An identifier is just a value associated with other identifiers and representations. That's distinct from the identifier→representation mapping. The server can map whatever identifier it wants to any representation, as long as both are associated by the same resource.

      开发人员可以通过考虑诸如用户"和用户"等类别来合理地描述业务的资源定义.和帖子".

      It's up to the developer to come up with resource definitions that reasonably describe the business by thinking of categories of things like "users" and "posts".

      如果我真的关心完美的 HATEOAS,我可以在 /foo 表示中的某处放置一个超链接到 /foo/members,并且该表示将只包含一个超链接到每个受支持的成员组合.

      If I really care about perfect HATEOAS, I could put a hyperlink somewhere in the /foo representation to /foo/members, and that representation would just contain a hyperlink to every supported combination of members.

      来自 URL 的定义:

      查询组件包含非分层数据,这些数据与路径组件中的数据一起用于标识 URI 方案和命名权限(如果有)范围内的资源.

      The query component contains non-hierarchical data that, along with data in the path component, serves to identify a resource within the scope of the URI's scheme and naming authority (if any).

      所以 /foo?sections=a,b,d/foo?sections=b 是不同的标识符.但是它们可以在同一资源中关联,同时映射到不同的表示.

      So /foo?sections=a,b,d and /foo?sections=b are distinct identifiers. But they can be associated within the same resource while being mapped to different representations.

      HTTP 的 404 代码 意味着 服务器找不到任何可以将 URL 映射到的内容,而不是该 URL 与任何资源都没有关联.

      HTTP's 404 code means that the server couldn't find anything to map the URL to, not that the URL is not associated with any resource.

      任何浏览器或缓存都不会遇到斜线或连字符的问题.

      No browser or cache will ever have trouble with slashes or hyphens.

      这篇关于相同资源的不同 RESTful 表示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆