什么是 RESTful 编程?

问题描述:

RESTful programming 到底是什么?

解决方案1:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

REST 是 Web 的底层架构原则。 Web 的惊人之处在于,客户端(浏览器)和服务器可以以复杂的方式进行交互,而客户端无需事先了解服务器及其托管的资源。关键约束是服务器和客户端都必须就使用的媒体达成一致,在 Web 的情况下是 HTML。

遵循 REST 原则的 API 不需要客户端知道任何有关 API 结构的信息。相反,服务器需要提供客户端与服务交互所需的任何信息。 HTML 表单 就是一个例子:服务器指定资源的位置和必填字段。 浏览器事先不知道在哪里提交信息,也不事先知道要提交什么信息。两种形式的信息都完全由服务器提供。(此原理称为 HATEOAS: Hypermedia As The Engine Of Application State。)

那么,这如何适用于 HTTP,以及如何在实践中实现它? HTTP 是面向动词和资源的。主流用法的两个动词是GET和POST,我想大家都会认识的。但是,HTTP 标准定义了其他几个标准,例如 PUT 和 DELETE。然后根据服务器提供的指令将这些动词应用于资源。

例如,假设我们有一个由 Web 服务管理的用户数据库。我们的服务使用基于 JSON 的自定义超媒体,我们为其分配 mimetype application/json+userdb(可能还有 application/xml+userdb 和 application/whatever+userdb - 可能支持许多媒体类型)。客户端和服务器都被编程来理解这种格式,但他们对彼此一无所知。正如 Roy Fielding 指出的:

REST API 应该花费几乎所有的描述性工作来定义用于表示资源和驱动应用程序状态的媒体类型,或定义扩展关系名称和/或现有标准媒体类型的超文本启用标记。

对基础资源 / 的请求可能会返回如下内容:

要求

GET /
Accept: application/json+userdb

回复

200 OK
Content-Type: application/json+userdb

{
    "version": "1.0",
    "links": [
        {
            "href": "/user",
            "rel": "list",
            "method": "GET"
        },
        {
            "href": "/user",
            "rel": "create",
            "method": "POST"
        }
    ]
}

我们从媒体的描述中知道,我们可以从称为“链接”的部分中找到有关相关资源的信息。这称为超媒体控件。在这种情况下,我们可以从这样的部分得知,我们可以通过对 /user 发出另一个请求来找到用户列表:

要求

GET /user
Accept: application/json+userdb

回复

200 OK
Content-Type: application/json+userdb

{
    "users": [
        {
            "id": 1,
            "name": "Emil",
            "country: "Sweden",
            "links": [
                {
                    "href": "/user/1",
                    "rel": "self",
                    "method": "GET"
                },
                {
                    "href": "/user/1",
                    "rel": "edit",
                    "method": "PUT"
                },
                {
                    "href": "/user/1",
                    "rel": "delete",
                    "method": "DELETE"
                }
            ]
        },
        {
            "id": 2,
            "name": "Adam",
            "country: "Scotland",
            "links": [
                {
                    "href": "/user/2",
                    "rel": "self",
                    "method": "GET"
                },
                {
                    "href": "/user/2",
                    "rel": "edit",
                    "method": "PUT"
                },
                {
                    "href": "/user/2",
                    "rel": "delete",
                    "method": "DELETE"
                }
            ]
        }
    ],
    "links": [
        {
            "href": "/user",
            "rel": "create",
            "method": "POST"
        }
    ]
}

我们可以从这个回应中看出很多。例如,我们现在知道可以通过 POST 到 /user 创建一个新用户:

要求

POST /user
Accept: application/json+userdb
Content-Type: application/json+userdb

{
    "name": "Karl",
    "country": "Austria"
}

回复

201 Created
Content-Type: application/json+userdb

{
    "user": {
        "id": 3,
        "name": "Karl",
        "country": "Austria",
        "links": [
            {
                "href": "/user/3",
                "rel": "self",
                "method": "GET"
            },
            {
                "href": "/user/3",
                "rel": "edit",
                "method": "PUT"
            },
            {
                "href": "/user/3",
                "rel": "delete",
                "method": "DELETE"
            }
        ]
    },
    "links": {
       "href": "/user",
       "rel": "list",
       "method": "GET"
    }
}

我们还知道我们可以更改现有数据:

要求

PUT /user/1
Accept: application/json+userdb
Content-Type: application/json+userdb

