RESTful编程究竟是什么?

时间:2009-03-22 14:45:39

标签: http rest definition

RESTful编程究竟是什么?

35 个答案:

答案 0 :(得分:2871)

REST 是Web的基础架构原则。关于Web的惊人之处在于,客户端(浏览器)和服务器可以以复杂的方式进行交互,而客户端无需事先了解服务器及其承载的资源。关键的限制是服务器和客户端必须同意所使用的 media ,在Web的情况下, HTML

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

那么,这如何适用于 HTTP ,以及如何在实践中实现? HTTP围绕动词和资源。主流使用的两个动词是GETPOST,我认为每个人都会认出。但是,HTTP标准定义了其他几个,例如PUTDELETE。然后根据服务器提供的说明将这些动词应用于资源。

例如,假设我们有一个由Web服务管理的用户数据库。我们的服务使用基于JSON的自定义超媒体,我们为其分配了mimetype application/json+userdb(可能还有application/xml+userdbapplication/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动词(GETPUTPOSTDELETE等)来操纵这些资源,并且我们认为这是唯一的知识在客户端是我们的媒体定义。

进一步阅读:

(这个答案因为忽略了这一点而受到了相当多的批评。在大多数情况下,这是一个公平的批评。我最初所描述的更符合REST通常如何实施几年在我第一次写这篇文章时,而不是它的真实含义。我修改了答案以更好地代表真正的意义。)

答案 1 :(得分:663)

名为REST (Representational State Transfer)体系结构样式提倡Web应用程序应使用HTTP,因为最初设想。查找应使用GET个请求。 PUT, POST, and DELETE requests应分别用于变异,创建和删除

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

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

但REST架构不需要这些&#34;漂亮的URL&#34;。带参数

的GET请求
http://myserver.com/catalog?item=1729

就像RESTful一样。

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

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

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

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

答案 2 :(得分:522)

RESTful编程是关于:

  • 资源由持久性标识符标识:URI是目前无处不在的标识符选择
  • 使用一组通用动词操纵资源:HTTP方法是常见的案例 - 古老的CreateRetrieveUpdateDelete变为{{1 },POSTGETPUT。但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规范(特别是RFC2616RFC3040)并考虑缓存的工作方式和原因。最终,它只会点击。对我来说,最后的启示是当我看到DNS和HTTP之间的相似之处时。在此之后,了解SOA和消息传递接口可扩展的原因开始单击。

我认为理解RESTful和Shared Nothing体系结构的体系结构重要性和性能影响的最重要技巧是避免对技术和实现细节感到困惑。专注于谁拥有资源,谁负责创建/维护它们等等。然后考虑表示,协议和技术。

答案 3 :(得分:404)

这可能是它的样子。

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

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

服务器响应:

200 OK
Location: /user/123

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

GET /user/123

服务器响应:

200 OK
<fname>John</fname><lname>Doe</lname><age>25</age>

修改记录(lnameage将保持不变):

PATCH /user/123
fname=Johnny

更新记录(因此lnameage将为NULL):

PUT /user/123
fname=Johnny

答案 4 :(得分:178)

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

必读内容为Representational State Transfer (REST)REST APIs must be hypertext-driven

请参阅Martin Fowlers文章Richardson Maturity Model(RMM),了解有关RESTful服务的内容。

Richardson Maturity Model

要成为RESTful,服务需要满足Hypermedia as the Engine of Application State. (HATEOAS),也就是说,它需要达到RMM中的第3级,read the article以获取详细信息或slides from the qcon talk

  

HATEOAS约束是首字母缩略词   用于超媒体作为引擎   申请国。这个原则是   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讨论了可扩展性,版本控制,可演化性等。  通过可修改性

答案 5 :(得分:133)

  

什么是REST?

     

REST代表Representational State Transfer。 (有时候   拼写为“ReST”。)它依赖于无状态的客户端服务器,可缓存   通信协议 - 实际上在所有情况下都是HTTP   使用协议。

     

REST是一种用于设计网络应用程序的架构风格。   这个想法是,而不是使用CORBA之类的复杂机制,   用于在机器之间连接的RPC或SOAP,用于制作简单的HTTP   机器之间的通话。

     

在许多方面,可以查看基于HTTP的万维网本身   作为基于REST的架构。 RESTful应用程序使用HTTP请求   发布数据(创建和/或更新),读取数据(例如,进行查询),   并删除数据。因此,REST对所有四个CRUD使用HTTP   (创建/读取/更新/删除)操作。

     

REST是RPC(Remote)等机制的轻量级替代品   过程调用)和Web服务(SOAP,WSDL等)。稍后,我们会   看看REST有多简单。

     

尽管很简单,但REST功能齐全;基本上就是这样   您无法在Web服务中执行任何无法使用RESTful执行的操作   建筑。 REST不是“标准”。永远不会有W3C   例如,推荐REST用于REST。虽然有REST   编程框架,使用REST非常简单,你可以   通常使用标准库功能“滚动你自己”   Perl,Java或C#。

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

http://rest.elkstein.org/

答案 6 :(得分:88)

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

您可以向/user/123/delete网址发送DELETE请求,编辑用户,检索用户的信息,而不是使用特定的网址来删除方法(例如/user/[id])向/user/[id]

发送GET请求

例如,而是一组可能看起来像以下某些内容的网址。

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

答案 7 :(得分:67)

这是编程,其中系统的体系结构符合Roy {{{}}中由Roy Fielding设计的REST style。由于这是描述网络的架构风格(或多或少),很多人都对它感兴趣。

奖金回答:不会。除非您正在学习软件架构作为学术或设计网络服务,否则没有理由听到这个术语。

答案 8 :(得分:45)

如果我没有直接回答这个问题,我很抱歉,但通过更详细的例子更容易理解这一切。由于所有的抽象和术语,Fielding不容易理解。

这里有一个相当不错的例子:

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

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

http://www.xfront.com/REST.ppthttp://www.xfront.com/REST.html

阅读完示例后,我可以看出为什么Ken说REST是超文本驱动的。我不确定他是对的,因为/ user / 123是一个指向资源的URI,而且我不清楚它是不是因为客户端“带外”知道它是不可靠的。

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

答案 9 :(得分:44)

我想说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问题的回答可以缓解一些感受。

答案 10 :(得分:38)

什么是REST?

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

  • 原则1:一切都是资源 在REST架构风格中,数据和功能被视为资源,可使用统一资源标识符(URI)访问,通常是Web上的链接。
  • 原则2:每个资源都由唯一标识符(URI)标识
  • 原则3:使用简单和统一的接口
  • 原则4:通过陈述进行沟通
  • 原则5:无国籍

答案 11 :(得分:33)

我看到一堆答案说将用户123的所有内容放在资源“/ user / 123”上是RESTful。

创造这个词的罗伊菲尔丁说REST APIs must be hypertext-driven。特别是,“REST API不能定义固定资源名称或层次结构”。

因此,如果您的“/ user / 123”路径在客户端上是硬编码的,那么它并不是真正的RESTful。很好地利用HTTP,也许不是。但不是RESTful。它必须来自超文本。

答案 12 :(得分:26)

答案非常简单,罗伊·菲尔丁写了dissertation。] 1在论文中,他定义了REST原则。如果应用程序满足所有这些原则,那么这就是REST应用程序。

The term RESTful was created because ppl exhausted the word REST by calling their non-REST application as REST.之后,RESTful这个词也用尽了。 Nowadays we are talking about Web APIs and Hypermedia APIs,因为大多数所谓的REST应用程序都没有满足统一接口约束的HATEOAS部分。

REST约束如下:

  1. 客户端 - 服务器架构

    因此它不适用于例如PUB / SUB套接字,它基于REQ / REP。

  2. 无国籍传播

    因此服务器不维护客户端的状态。这意味着您无法使用服务器端会话存储,您必须验证每个请求。您的客户端可能通过加密连接发送基本身份验证标头。 (大型应用程序很难维持很多会话。)

  3. 如果可以

    使用缓存

    因此,您不必一次又一次地提供相同的请求。

  4. 统一接口作为客户端和服务器之间的通用契约

    服务器不维护客户端与服务器之间的合同。换句话说,客户端必须与服务的实现分离。您可以使用标准解决方案达到此状态,例如用于标识资源的IRI(URI)标准,用于交换消息的HTTP标准,用于描述正文序列化格式的标准MIME类型,元数据(可能是RDF词汇,微格式等)到描述消息体不同部分的语义。要将IRI结构与客户端分离,您必须以超媒体格式(如HTML,JSON-LD,HAL等)向客户端发送超链接。因此,客户端可以使用分配给超链接的元数据(可能是链接关系,RDF词汇)来通过适当的状态转换来导航应用程序的状态机,以实现其当前目标。

    例如,当客户想要向网上商店发送订单时,它必须检查网上商店发送的响应中的超链接。通过检查链接,它找到了http://schema.org/OrderAction描述的链接。客户端知道schema.org词汇,因此它了解通过激活此超链接,它将发送订单。因此,它激活超链接并发送POST https://example.com/api/v1/order消息与正确的正文。之后,服务处理消息并使用具有正确HTTP状态标头的结果进行响应,例如201 - created成功。要使用详细元数据注释消息,使用RDF格式的标准解决方案,例如JSON-LD和REST词汇,例如Hydra和特定领域的词汇,如schema.org或任何其他{{3}如果需要,也许是自定义应用程序特定的词汇。现在这并不容易,这就是为什么大多数人使用HAL和其他通常只提供REST词汇但没有链接数据支持的简单格式的原因。

  5. 构建分层系统以提高可扩展性

    REST系统由分层结构组成。每个层都包含使用下一层中组件服务的组件。因此,您可以毫不费力地添加新的图层和组件。

    例如,有一个包含客户端的客户端层,下面是一个包含单个服务的服务层。现在,您可以在它们之间添加客户端缓存。之后,您可以添加另一个服务实例和负载均衡器,等等......客户端代码和服务代码不会更改。

  6. 按需扩展客户端功能的代码

    此约束是可选的。例如,您可以将特定媒体类型的解析器发送到客户端,依此类推......为了做到这一点,您可能需要在客户端中使用标准插件加载器系统,或者您的客户端将耦合到插件加载器解决方案

  7. REST约束导致高度可扩展的系统,其中客户端与服务的实现分离。因此,客户端可以重复使用,就像网络上的浏览器一样。客户端和服务共享相同的标准和词汇,因此尽管客户端不知道服务的实现细节,但他们可以相互理解。这使得创建自动化客户端成为可能,这些客户端可以找到并利用REST服务来实现其目标。从长远来看,这些客户可以相互沟通,相互信任,就像人类一样。如果我们向这样的客户端添加学习模式,那么结果将是使用机器网而不是单个服务器园的一个或多个AI。所以最后伯纳斯李的梦想:语义网和人工智能将成为现实。所以在2030年我们终于被天网终止了。在那之前...; - )

