首页 文章

REST和HATEOS定义是否自我违规?

提问于
浏览
-4

问题:如果一个接口被认为不是RESTful(根据Fielding),当客户端无法利用带内数据时,可以将REST中的HATEOAS视为一个有效的命题(URI 's) from the Response Hypertext (Hypermedia) without reference to an external (out-of-band) document, and therefore tightly coupling Client and Server according to Fielding, how can we do anything but fail Roy Fielding' s prima facie assertion

在我看来,菲尔丁的论述使得HATEOAS和REST成为一种内部矛盾的命题,这种命题无法用当前的技术来实现 - 除非有人知道怎么做而不引用带外数据?

(编辑)我怀疑没有人正在阅读/阅读Fielding 's rant, so here'是最相关的部分:

“应该输入REST API,除了初始URI(书签)之外没有任何先验知识,并且适用于目标受众的标准化媒体类型集合(即,任何可能使用API的客户都应该理解) . 如图所示,所有应用程序状态转换必须由客户端选择服务器提供的选择来驱动,这些选择存在于接收的表示中或者由用户对这些表示的操纵所暗示 . 转换可以由客户端的媒体知识确定(或限制)类型和资源通信机制,两者都可以在运行中进行改进(例如,按需代码). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]

我们都坚持认为我们必须拥有URI的带外知识's available methods beyond the initial data stream. Note how Fielding very stridently tells us that this is failure. Yet, it' s我们如何将它全部包括在内,包括我在内 . 但是菲尔丁尖叫着不回头对我们说 .

(编辑:因为没人读它的解释) .

3 回答

  • 0

    不,REST和HATEOAS互不矛盾 . 事实上,这个命题甚至没有意义,因为HATEOAS是REST定义的一部分 . 它们不是两个独立的东西 .

    为了更好地理解菲尔丁的带外知识,我建议考虑使用网络浏览器 . Web浏览器是实现一组标准(HTTP,HTML,URI等)的通用客户端 . 客户端实现的任何标准都可以被认为是带内的 . 在通用客户端实现的标准之一中未表达的任何内容都是带外的 .

    如果您的资源看起来像这样

    GET /some/resource HTTP/1.1
    Content-Type: application/json
    
    {
      "author": "/authors/me",
      "foo": 42
    }
    

    作为一个人,我可以看一下,并认识到“作者”的 Value 看起来像一个链接,我可以尝试遵循它,但通用浏览器只能将其识别为普通的JSON . 这只是一个字符串 . 解释“作者”是一个链接需要带外知识 .

    解决方案是选择定义如何表达链接的超媒体媒体类型 . 这是用HAL表示的那个例子 .

    GET /some/resource HTTP/1.1
    Content-Type: application/hal+json
    
    
    {
      "_links": {
        "author": { "href": "/authors/me" }
      },
      "foo": 42
    }
    

    可以开发理解HAL的通用客户端 . 我的API和您的API都可以使用相同的客户端,而无需了解彼此或了解任何API的客户端 .

    关于如何知道链接使用哪种方法的问题也取决于要定义的超媒体媒体类型 . HTML通过定义语义暗示方法的构造来实现 . 锚标记 <a href="/foo">foo</a> 表示GET请求 . 表单标记具有类似的明确定义的语义 . 基于JSON的超媒体格式必须定义它's own structures and semantics for those structures. All of this is considered in-band because it'是可以由通用浏览器实现的标准的一部分 .

    因此,如果您希望获得Roy API对您的REST API的批准,您需要使用标准化的通用超媒体媒体类型,该类型能够描述您的应用程序需要执行的所有操作 . 我最喜欢的是JSON Hyper-Schema . 它是最好的描述类似没有带外知识的表单帖子,因为它使用JSON Schema来描述服务器期望的数据 .

  • -1

    REST允许的三个先验知识:API的主页(在浏览器中,这是由用户键入地址栏提供的);了解常见的媒体类型,例如HTML(由浏览器开发人员提供);通知客户端应用程序的链接关系可以在决定做什么时查看(例如, rel=stylesheet 链接被图形浏览器自动下载和解析,以使它们呈现的文档看起来很漂亮) .

    REST禁止的是客户知道它可以执行诸如从您网页上的某个位置读取ID然后将其附加到 youtube.com/watch?v= 的末尾以获取YouTube视频 . 相反,您应该定义"video-clip"链接关系并使用媒体类型的超链接机制来提供完整的URL,而不仅仅是ID .

  • -1

    所以,我的问题的答案似乎是,没有人知道如何按照菲尔丁的说法去做应该这样做,所以我们都不知道如何在不违反Fielding关于带外数据的主要断言的情况下实现符合HATEOAS标准的RESTful API,从而使我们的应用程序非RESTful .

    每个人都强烈认为他们有正确的答案,但我们都忽视了罗伊菲尔丁说我们都错了 . 他说我们都在写RPC .

    Roy Fielding: REST APIs must be hypertext-driven“我对调用 any 基于HTTP的接口REST API的人数感到沮丧”

    归结为这样一个事实,即我们没有构建那些适合作为CDATA的一部分的应用程序,包括"method"或者URI的上下文无疑会提供它,就像FORM元素那样 . 他明确指责OpenSocialst REST API声明它不是RESTful .

    这里:“具有href属性的锚元素创建一个超文本链接,当选择该链接时,在对应于CDATA编码的href属性的URI上调用检索请求(GET) . ”标识符,方法和媒体类型是正交关注点 - 方法没有给出媒体类型的含义 . 相反,媒体类型告诉客户端使用什么方法(例如,锚意味着GET)或如何确定要使用的方法(例如,表单元素表示查看方法属性) . 客户端应该已经知道方法的含义(它们是通用的)以及如何取消引用URI .

    我倾向于设计提供此方法的JSON响应:

    GET /account/12345 HTTP/1.1
    {
        "account": {
            "number": "12345",
            "currency": "usd",
            "balance": "100.00",
            "deposit": {
                "href": "/account/12345/deposit",
                "action": "POST"
            },
            "withdraw": {
                "href": "/account/12345/withdraw",
                "action": "POST"
            },
            "transfer": {
                "href": "/account/12345/transfer",
                "action": "POST"
            },
            "close": {
                "href": "/account/12345/close",
                "action": "DELETE"
            }
        }
    }
    

    ...根据需要为设计添加其他属性,但这些是基础知识 .

    我相信这允许客户端被编写成RESTful,但这样做我正在使用响应主体,Fielding说这不是他想要的 .

相关问题