{
    "name": "Emil",
    "country": "Bhutan"
}

回复

200 OK
Content-Type: application/json+userdb

{
    "user": {
        "id": 1,
        "name": "Emil",
        "country": "Bhutan",
        "links": [
            {
                "href": "/user/1",
                "rel": "self",
                "method": "GET"
            },
            {
                "href": "/user/1",
                "rel": "edit",
                "method": "PUT"
            },
            {
                "href": "/user/1",
                "rel": "delete",
                "method": "DELETE"
            }
        ]
    },
    "links": {
       "href": "/user",
       "rel": "list",
       "method": "GET"
    }
}

请注意,我们使用不同的 HTTP 动词(GET、PUT、POST、DELETE 等)来操作这些资源,并且我们假定客户端的唯一知识是我们的媒体定义。

进一步阅读:

这一页上有许多更好的答案。

我如何向我的妻子解释 REST。

我如何向我的妻子解释 REST。

马丁·福勒的想法

PayPal 的 API 具有超媒体控件

(这个答案因为没有抓住重点而受到相当多的批评。在大多数情况下,这是一个公平的批评。我最初描述的内容更符合几年前我通常如何实现 REST首先写这个,而不是它的真正含义。我已经修改了答案以更好地代表真正的含义。)

不,REST 不只是作为另一个流行词出现。它是作为一种描述基于 SOAP 的数据交换的替代方法而出现的。术语 REST 有助于构建关于如何传输和访问数据的讨论。

尽管如此,REST(在实际应用中)的核心是“不要使用 GET 进行更改,使用 POST/PUT/DELETE”,这是我早在 SOAP 出现之前就已经听到(并遵循)的建议。 REST 一直存在,只是直到最近它才获得了超越“实现方式”的名称。

不要忘记“超文本作为应用程序状态的引擎”。

这个答案没有抓住重点。在 Fielding 的论文中几乎没有提到 HTTP。

这个答案没有提到 REST 的目的,并且看起来就像是关于干净的 URI。虽然这可能是对 REST 的普遍看法,但 D.Shawley 和 oluies 的答案更准确 - 它是关于能够利用架构中内置的功能,如缓存,通过使用它而不是反对它。更漂亮的 URI 大多是常见的副作用。

解决方案2:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

一种称为 REST (Representational State Transfer) 的架构风格主张网络应用程序应该使用 HTTP,因为它是最初设想的。查找应使用 GET 请求。 PUT, POST, and DELETE requests 应分别用于 mutation、creation 和 deletion。

REST 支持者倾向于使用 URL,例如

http://myserver.com/catalog/item/1729

但 REST 架构不需要这些“漂亮的 URL”。带参数的 GET 请求

http://myserver.com/catalog?item=1729

一点也不像 RESTful。

请记住,永远不应使用 GET 请求来更新信息。例如,将商品添加到购物车的 GET 请求

http://myserver.com/addToCart?cart=314159&item=1729

不合适。 GET 请求应为 idempotent。也就是说,发出两次请求应该与发出一次没有什么不同。这就是使请求可缓存的原因。 “添加到购物车”请求不是幂等的——发出两次会将商品的两个副本添加到购物车中。在这种情况下,POST 请求显然是合适的。因此,即使是 RESTful Web 应用程序 也需要它的 POST 请求份额。

这取自 David M. Geary 的优秀书籍 Core JavaServer faces book。

列出可用的幂等操作:GET(安全)、PUT 和 DELETE(此链接restapitutorial.com/lessons/idempotency.html 中提到了例外)。安全和幂等方法的附加参考 w3.org/Protocols/rfc2616/rfc2616-sec9.html

a)关于 GET 的重点是安全性,而不是幂等性,b)@Abhijeet:RFC 2616 已于 2014 年过时;见射频 7230ff。

这是错误的。阅读此内容以正确解释 REST roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven 或此 stackoverflow.com/questions/19843480/…

@kushalvm REST 的学术定义并未在实践中使用。

实际上,我们可以怀疑一个概念是否可操作,因为我们无法简单地为所有人提供一个稳定且易于理解的定义

解决方案3:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

RESTful 编程是关于:

由持久标识符标识的资源:如今,URI 是无处不在的标识符选择

使用一组通用动词操作资源:HTTP 方法是常见的情况——古老的 Create、Retrieve、Update、Delete 变成 POST、GET、PUT 和 DELETE。但 REST 不限于 HTTP,它只是目前最常用的传输方式。