答案 13 :(得分:20)

RESTful(具象状态转移)API编程通过遵循5种基本软件architectural style原则,以任何编程语言编写Web应用程序:

  1. 资源(数据,信息)。
  2. Unique global identifier(所有资源都由URI标识为唯一。)
  3. Uniform interface - 使用简单和标准接口(HTTP)。
  4. 代表 - 所有通讯均以代表方式完成(例如XML / JSON
  5. Stateless(每个请求都完全隔离,缓存和负载平衡更容易),
  6. 换句话说,您正在通过HTTP编写简单的点对点网络应用程序,它通过实现RESTful架构来使用诸如GET,POST,PUT或DELETE之类的动词,该架构提出了每个“资源”公开的接口的标准化。以简单有效的方式使用Web的当前功能(非常成功,经过验证和分布式架构)并不是什么。它是SOAPCORBARPC等更复杂机制的替代方案。

    RESTful编程符合Web架构设计,如果实施得当,它可以让您充分利用可扩展的Web基础架构。

答案 14 :(得分:17)

如果我不得不将关于REST的原始论文减少到只有3个短句,我认为以下内容抓住了它的本质:

  1. 通过网址请求资源。
  2. 协议仅限于您可以使用网址进行通信的内容。
  3. 元数据作为名称 - 值对传递(发布数据和查询字符串参数)。
  4. 之后,很容易陷入有关改编,编码惯例和最佳实践的争论中。

    有趣的是,论文中没有提到HTTP POST,GET,DELETE或PUT操作。这必须是某人后来对“统一界面”的“最佳实践”的解释。

    当谈到Web服务时,似乎我们需要一些区分WSDL和基于SOAP的体系结构的方法,这会增加相当大的开销,并且可能会给接口带来很多不必要的复杂性。他们还需要额外的框架和开发人员工具才能实现。我不确定REST是否是区分常识接口和过度设计的接口(如WSDL和SOAP)的最佳术语。但我们需要一些东西。

答案 15 :(得分:17)

REST是一种编写分布式应用程序的架构模式和风格。从狭义上讲,它不是一种编程风格。

说你使用REST风格类似于说你建造了一个特定风格的房子:例如Tudor或Victorian。作为软件风格的REST和作为家庭风格的都铎王朝或维多利亚时代都可以通过构成它们的品质和约束来定义。例如,REST必须具有客户端服务器分离,其中消息是自描述的。都铎风格的住宅拥有重叠的山墙和屋顶,与前面的山墙陡峭搭配。您可以阅读Roy的论文,以了解构成REST的约束和质量的更多信息。

REST不同于家庭风格一直很难实际应用。这可能是故意的。将其实际实施留给设计师。因此,只要您满足创建REST系统论文中规定的约束条件,您就可以自由地执行您想要的任务。

加成:

整个网络基于REST(或REST基于Web)。因此,作为Web开发人员,您可能需要注意这一点,尽管没有必要编写好的Web应用程序。

答案 16 :(得分:17)

这是我的REST基本概要。我试图展示RESTful架构中每个组件背后的思想,以便更直观地理解这个概念。希望这有助于为某些人揭开REST的神秘面纱!

REST(Representational State Transfer)是一种设计架构,概述了如何设计和寻址网络资源(即共享信息的节点)。通常,RESTful架构使得客户端(请求机器)和服务器(响应机器)可以请求读取,写入和更新数据,而客户端不必知道服务器如何操作以及服务器可以通过它不需要知道客户端的任何信息。好的,很酷......但我们在实践中如何做到这一点?

  • 最明显的要求是需要某种通用语言,以便服务器可以告诉客户端它尝试对请求做什么以及服务器做出响应。

  • 但是为了找到任何给定的资源,然后告诉客户端资源在哪里,需要有一种指向资源的通用方法。这是统一资源标识符(URI)的用武之地;它们基本上是查找资源的唯一地址。

但REST架构并没有就此结束!虽然上述内容满足了我们想要的基本需求,但我们还希望拥有一个支持高流量流量的体系结构,因为任何给定的服务器通常都会处理来自多个客户端的响应。因此,我们不希望通过记住有关先前请求的信息来压倒服务器。

  • 因此,我们强加了客户端和服务器之间的每个请求 - 响应对是独立的限制,这意味着服务器不必记住有关先前请求的任何信息(客户端 - 服务器交互的先前状态) )回应新请求。这意味着我们希望我们的互动是无国籍的。

  • 为了进一步减轻我们的服务器上的压力,使其重做最近为给定客户端完成的计算,REST还允许缓存。基本上,缓存意味着拍摄提供给客户端的初始响应的快照。如果客户端再次发出相同的请求,则服务器可以向客户端提供快照,而不是重做创建初始响应所需的所有计算。但是,由于它是快照,如果快照尚未过期 - 服务器提前设置过期时间 - 并且响应自初始缓存以来已更新(即请求将给出与缓存响应不同的答案) ,客户端将不会看到更新,直到缓存过期(或缓存被清除)并且响应再次从头开始呈现。

  • 关于RESTful架构的最后一件事就是它们是分层的。实际上,在讨论客户端和服务器之间的交互时,我们已经隐含地讨论了这个要求。基本上,这意味着我们系统中的每个层仅与相邻层交互。因此,在我们的讨论中,客户端层与我们的服务器层交互(反之亦然),但可能有其他服务器层帮助主服务器处理客户端不直接与之通信的请求。相反,服务器会根据需要传递请求。

