构造基于REST方式的网络服务

    技术2022-05-11  60

    Building Web Services the REST Way

      Roger L. Costello

    I will first provide a brief introduction to REST and then describe how to build Web services in the REST style. 

    首先,对Rest进行一个简单的饿介绍,然后,描叙怎么来构造一个REST风格的网络服务。

    What is REST?

    什么是REST?

    REST是由 Roy Fielding博士在他的博士论文中用来描叙网络系统框架风格时提出的一个术语。REST是下面三个单词的缩写:Representational State Transfer(表述性状态转移)。

     REST is a term coined by Roy Fielding in his Ph.D. dissertation [1] to describe an architecture style of networked systems. REST is an acronym standing for Representational State Transfer.  

    Why is it called Representational State Transfer?

    为什么取名叫表述性状态转移?

    网络是由资源组成。这些资源是任何感兴趣的条目。比如: the Boeing Aircraft Corp可能定义一个747资源。客户可能使用如下URL访问这个资源:

    http://www.boeing.com/aircraft/747 

     The Web is comprised of resources. A resource is any item of interest. For example, the Boeing Aircraft Corp may define a 747 resource. Clients may access that resource with this URL:

    http://www.boeing.com/aircraft/747 

    用返回值作为一种资源的表述法(如Boeing747.html),是表述性的起名的原因。而表述性意味着客户端应用程序处于某种状态。当客户端由Boeing747.html转变到其他链接时,由于会访问到其他的资源,从而引起表述的结果也发生转变。客户的状态也就改变了。如此:客户端应用程序随着资源表述的不同而转变到不同的状态。

    representation of the resource is returned (e.g., Boeing747.html). The representation places the client application in a state. The result of the client traversing a hyperlink in Boeing747.html is another resource is accessed. The new representation places the client application into yet another state. Thus, the client application changes (transfers) state with each resource representation --> Representational State Transfer!

    Here is Roy Fielding's explanation of the meaning of Representational State Transfer:

    下面是 Roy Fielding博士对表述性状态转移的解释:

    表述性状态转移被设计来触发一个返回结果这个结果是针对每一个客户行为设计的。如:一个网状的网络页面(一个虚拟状态机),当用户通过点击链接来改变状态(状态改变)时,下一个页面将出现在我们面前(呈现下一个状态)。

    "Representational State Transfer is intended to evoke an image of how a well-designed Web application behaves: a network of web pages (a virtual state-machine), where the user progresses through an application by selecting links (state transitions), resulting in the next page (representing the next state of the application) being transferred to the user and rendered for their use."  

    Motivation for REST

    REST的动机是捕捉使网络成功原因的特征,一系列这些特征正在被用来引导网络的发展。

     The motivation for REST was to capture the characteristics of the Web which made the Web successful. Subsequently these characteristics are being used to guide the evolution of the Web.  

    REST - An Architectural Style, Not a Standard

    REST是一个框架不是一个标准

    Rest不是一个标准。你不将看到W3C推出一个REST规范。你也不将看到IBM或者Mircosoft 或者SUN出售Rest发展工具。为什么?因为REST仅仅是一个框架样式。我们不能封装这个样式。你只可以理解它,用它来设计你的网络服务。(类似于C/S框架样式,没有C/S标准吧?)

     REST is not a standard. You will not see the W3C putting out a REST specification. You will not see IBM or Microsoft or Sun selling a REST developer's toolkit. Why? Because REST is just an architectural style. You can't bottle up that style. You can only understand it, and design your Web services in that style. (Analogous to the client-server architectural style. There is no client-server standard.)

    虽然,REST不是一个标准,但是它确实使用了如下标准:

    HTTP

    URL

      XML/HTML/GIF/JPEG/etc (Resource Representations) 

    text/xml, text/html, image/gif, image/jpeg, etc (MIME Types) 

    四块标准

    While REST is not a standard, it does use standards:  

    HTTP 

    URL 

    XML/HTML/GIF/JPEG/etc (Resource Representations) 

    text/xml, text/html, image/gif, image/jpeg, etc (MIME Types) 

    The Classic REST System

    典型的REST系统

    网络是一个REST 系统,许多你以前使用的网络服务都使用了REST 。如书刊订阅服务,查询服务,网络字典服务等等,都是基于REST 的网络服务。你已经使用REST 建造REST 服务只是你不知道它吧了!

     The Web is a REST system! Many of those Web services that you have been using these many years - book-ordering services, search services, online dictionary services, etc - are REST-based Web services. Alas, you have been using REST, building REST services and you didn't even know it.

    REST 与网络的大颗粒场景有关,其不处理具体的细节。(不管这个网络服务是基于java servlets还是CGI)所以,我们来看看一个基于REST 的大颗粒观点的例子。

    REST is concerned with the "big picture" of the Web. It does not deal with implementation details (e.g., using Java servlets or CGI to implement a Web service). So let's look at an example of creating a Web service from the REST "big picture" perspective.  

    Parts Depot Web Services

    备件仓库网络服务例子

    Parts Depot 公司(一个假想公司)已经部署了很多网络服务来使其客户获取备件清单,获取具体配件的详细信息,然后提交订购单。

    让我们来考虑一下每一个这种服务是怎么在restful框架下实现的。

     Parts Depot, Inc (fictitious company) has deployed some web services to enable its customers to:  

    get a list of parts 

    get detailed information about a particular part 

    submit a Purchase Order (PO) 

    Let's consider how each of these services are implemented in a RESTful fashion.  

    Get Parts List

     获取备件清单

    这个网络服务通过一个有用的统一资源定位来访问备件清单资源.比如:客户使用如下URL获取备件清单。

    http://www.parts-depot.com/parts 

    The web service makes available a URL to a parts list resource. For example, a client would use this URL to get the parts list:

    http://www.parts-depot.com/parts 

    注意:网络服务怎么来产生备件清单这件事情对客户来说完全是透明的。(所谓透明的就是不要管他怎么来的,只要这么一句话就ok了,SG方式。)所以的客户知道,如果他提交了这个地址那么一个文件(包含备件清单)将会返回。既然对客户来说执行是透明的,那么

    备件仓库将自由的修改其后续执行的这个资源而不影响其他的客户。这就是所谓的松耦合。

    如下是客户从网络服务上返回的结果文档:

    <?xml version="1.0"?> 

    <p:Parts xmlns:p="http://www.parts-depot.com"  

             xmlns:xlink="http://www.w3.org/1999/xlink"> 

          <Part id="00345" xlink:href="http://www.parts-depot.com/parts/00345"/> 

          <Part id="00346" xlink:href="http://www.parts-depot.com/parts/00346"/> 

          <Part id="00347" xlink:href="http://www.parts-depot.com/parts/00347"/> 

          <Part id="00348" xlink:href="http://www.parts-depot.com/parts/00348"/> 

    </p:Parts> 

    Note that "how" the web service generates the parts list is completely transparent to the client. All the client knows is that if he/she submits the above URL then a document containing the list of parts is returned. Since the implementation is transparent to clients, Parts Depot is free to modify the underlying implementation of this resource without impacting clients. This is loose coupling.

    Here's the document that the client receives:

    <?xml version="1.0"?> 

    <p:Parts xmlns:p="http://www.parts-depot.com"  

             xmlns:xlink="http://www.w3.org/1999/xlink"> 

          <Part id="00345" xlink:href="http://www.parts-depot.com/parts/00345"/> 

          <Part id="00346" xlink:href="http://www.parts-depot.com/parts/00346"/> 

          <Part id="00347" xlink:href="http://www.parts-depot.com/parts/00347"/> 

          <Part id="00348" xlink:href="http://www.parts-depot.com/parts/00348"/> 

    </p:Parts> 

    (假设:通过内容协议,客服端需要的服务是通过xml来表现的(这是一个机器之间的传递过程)。

    注意:部件清单已经有联系方式来获取每一个部件的细节信息,对REST来说,这是一个关键要素,客户端转变状态到其它都是通过选择这些URL联系方式。

    [Assume that through content negotiation the service determined that the client wants the representation as XML (for machine-to-machine processing).] Note that the parts list has links to get detailed info about each part. This is a key feature of REST. The client transfers from one state to the next by examining and choosing from among the alternative URLs in the response document.  

    Get Detailed Part Data

    获取细节备件数据

    这些网络服务利用URL来获取每一个部件元数据,比如:

    这里是客户需要获取编号为的00345部件。

    http://www.parts-depot.com/parts/00345 

    下面是客户收到的文件:

    <?xml version="1.0"?> 

    <p:Part xmlns:p="http://www.parts-depot.com"    

            xmlns:xlink="http://www.w3.org/1999/xlink"> 

          <Part-ID>00345</Part-ID> 

          <Name>Widget-A</Name> 

          <Description>This part is used within the frap assembly</Description> 

          <Specification xlink:href="http://www.parts-depot.com/parts/00345/specification"/> 

          <UnitCost currency="USD">0.10</UnitCost> 

          <Quantity>10</Quantity> 

    </p:Part> 

    收到结束。

     The web service makes available a URL to each part resource. Example, here's how a client requests part 00345:

    http://www.parts-depot.com/parts/00345 

    Here's the document that the client receives:

    <?xml version="1.0"?> 

    <p:Part xmlns:p="http://www.parts-depot.com"    

            xmlns:xlink="http://www.w3.org/1999/xlink"> 

          <Part-ID>00345</Part-ID> 

          <Name>Widget-A</Name> 

          <Description>This part is used within the frap assembly</Description> 

          <Specification xlink:href="http://www.parts-depot.com/parts/00345/specification"/> 

          <UnitCost currency="USD">0.10</UnitCost> 

          <Quantity>10</Quantity> 

    </p:Part> 

    再次观察这些数据是怎么被链接到更多的数据:这个部件的详述可以通过其他的超链接来找到。每一个返回的文件都容许客户往下去获得等多的细节信息。

    Again observe how this data is linked to still more data - the specification for this part may be found by traversing the hyperlink. Each response document allows the client to drill down to get more detailed information.  

    Submit PO

     提交订单

    网络服务利用URL来提交订单,客户产生订单通过填写订单表格,这些在备件仓库中已经被设计好了同时被在网络服务描述语言中被公开了,客户可以把订单xml文件以HTTP POST的方式提交。

    The web service makes available a URL to submit a PO. The client creates a PO instance document which conforms to the PO schema that Parts Depot has designed (and publicized in a WSDL document). The client submits PO.xml as the payload of an HTTP POST.

    订单服务通过URL的HTTP POST的方式对提交订单的事件进行响应,然后,客户能够在任何时候重新得到订单,然后去更新和修改它。这个订单已经变为一个在客户和服务者之间分享的信息。这个分享的信息被服务者赋予一个URL地址,以网络服务的形式公开。

    The PO service responds to the HTTP POST with a URL to the submitted PO. Thus, the client can retrieve the PO any time thereafter (to update/edit it). The PO has become a piece of information which is shared between the client and the server. The shared information (PO) is given an address (URL) by the server and is exposed as a Web service.  

    Logical URLs versus Physical URLs

     逻辑地址与物理地址比较

    一个资源是一个概念上的实体,其中一种具体的资源表述性方法是URL:如:

    http://www.parts-depot.com/parts/00345 

    是一个逻辑URL,不是一个物理URL。然而,最好不要是一个静态的网页来针对每一个部件。事实上,如果有成千上万的部件都是通过静态的HTML的话,这将不是一个好的设计。

    A resource is a conceptual entity. A representation is a concrete manifestation of the resource. This URL:  

    http://www.parts-depot.com/parts/00345 

    is a logical URL, not a physical URL. Thus, there doesn't need to be, for example, a static HTML page for each part. In fact, if there were a million parts then a million static HTML pages would not be a very attractive design.

    执行细节:备件仓库将执行服务来获得逐条的细节数据通过开发一个java servlet ,通过其解析主机名后的字符,然后使用部件号码来查询部件数据库,形成xml格式的查询结果。

    最好,返回xml结果作为http 回应的有效负载。

    [Implementation detail: Parts Depot could implement the service that gets detailed data about a particular part by employing a Java Servlet which parses the string after the host name, uses the part number to query the parts database, formulate the query results as XML, and then return the XML as the payload of the HTTP response.]

    作为一个URL风格的样式 ,我们不应该暴露技术细节,我们可以自由的改变执行而不影响客户或者误导的URL。

    As a matter of style URLs should not reveal the implementation technique used. You need to be free to change your implementation without impacting clients or having misleading URLs.  

    REST Web Services Characteristics

    基于REST的网络服务特征

    1、客户—服务器:基于pull的交互方式;强类型的pull组件表述法。

    2、无状态性:每一次请求从客户端到服务器端都必须包含所以的必须信息来理解请求,不能利用任何在服务器上的内容。

    3、缓存:为了改进网络响应效率,应该可以自己标注是否可以缓存。

    4、统一的接口:所以资源是通过统一的接口访问如:HTTP GET POST,PUT.DELETE

    5、命名资源:组成系统的资源是使用URL来命名。

    6、相互链接的资源表述:资源表述是通过URL来链接的,所以,客户可以从一个状态转到另外一个状态。

    7、图层系统:中间层如代理服务器,缓存服务器,网关等能被嵌入到客户端和资源中来提高性能和安全性等。

     Here are the characteristics of REST:  

    Client-Server: a pull-based interaction style: consuming components pull representations. 

    Stateless: each request from client to server must contain all the information necessary to understand the request, and cannot take advantage of any stored context on the server. 

    Cache: to improve network efficiency responses must be capable of being labeled as cacheable or non-cacheable. 

    Uniform interface: all resources are accessed with a generic interface (e.g., HTTP GET, POST, PUT, DELETE). 

    Named resources - the system is comprised of resources which are named using a URL. 

    Interconnected resource representations - the representations of the resources are interconnected using URLs, thereby enabling a client to progress from one state to another. 

    Layered components - intermediaries, such as proxy servers, cache servers, gateways, etc, can be inserted between clients and resources to support performance, security, etc. 

    Principles of REST Web Service Design

    REST 网络服务设计的基本原理

    1、在网络中创建基于网络服务的REST框架的关键是定义所有的概念实体,(即你希望作为服务暴露的内容如上面资源例子中的,备件清单,备件细节信息数据,购物单等)

    2、给每一个资源创建一个URL,这个资源应该是名称,而不是动词。比如

    不要:

       http://www.parts-depot.com/parts/getPart?id=00345 

         因为使用了动词getPart,而正确的是使用名词。

          http://www.parts-depot.com/parts/00345 

         恩典

     1. The key to creating Web Services in a REST network (i.e., the Web) is to identify all of the conceptual entities that you wish to expose as services. Above we saw some examples of resources: parts list, detailed part data, purchase order.

    2. Create a URL to each resource. The resources should be nouns, not verbs. For example, do not use this:

    http://www.parts-depot.com/parts/getPart?id=00345 

    Note the verb, getPart. Instead, use a noun:

    http://www.parts-depot.com/parts/00345 

    3. Categorize your resources according to whether clients can just receive a representation of the resource, or whether clients can modify (add to) the resource. For the former, make those resources accessible using an HTTP GET. For the later, make those resources accessible using HTTP POST, PUT, and/or DELETE.

    3、订单对你的资源进行分类,以是否可以增加,修改,删除和是否主要表述分为2类,第一类情况我们通过HTTP POST, PUT, and/or DELETE.访问。第二中情况我们通过Http PUT访问。

    4、通过http GET访问的资源应该是单向自由访问的。也就是说:资源器仅仅返回资源的表述,访问资源不会导致资源的修改。

    5、没有人是封闭的,所以也没有表述应该封闭,也就是说,利用超链接来该客户表现资源,这样其可以获取下一步的信息或者获取相关的信息。

    6、一步一步的获取信息,不要把所有的信息都放在一个单独的文件中,要提供超链接来获取更多的信息。

    7、使用schema (DTD, W3C Schema, RelaxNG, or Schematron)来表达数据,然后利用其指定返回的格式。

    8、使用wsdl或者简单的http文档来描述你的服务怎么才能被引发。

    4. All resources accessible via HTTP GET should be side-effect free. That is, the resource should just return a representation of the resource. Invoking the resource should not result in modifying the resource.

    5. No man/woman is an island. Likewise, no representation should be an island. In other words, put hyperlinks within resource representations to enable clients to drill down for more information, and/or to obtain related information.

    6. Design to reveal data gradually. Don't reveal everything in a single response document. Provide hyperlinks to obtain more details.

    7. Specify the format of response data using a schema (DTD, W3C Schema, RelaxNG, or Schematron). For those services that require a POST or PUT to it, also provide a schema to specify the format of the response.

    8. Describe how your services are to be invoked using either a WSDL document, or simply an HTML document.  

    Summary

    总结:

    本文把REST描述为框架样式,事实上,它是一个网络框架样式。REST描叙了网络是怎么很好运行的。同时描述的REST的原理将使你的网络服务工作的更好。

     This article described REST as an architectural style. In fact, it's the architectural style of the Web. REST describes what makes the Web work well. Adhering to the REST principles will make your services work well in the context of the Web.

    在以后的文章中,我将继续写关于在网络改革中使用REST原理,敬请关注!

    In a future article I will write about the evolution of the Web using the REST principles.  

    谢明:

    感谢Robert Leftwich and Philip Eskelin在写这篇文章过程中给于的大力帮助!

    Acknowledgement

     Thanks to Robert Leftwich and Philip Eskelin for their very helpful comments in creating this document.

     

    最新回复(0)