为资源检索的实际表示取决于请求而不是标识符:使用 Accept 标头来控制您是否需要 XML、HTTP 甚至是表示资源的 Java 对象

维护对象中的状态并在表示中表示状态

在资源的表示中表示资源之间的关系:对象之间的链接直接嵌入在表示中

资源表示描述了如何使用表示以及在什么情况下应该以一致的方式丢弃/重新获取它: HTTP Cache-Control 标头的使用

就 REST 的后果和整体有效性而言,最后一个可能是最重要的。总体而言,大多数 RESTful 讨论似乎都集中在 HTTP 及其在浏览器中的使用以及其他方面。我知道 R. Fielding 在描述导致 HTTP 的架构和决策时创造了这个术语。他的论文更多地是关于资源的架构和缓存能力,而不是关于 HTTP。

如果您真的对什么是 RESTful 架构及其工作原理感兴趣,请阅读 his thesis 几遍并阅读全部内容,而不仅仅是第 5 章!接下来查看 why DNS works。阅读有关 DNS 的分层组织以及引荐的工作原理。然后阅读并考虑 DNS 缓存的工作原理。最后,阅读 HTTP 规范(特别是 RFC2616 和 RFC3040)并考虑缓存如何以及为什么会以这种方式工作。最终,它只会点击。对我来说,最后的启示是当我看到 DNS 和 HTTP 之间的相似性时。在此之后,开始点击了解 SOA 和消息传递接口为何具有可扩展性。

我认为了解 RESTful 和 Shared Nothing 架构的架构重要性和性能影响的最重要技巧是避免陷入技术和实现细节上。关注谁拥有资源,谁负责创建/维护资源等。然后考虑表示、协议和技术。

提供阅读清单的答案非常适合这个问题。

感谢更新。 PUT 和 POST 并没有真正一对一地映射更新和创建。 PUT 可用于创建客户端是否指定 URI。 POST 如果服务器正在分配新的 URI,则创建。

URN 是使用 urn: 方案的 URI。从概念上讲没有区别;但是,URN 确实需要您有一个单独定义的方法来“定位”由 URN 标识(命名)的资源。必须注意确保在关联命名资源及其位置时不会引入隐式耦合。

@ellisbben 同意。如果我理解正确,这就是引发 REST 的论文:ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

关于这一点的一个疑问:“为资源检索的实际表示取决于请求而不是标识符:使用 HTTP Accept 标头来控制您是否需要 XML、HTTP 甚至是表示资源的 Java 对象”——这里,它应该是“......无论你想要 XML、HTML 还是代表资源的 Java 对象......”我认为 HTTP Accept 标头告诉数据交换的格式。 HTTP 是 RESTel Web API 中使用的协议

解决方案4:

huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求

这可能是它的样子。

创建具有三个属性的用户:

POST /user
fname=John&lname=Doe&age=25

服务器响应:

200 OK
Location: /user/123

将来,您可以检索用户信息:

GET /user/123

服务器响应:

200 OK
JohnDoe25

修改记录(lname 和 age 将保持不变):

PATCH /user/123
fname=Johnny

要更新记录(因此 lname 和 age 将为 NULL):

PUT /user/123
fname=Johnny

对我来说,这个答案抓住了所需答案的本质。简单实用。当然还有很多其他标准,但提供的示例是一个很棒的启动台。

在最后一个示例中,@pbreitenbach 使用 PUT fname=Jonny。这会将 lname 和 age 设置为默认值(可能是 NULL 或空字符串,以及整数 0),因为 PUT 使用提供的表示中的数据覆盖整个资源。这不是“更新”所暗示的,要进行真正的更新,请使用 PATCH 方法,因为这不会更改表示中未指定的字段。

尼古拉斯是对的。此外,创建用户的第一个 POST 的 URI 应该称为 users,因为 /user/1 没有意义,并且应该在 /users 处有一个列表。在这种情况下,响应应该是 201 Created 而不仅仅是 OK。

这只是一个 API 的示例,不一定是 RESTful api。 RESTful 具有它所遵循的约束。客户端-服务器架构,无状态,缓存能力,分层系统,统一接口。

这是一个非常紧凑的答案,涵盖了所有 http servlet 访问方法

解决方案5:

打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!

REST in Practice 是一本关于 REST 的好书。