现在,如果所有这些听起来都很熟悉,那么很棒。通过万维网定义通信协议的超文本传输​​协议(HTTP)是RESTful架构的抽象概念的实现(如果你是像我这样的OOP狂热者,则是REST类的一个实例)。在REST的这个实现中,客户端和服务器通过GET,POST,PUT,DELETE等进行交互,这些是通用语言的一部分,可以使用URL指向资源。

答案 17 :(得分:15)

我认为,在将互联网(协议)用作无状态传输层的同时,将有状态分离为更高层是非常重要的。大多数其他方法混合起来。

它是处理互联网时代编程根本变革的最佳实用方法。关于根本性变化,Erik Meijer在此处进行了讨论:http://www.infoq.com/interviews/erik-meijer-programming-language-design-effects-purity#view_93197。他将其总结为五种效果,并通过将解决方案设计为编程语言来提供解决方案。无论语言如何,解决方案也可以在平台或系统级别实现。宁静可以被视为在当前实践中非常成功的解决方案之一。

通过宁静的风格,您可以在不可靠的互联网上获取和操纵应用程序的状态。如果当前操作未能获得正确的当前状态,则需要零验证主体来帮助应用程序继续。如果它无法操纵状态,它通常会使用多个阶段的确认来保持正确。从这个意义上讲,休息本身并不是一个完整的解决方案,它需要Web应用程序堆栈其他部分的功能来支持其工作。

鉴于这一观点,其余的风格并没有真正与互联网或网络应用程序联系在一起。它是许多编程情况的基本解决方案。它也不简单,它只是使界面非常简单,并且非常好地应对其他技术。

只是我的2c。

编辑:两个更重要的方面:

答案 18 :(得分:14)

这是非常漫长的讨论&#34;但至少可以说是很困惑。

IMO:

1)没有宁静的节目,没有大的联合和大量的啤酒这样的事情:)

2) Representational State Transfer(REST)是the dissertation of Roy Fielding中指定的架构风格。 它有许多限制。如果您的服务/客户尊重这些,那么它就是RESTful。就是这样。

您可以(显着地)将约束汇总到:

  • 无国籍传播
  • 尊重HTTP规范(如果使用HTTP)
  • 清楚地传达了传输的内容格式
  • 使用超媒体作为应用程序状态的引擎

还有另一个very good post可以很好地解释事情。

许多答案复制/粘贴有效信息混合它并添加一些混淆。人们在这里谈论关于RESTFul URI的层次(没有这样的东西!),应用HTTP方法GET,POST,PUT ...... REST不是关于那个或不仅仅是关于那个。

例如链接 - 拥有一个漂亮的API很不错,但最后客户端/服务器并不真正关心你获得/发送它的链接是重要的内容。