必须阅读是 Representational State Transfer (REST) 和 REST APIs must be hypertext-driven

有关什么是 RESTful 服务的解释,请参阅 Martin Fowlers 文章 Richardson Maturity Model (RMM)。

https://i.stack.imgur.com/FoKRB.png

要成为 RESTful 服务需要满足 Hypermedia as the Engine of Application State. (HATEOAS),即它需要达到 RMM 中的第 3 级,read the article 了解详细信息或 slides from the qcon talk。

HATEOAS 约束是 Hypermedia as the Engine of Application State 的首字母缩写。此原则是 REST 与大多数其他形式的客户端服务器系统之间的关键区别。 … RESTful 应用程序的客户端只需要知道一个固定的 URL 即可访问它。所有未来的动作都应该可以从包含在从该 URL 返回的资源表示中的超媒体链接中动态发现。任何可能使用 RESTful API 的客户端也应该能够理解标准化的媒体类型。 (维基百科,自由的百科全书)

REST Litmus Test for Web Frameworks 是针对 Web 框架的类似成熟度测试。

Approaching pure REST: Learning to love HATEOAS 是一个很好的链接集合。

REST versus SOAP for the Public Cloud 讨论了 REST 的当前使用水平。

REST and versioning 通过可修改性讨论可扩展性、版本控制、可演化性等

我认为这个答案触及了理解 REST 的关键点:representative 这个词是什么意思。级别 1 - 资源说明状态。级别 2 - HTTP 动词说关于传输(读取更改)。第 3 级 - HATEOAS 表示通过表示(返回的 JSON/XML/HTML)推动未来的传输,这意味着您已经知道如何使用返回的信息进行下一轮对话。所以 REST 读作:“(代表性(状态转移))”,而不是“((代表性状态)转移)”。

Difference between REST and POX

解决方案6:

huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。

什么是 REST? REST 代表具象状态转移。 (有时拼写为“ReST”。)它依赖于无状态、客户端-服务器、可缓存的通信协议——几乎在所有情况下都使用 HTTP 协议。 REST 是一种用于设计网络应用程序的架构风格。这个想法是,不是使用复杂的机制,如 CORBA、RPC 或 SOAP 来连接机器,而是使用简单的 HTTP 在机器之间进行调用。在许多方面,基于 HTTP 的万维网本身可以被视为基于 REST 的架构。 RESTful 应用程序使用 HTTP 请求来发布数据(创建和/或更新)、读取数据(例如,进行查询)和删除数据。因此,REST 将 HTTP 用于所有四个 CRUD(创建/读取/更新/删除)操作。 REST 是 RPC(远程过程调用)和 Web 服务(SOAP、WSDL 等)等机制的轻量级替代方案。稍后,我们将看到 REST 是多么简单。尽管很简单,但 REST 功能齐全;在 Web 服务中,基本上没有什么是 RESTful 架构无法完成的。 REST 不是“标准”。例如,永远不会有针对 REST 的 W3C 推荐。虽然有 REST 编程框架,但使用 REST 非常简单,您通常可以使用 Perl、Java 或 C# 等语言的标准库功能“自行开发”。

当我试图找到休息的简单真正含义时,我找到了最好的参考资料之一。

http://rest.elkstein.org/

这是一个非常简洁的答案。你能否描述一下为什么 REST 被称为无状态?

解决方案7:

huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。

REST 使用各种 HTTP 方法(主要是 GET/PUT/DELETE)来操作数据。

与其使用特定 URL 来删除方法(例如 /user/123/delete),不如向 /user/[id] URL 发送 DELETE 请求,以编辑用户,检索您向 {2 }

例如,取而代之的是一组可能类似于以下内容的 URL。

GET /delete_user.x?id=123
GET /user/delete
GET /new_user.x
GET /user/new
GET /user?id=1
GET /user/id/1

您使用 HTTP“动词”并拥有…

GET /user/2
DELETE /user/2
PUT /user

那就是“正确使用HTTP”,和“restful”不一样(虽然和它有关)

您也可以使用 /user/del/2 和 /user/remove/2 或... GET/DELETE/PUT/POST 只是标准化的“正确”方式来做这些事情(正如朱利安所说,这还不是全部有休息)

当然,但这不是避免它们的理由。REST 只是让您每次都重新发明轮子。对于 API,REST 很棒(一致性!),但对于构建一个随机网站,我想说这并不重要(它可能比它的价值更麻烦)

Vadim,那就是简单的 RPC。使用 GET 修改数据也很危险,因为(除其他原因外)搜索引擎可能会抓取您的删除链接并访问它们。

@aehlke - 我认为真正的问题是“为什么匿名用户能够从您的系统中删除记录?”

解决方案8:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

它是您的系统架构符合 Roy Fielding 在 his thesis 中提出的 REST style 的编程。由于这是描述网络的架构风格(或多或少),所以很多人都对它感兴趣。

奖励答案:不。除非您正在研究软件架构作为学术或设计 Web 服务,否则真的没有理由听说过这个术语。

但不是直截了当..使它变得更加复杂。

此外,尽管 REST 和 RESTful 这两个术语现在几乎专门用于 Web 应用程序领域,但从技术上讲,没有任何东西将 REST 与 HTTP 联系起来。

Fielding 的博客有一些关于 REST 和常见误解的好文章,更易于理解:roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

@HankGay 我认为它不是更深奥的原因是大多数 Web 服务开发人员将 REST 视为对 SOAP 等替代方案的极好的简化。他们不一定坚持让所有 REST 技术正确——这可能会让 REST 狂热者发疯——但在大多数情况下,他们可能不需要担心诸如确保他们的结果是“支持超媒体的”之类的事情。

解决方案9:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

我会说 RESTful 编程是关于创建遵循 REST 架构风格的系统 (API)。

我发现 M. Elkstein 博士撰写的关于 REST 的精彩、简短且易于理解的教程,并引用了大部分可以回答您的问题的基本部分:

Learn REST: A Tutorial

REST 是一种用于设计网络应用程序的架构风格。这个想法是,不是使用复杂的机制,如 CORBA、RPC 或 SOAP 来连接机器,而是使用简单的 HTTP 在机器之间进行调用。在许多方面,基于 HTTP 的万维网本身可以被视为基于 REST 的架构。 RESTful 应用程序使用 HTTP 请求来发布数据(创建和/或更新)、读取数据(例如,进行查询)和删除数据。因此,REST 将 HTTP 用于所有四个 CRUD(创建/读取/更新/删除)操作。

我认为你不应该因为没有听到 Stack Overflow 之外的 REST 而感到愚蠢…,我也会遇到同样的情况!回答 Why is REST getting big now 上的其他 SO 问题可以缓解一些情绪。

本文解释了 HTTP 和 REST freecodecamp.org/news/… 之间的关系

解决方案10:

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

如果我没有直接回答问题,我深表歉意,但是通过更详细的示例更容易理解所有这些。由于所有的抽象和术语,Fielding 并不容易理解。

这里有一个相当好的例子:

Explaining REST and Hypertext: Spam-E the Spam Cleaning Robot

更好的是,这里有一个简单的例子的清晰解释(powerpoint 更全面,但你可以在 html 版本中获得大部分内容):

http://www.xfront.com/REST.ppt 或 http://www.xfront.com/REST.html

阅读示例后,我可以理解为什么 Ken 说 REST 是超文本驱动的。不过,我实际上不确定他是否正确,因为 /user/123 是一个指向资源的 URI,而且我不清楚它是否是非 RESTful 只是因为客户端“带外”知道它。

该 xfront 文档解释了 REST 和 SOAP 之间的区别,这也很有帮助。当 Fielding 说“That is RPC. It screams RPC.”时,很明显 RPC 不是 RESTful,因此了解其确切原因很有用。 (SOAP 是一种 RPC。)

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

很酷的链接,谢谢。我厌倦了这些 REST 家伙说某些示例不是“REST-ful”,然后拒绝说如何将示例更改为 REST-ful。

解决方案11:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

什么是 REST?

REST 用官方的话说,REST 是一种架构风格,建立在某些原则之上,使用当前的“Web”基础。有 5 个 Web 基本原理可用于创建 REST 服务。

原则 1:一切都是资源 在 REST 架构风格中,数据和功能被视为资源,并使用统一资源标识符 (URI) 访问,通常是 Web 上的链接。

原则 2:每个资源都由唯一标识符 (URI) 标识

原则 3:使用简单统一的接口

原则 4:沟通由代表完成

原则 5:无国籍

Communication is Done by Representation 是什么意思?

原文链接:https://www.huntsbot.com/qa/OdLX/what-is-restful-programming?lang=zh_CN

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值