最后只要内容格式已知,任何RESTful客户端都应该能够使用任何RESTful服务。

答案 19 :(得分:11)

REST定义了6个构建约束,这些约束构成了任何Web服务 - 真正的RESTful API

  1. 统一界面
  2. 客户端 - 服务器
  3. 无国籍
  4. 可缓存
  5. 分层系统
  6. 按需代码(可选)
  7. https://restfulapi.net/rest-architectural-constraints/

答案 20 :(得分:11)

REST === HTTP类比不正确,直到你不强调它“必须”被HATEOAS驱动的事实。

罗伊自己清除了here

应输入REST API,除了初始URI(书签)和适用于目标受众的标准化媒体类型集之外没有任何先验知识(即,任何可能使用API​​的客户都应该理解)。从那时起,所有应用程序状态转换必须由客户端选择服务器提供的选择来驱动,这些选择存在于接收的表示中或者由用户对这些表示的操纵所暗示。转换可以由客户端对媒体类型和资源通信机制的知识来确定(或限制),这两者都可以在运行中(例如,按需代码)进行改进。

[这里的失败意味着带外信息正在推动互动而不是超文本。]

答案 21 :(得分:11)

  

REST 是一种基于Web标准和HTTP协议(2000年推出)的架构风格。

在基于REST的架构中,一切都是资源(用户,订单,评论)。通过基于HTTP标准方法(GET,PUT,PATCH,DELETE等)的公共接口访问资源。

  

在基于REST的架构中,您有一个提供的REST服务器   访问资源。 REST客户端可以访问和修改REST   资源。

每个资源都应该支持HTTP常用操作。资源由全局ID(通常是URI)标识。

REST允许资源具有不同的表示形式,例如文本,XML,JSON等.REST客户端可以通过HTTP协议(内容协商)请求特定的表示。

HTTP方法:

PUT,GET,POST和DELETE方法通常用于基于REST的体系结构。下表给出了这些操作的解释。

  • GET定义资源的读取访问权限,没有副作用。资源永远不会通过GET请求更改,例如,请求没有副作用(幂等)。
  • PUT创建一个新资源。它也必须是幂等的。
  • DELETE删除资源。这些操作是幂等的。它们可以重复而不会导致不同的结果。
  • POST更新现有资源或创建新资源。

答案 22 :(得分:11)

老问题,新的回答方式。关于这个概念存在很多误解。我总是试着记住:

  1. 结构化URL和Http方法/动词不是定义 宁静的编程。
  2. JSON不是宁静的编程
  3. RESTful编程不适用于API
  4. 我将restful编程定义为

      

    如果应用程序在客户端理解的媒体类型中提供资源(是数据+状态转换控件的组合),那么应用程序就是宁静的

    要成为一个宁静的程序员,你必须尝试构建允许演员做事的应用程序。不只是公开数据库。

    状态转换控制仅在客户端和服务器就资源的媒体类型表示达成一致时才有意义。否则,无法知道什么是控件,什么不是以及如何执行控件。 IE浏览器如果浏览器不知道html中的<form>标签,那么您无需在浏览器中提交过渡状态。

    我不打算自我推销,但我在谈话http://techblog.bodybuilding.com/2016/01/video-what-is-restful-200.html中深入探讨了这些想法。

    我的演讲摘录是关于经常提到的理查森成熟度模型,我不相信等级,你要么是RESTful(3级),要么你不是,但我想说的是这是每个级别在你去RESTful的途中为你做的事情

    annotated richardson maturity model

答案 23 :(得分:10)

说话不仅仅是交换信息。实际上,协议的设计使得不必进行谈话。每一方都知道他们的特定工作是什么,因为它在协议中指定。协议允许纯信息交换,但代价是可能的操作有任何变化。另一方面,谈话允许一方询问可以从另一方采取进一步的行动。他们甚至可以两次提出同样的问题并得到两个不同的答案,因为另一方的国家可能在此期间发生了变化。 说话是RESTful架构。菲尔丁的论文指定了一个人必须遵循的架构,如果一个人想让机器交谈而不是简单地沟通

答案 24 :(得分:10)

本身并没有“RESTful编程”这样的概念。它会更好地称为RESTful范例,甚至更好的RESTful架构。它不是一种编程语言。这是一种范例。

From Wikipedia

  

在计算中,代表性状态转移(REST)是一种   用于Web开发的架构风格。

答案 25 :(得分:10)

REST 代表具有代表性的状态转移

它依赖于无状态,客户端 - 服务器,可缓存的通信协议 - 几乎在所有情况下,都使用HTTP协议。

REST通常用于移动应用程序,社交网站,mashup工具和自动化业务流程。 REST风格强调通过使用有限数量的操作(动词)来增强客户端和服务之间的交互。通过为资源(名词)分配他们自己独特的通用资源指标(URI)来提供灵活性。

Introduction about Rest

答案 26 :(得分:9)

休息之处在于,如果我们同意使用通用语言进行基本操作(http动词),则可以配置基础结构以理解它们并对其进行适当优化,例如,通过使用缓存标头来实现在所有级别缓存。

通过正确实施Restful GET操作,信息来自服务器的数据库,服务器的内存缓存,CDN,代理缓存,浏览器缓存或浏览器的本地存储无关紧要。可以使用禁食,最容易获得的最新来源。

说Rest只是从使用带动作参数的GET请求到使用可用的http动词的语法变化,使它看起来没有任何好处,纯粹是装饰性的。关键是要使用可以被链的每个部分理解和优化的语言。如果您的GET操作有一个带副作用的操作,您必须跳过所有HTTP缓存,否则您最终会得到不一致的结果。

答案 27 :(得分:5)

除了 Richardson的成熟度模型之外,其他人都很少提及,但实际上判断Restful是一个人的API是最好的方法之一。更多关于它的信息:

Richardson's Maturity Model

答案 28 :(得分:5)

什么是API Testing

API测试利用编程将调用发送到API并获得收益。它测试将被测段视为黑盒子。 API测试的目的是确认在协调之前对部件进行正确执行和错误处理。

REST API

REST:具象状态转移。

  • 这是测试人员执行请求和接收响应的功能安排。在REST API中,交互是通过HTTP协议进行的。
  • REST还允许计算机之间通过网络进行通信。
  • 对于发送和接收消息,它涉及使用HTTP方法,与Web服务不同,它不需要严格的消息定义。
  • REST消息通常以XML或JavaScript Object Notation(JSON)的形式接受表单。

4种常用的API方法: -

  1. GET: - 它提供对资源的只读访问权。
  2. POST: - 用于创建或更新新资源。
  3. PUT: - 用于更新或替换现有资源或创建新资源。
  4. DELETE: - 用于删除资源。
  5. 手动测试API的步骤: -

    要手动使用API​​,我们可以使用基于浏览器的REST API插件。

    1. 安装POSTMAN(Chrome)/ REST(Firefox)插件​​
    2. 输入API网址
    3. 选择REST方法
    4. 选择内容标题
    5. 输入申请JSON(POST)
    6. 点击发送
    7. 它将返回输出响应
    8. Steps to Automate REST API

答案 29 :(得分:5)

这个答案是给绝对的初学者的,让我们知道当今最常用的API架构。

了解Restful编程或Restful API。首先,您必须了解什么是API,在一个非常高级的API代表应用程序编程接口上,它基本上是一个软件,可以由另一软件使用,以允许应用程序相互通信。 / p>

全球范围内使用最广泛的API类型是网络API,而每当有请求进入时,该应用就会向客户端发送数据。

enter image description here

实际上,API不仅用于发送数据,并不总是与Web开发或javascript,python或任何编程语言或框架相关。

只要软件的价格相对独立,API中的应用程序实际上可能意味着许多不同的东西。以文件系统或HTTP模块为例,我们可以说它们是很小的软件,我们可以使用它们,也可以使用它们的API与它们交互。例如,当我们将read file函数用于任何编程语言的文件系统模块时,实际上是在使用file_system_reading API。或者,当我们在浏览器中进行DOM操作时,我们并不是真正在使用JavaScript语言本身,而是浏览器向我们公开的DOM API,因此它使我们可以访问它。甚至再举一个例子,假设我们使用Java之类的任何编程语言创建了一个类,然后向其中添加了一些公共方法或属性,这些方法将成为从该类创建的每个对象的API,因为我们要提供其他软件。与我们最初的软件(在这种情况下为对象)进行交互的可能性。 S0,API实际上具有比构建Web API更广泛的含义。

现在让我们看一下构建API的REST体系结构。

代表代表性状态转移的

REST 基本上是一种以逻辑方式构建Web API的方法,使它们易于为我们自己或他人使用。

要遵循REST体系结构构建Restful API,我们只需要遵循一些原则。 1.我们需要将API分为逻辑资源。 2.然后,应使用基于资源的URL公开这些资源。 3.要对数据执行不同的操作,例如读取,创建或删除数据,API应该使用正确的HTTP方法而不是URL。 4.现在,我们实际发送回客户端或从客户端接收的数据通常应使用JSON数据格式,这是一些格式化标准。 5.最后,EST API的另一个重要原则是它们必须是无状态的。

enter image description here

将API分离为逻辑资源:REST中信息的关键抽象是一种资源,因此,我们希望在API中共享的所有数据都应划分为逻辑资源。实际是什么资源?好吧,在REST的上下文中,它是某个对象或某种事物的表示形式,具有与其相关的一些数据。例如,诸如导游之类的应用程序,或用户,地点或回头客等都是逻辑资源的例子。因此,基本上任何可以命名的信息都可以成为资源。只是必须命名,而不是动词。 enter image description here

公开结构:现在,我们需要使用一些结构化URL公开数据,这意味着使数据可用,客户端可以向其发送请求。例如,像这样的整个地址都称为URL。并且这个/ addNewTour被称为API端点。 enter image description here

我们的API就像波纹管一样具有许多不同的端点

https://www.tourguide.com/addNewTour
https://www.tourguide.com/getTour
https://www.tourguide.com/updateTour
https://www.tourguide.com/deleteTour
https://www.tourguide.com/getRoursByUser
https://www.tourguide.com/deleteToursByUser

每个API都会在执行不同操作时将不同的数据发送回客户端。 现在,这些端点存在非常错误的,因为它们确实没有遵循第三条规则,即我们仅应使用HTTP方法来对数据执行操作。因此,终结点应该只包含我们的资源,而不应该包含我们对其执行的操作,因为它们将很快成为维护的噩梦。

我们应该如何在实践中使用这些HTTP方法?好吧,让我们看看这些端点从/ getTour开始的样子。因此,此getTour端点用于获取有关巡回的数据,因此,我们应该简单地将端点命名为/ tours,并在对该端点做出get请求时发送该数据。也就是说,当客户端使用GET HTTP方法访问端点时, enter image description here

(我们在端点或URL中只有资源,没有动词,因为动词现在在HTTP方法中,对吗? 总是使用复数形式的资源名称的常见做法,这就是为什么我写/ tours或/ tour的原因。 习惯上,当调用端点/ tours时,将取回数据库中的所有游览,但是如果我们只想使用一个ID游览,比如说七个,则在另一个斜杠(/ tours / 7)后面加上七个在搜索查询(/ tours?id = 7)中,当然,它也可以是游览名称而不是ID。

HTTP方法:这里真正重要的是端点名称如何与所有人完全相同。

GET: (for requesting data from the server.)

https://www.tourguide.com/tours/7
POST: (for sending data to the server.)
https://www.tourguide.com/tours
PUT/PATCH: (for updating requests for data to the server.) https://www.tourguide.com/tours/7
DELETE: (for deleting request for data to the server.)
https://www.tourguide.com/tours/7

PUT和PATCH之间的区别-> 通过使用PUT,客户端应该发送整个更新的对象,而使用PATCH时,客户端应该仅发送对象已更改的部分。

使用HTTP方法,用户可以执行基本的四个CRUD操作,CRUD代表创建,读取,更新和删除。

现在可能出现类似波纹管的情况:

enter image description here

因此,/ getToursByUser可以简单地转换为/ users / tours,因为3号用户的端点类似于/ users / 3 / tours。

如果我们要删除特定用户的特定游览,则该URL应类似于/ users / 3 / tours / 7,此处用户ID:3,游览ID:7。

因此,这样的资源组合确实存在无数种可能性。

将数据作为JSON发送:现在,关于客户端实际接收或服务器从客户端接收的数据,通常我们使用JSON数据格式。 典型的JSON可能如下所示: enter image description here 在发送JSON数据之前,我们通常会进行一些简单的响应格式设置,为此有一些标准,但是其中一个非常简单的标准称为Jsend。我们只需创建一个新对象,然后向其中添加状态消息,以通知客户端请求是成功,失败还是错误。然后,我们将原始数据放入名为Data的新对象中。

enter image description here

像在此所做的那样,将数据包装到另一个对象中称为“包络”,这是缓解某些安全问题和其他问题的常见做法。

RESTful API应该始终是无状态的:最后,RESTful API应该始终是无状态的,这意味着,在无状态RESTful API中,所有状态都在客户端而不是在服务器上处理。状态只是指应用程序中可能随时间变化的一条数据。例如,某个用户是否已登录或在具有包含多个页面的列表的页面上,当前页面是什么? 现在,应在客户端上处理状态这一事实意味着,每个请求必须包含在服务器上处理某个请求所必需的所有信息。因此,服务器永远不必记住前一个请求即可处理当前请求。

enter image description here

比方说,当前我们位于第5页,并且我们希望前进至第6页。这样,我们可以有一个简单的端点/ tours / nextPage并向服务器提交请求,但是服务器将不得不弄清楚当前页面是什么,然后基于该服务器将下一页发送给客户端。换句话说,服务器将必须记住先前的请求。我们正是要在RESTful API中避免这种情况。

而不是这种情况,我们应该创建一个/ tours / page端点 并在上面粘贴数字六,以请求第六页/ tours / page / 6。因此,服务器不必记住任何内容,它所要做的就是根据我们的请求发送回第6页的数据。

相反的无状态和有状态是计算机科学和一般应用中非常重要的概念

答案 30 :(得分:1)

我想说,理解REST的重要组成部分在于端点或映射,例如/customers/{id}/balance

您可以想象这样的端点是从网站(前端)到数据库/服务器(后端)的连接管道。使用它们,前端可以执行后端操作,这些操作在应用程序中任何REST映射的相应方法中定义。

答案 31 :(得分:0)

这些给出链接资源示例的答案很好,但是只有一半。

因此,想象一下您正在设计一个网站。你写一个故事,

我希望能够通过邮政编码搜索地址,以便选择送货地址

然后,您将构建站点以吸引用户参与该旅程,并尝试在工作流中将页面链接在一起。

一个网站设计会将他们带到地址查找中,然后让他们将地址复制到剪贴板中,然后返回到收货地址表格中。

REST API使用我们在网络上理所当然的模式来进行机器与机器的交互。

不应该搜索邮政编码功能base/addresses/{postcode},并且即使每个地址都链接到完整地址和某些编辑链接,集合也将返回,因为那是死胡同; API使用者将需要猜测如何使用该地址。

该功能的动机应该内置在使用该功能的流程中,以使旅程从起点开始结束:

1 GET /orders/123/shipping

  200 OK { Current shipping details + link to parent + link to address picker }

2  -> GET /orders/123/shipping/addresspicker

      200 OK { Link and form for searching for a postcode }

3   -> GET /orders/123/shipping/addresspicker?postcode=tn11tl

       200 OK { List of addresses each with link to pick it }

4    -> POST /orders/123/shipping/addresspicker?postcode=tn11tl&pickNo=3

        200 OK { Current shipping details + link to parent + link to address picker }

这是一次用户旅程,最后您可以看到流程对订单的影响。

HTTP请求/响应严格不是REST的一部分,但我认为没有人见过非HTTP REST应用程序。

现在这些URL可以是任何字符集,它们只是标识符,我使它们很漂亮是因为它们对人们有意义。机器将使用rel来确定其工作,而不依赖于可读的href

答案 32 :(得分:0)

REST API是遵守REST体系结构约束的API实现。它充当接口。客户端与服务器之间的通信通过HTTP进行。 REST API利用HTTP方法来建立客户端和服务器之间的通信。 REST还使服务器能够缓存响应,从而提高应用程序的性能。 客户端和服务器之间的通信是一个无状态的过程。通过这种方式,我的意思是客户端与服务器之间的每一次通信都像新的一样。

以前的通信没有任何信息或内存。因此,客户端每次与后端交互时,也必须向其发送身份验证信息。这样,后端就可以确定客户端是否有权访问数据。

通过实现REST API,客户端可以获取与之通信的后端端点。这完全将后端和客户端代码分离。

答案 33 :(得分:0)

要在这里做出新的贡献,我想分享我的文章的链接,该链接通过实用和客观的方法将REST概念化。

我将介绍一些主要概念,例如:

  • HATEOAS-超媒体作为应用程序状态的引擎,
  • 资源和表示形式,
  • 寻址能力,
  • REST中的幂等性
  • 理查森的REST成熟度模型。
  • 媒体类型
  • API版本控制

我还创建了一个GitHub项目,您可以在docker上轻松运行该项目,其中涵盖了我在本文中介绍的内容。

https://itnext.io/how-to-build-a-restful-api-a-deep-dive-into-rest-apis-215188f80854

答案 34 :(得分:-2)

REST是一个分布式系统(如WWW)的软件架构风格,你可以想象它是一个设计精良的Web应用程序规则:一组Internet网页(一个虚拟状态机),其中超链接点击链接(状态转换),结果是下一个网页(这意味着应用程序的下一个状态)。

REST描述的网络系统由三部分组成:

  1. 数据元素(资源,资源标识符,表示)
  2. 连接器(客户端,服务器,缓存,解析器,隧道)
  3. 组件(原始服务器,网关,代理,用户代理)
  4. REST严格符合以下条件:

    1. 应用程序功能的状态分为资源
    2. 每个资源用作超链接定位语法(即在WWW URI中)
    3. 所有资源在具有资源转换状态的客户端之间共享一个统一的接口,包括:
      1. 一组有限的明确定义的操作(即在HTTP GET / POST / PUT / DELETE中)
      2. 一组有限的内容格式内容类型,可能包含可执行代码(即在WWW Javascript中)