RESTful服务最佳实践——(二)

来源:互联网 发布:java小项目源代码 编辑:程序博客网 时间:2024/05/22 15:06

REST是什么?

REST架构方式描述了六种设计准则。这些用于架构的设计准则,最早是由Roy Fielding在他的博士论文中提出并定义了RESTful风格。(详见http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm)

六个设计准则分别是:
- 统一接口
- 无状态
- 可缓冲
- C-S架构
- 分层系统
- 按需编码

以下是这些设计准则的详细讨论:

统一接口

统一接口准则定义了客户端和服务端之间的接口,简化和分离了框架结构,这样一来每个部分都可独立演化。以下是接口统一的四个原则:

基于资源

不同资源需要用URI来唯一标识。返回给客户端的表征和资源本身在概念上有所不同,例如服务端不会直接传送一个数据库资源,然而,一些HTML、XML或JSON数据能够展示部分数据库记录,如用芬兰语来表述还是用UTF-8编码则要根据请求和服务器实现的细节来决定。

通过表征来操作资源

当客户端收到包含元数据的资源的表征时,在有权限的情况下,客户端已掌握的足够的信息,可以对服务端的资源进行删改。

自描述的信息

每条信息都包含足够的数据用以确认信息该如何处理。例如要由网络媒体类型(已知的如MIME类型①)来确认需调用哪个解析器。响应同样也表明了它们的缓存能力。

超媒体即应用状态引擎(HATEOAS)

客户端通过body内容、查询串参数、请求头和URI(资源名称)来传送状态。服务端通过body内容,响应码和响应头传送状态给客户端。这项技术被称为超媒体(或超文本链接)。

除了上述内容外,HATEOS也意味着,必要的时候链接也可被包含在返回的body(或头部)中,以提供URI来检索对象本身或关联对象。下文将对此进行更详细的阐述。

统一接口是每个REST服务设计时的必要准则。

无状态

正如REST是REpresentational State Transfer的缩写,无状态很关键。本质上,这表明了处理请求所需的状态已经包含在请求本身里,也有可能是URI的一部分、查询串参数、body或头部。URI能够唯一标识每个资源,body中也包含了资源的转态(或转态变更情况)。之后,服务器将进行处理,将相关的状态或资源通过头部、状态和响应body传递给客户端。

从事我们这一行业的大多数人都习惯使用容器来编程,容器中有一个“会话”的概念,用于在多个HTTP请求下保持状态。在REST中,如果要在多个请求下保持用户状态,客户端必须囊括客户端的所有信息来完成请求,必要时重新发送请求。自从服务端不需要维持、更新或传递会话状态后,无状态性得到了更大的延展。此外,负载均衡器无需担心和无状态系统之间的会话。

所以状态和资源间有什么差别?服务器对于状态,或者说是应用状态,所关注的点是在当前会话或请求中要完成请求所需的数据。而资源,或者说是资源状态,则是定义了资源表征的数据,例如存储在数据库中的数据。由此可见,应用状态是是随着客户端和请求的改变而改变的数据。相反,资源状态对于发出请求的客户端来说是不变的。

在网络应用的某一特定位置上摆放一个返回按钮,是因为它希望你能按一定的顺序来操作吗?其实是因为它违反了无状态的原则。有许多不遵守无状态原则的案例,例如三条腿的OAuth②,API调用速度限制等。但还是要尽量确保服务器中不需要在多个请求下保持应用状态。

可缓存

在万维网上,客户端可以缓存页面的响应内容。因此响应都应隐式或显式的定义为可缓存的,若不可缓存则要避免客户端在多次请求后用旧数据或脏数据来响应。管理得当的缓存会部分地或完全地除去客户端和服务端之间的交互,进一步改善性能和延展性。

C-S架构

统一接口使得客户端和服务端相互分离。关注分离意味什么?打个比方,客户端不需要存储数据,数据都留在服务端内部,这样使得客户端代码的可移植性得到了提升;而服务端不需要考虑用户接口和用户状态,这样一来服务端将更加简单易拓展。只要接口不改变,服务端和客户端可以单独地进行研发和替换。

分层系统

客户端通常无法表明自己是直接还是间接与端服务器进行连接。中介服务器可以通过启用负载均衡或提供共享缓存来提升系统的延展性。分层时同样要考虑安全策略。

按需编码(可选)

服务端通过传输可执行逻辑给客户端,从而为其临时拓展和定制功能。相关的例子有编译组件Java applets和客户端脚本JavaScript。

遵从上述原则,与REST架构风格保持一致,能让各种分布式超媒体系统拥有期望的自然属性,比如高性能,延展性,简洁,可变性,可视化,可移植性和可靠性。

提示:REST架构中的设计准则中,只有按需编码为可选项。如果某个服务违反了其他任意一项准则,严格意思上不能称之为RESTful风格。


原文如下


What is REST?
The REST architectural style describes six constraints. These constraints, applied to the architecture, were originally communicated by Roy Fielding in his doctoral dissertation (see http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) and defines the basis of RESTful-style.

The six constraints are:

  • Uniform Interface
  • Stateless
  • Cacheable
  • Client-Server
  • Layered System
  • Code on Demand

A more detailed discussion of the constraints follows:

Uniform Interface

The uniform interface constraint defines the interface between clients and servers. It simplifies and decouples the architecture, which enables each part to evolve independently. The four guiding principles of the uniform interface are:

Resource-Based

Individual resources are identified in requests using URIs as resource identifiers. The resources themselves are conceptually separate from the representations that are returned to the client. For example, the server does not send its database, but rather, some HTML, XML or JSON that represents some database records expressed, for instance, in Finnish and encoded in UTF-8, depending on the details of the request and the server implementation.

Manipulation of Resources Through Representations

When a client holds a representation of a resource, including any metadata attached, it has enough information to modify or delete the resource on the server, provided it has permission to do so.

Self-descriptive Messages

Each message includes enough information to describe how to process the message. For example, which parser to invoke may be specified by an Internet media type (previously known as a MIME type). Responses also explicitly indicate their cache-ability.

Hypermedia as the Engine of Application State (HATEOAS)

Clients deliver state via body contents, query-string parameters, request headers and the requested URI (the resource name). Services deliver state to clients via body content, response codes, and response headers. This is technically referred-to as hypermedia (or hyperlinks within hypertext).

Aside from the description above, HATEOS also means that, where necessary, links are contained in the returned body (or headers) to supply the URI for retrieval of the object itself or related objects. We’ll talk about this in more detail later.

The uniform interface that any REST services must provide is fundamental to its design.

Stateless

As REST is an acronym for REpresentational State Transfer, statelessness is key. Essentially, what this means is that the necessary state to handle the request is contained within the request itself, whether as part of the URI, query-string parameters, body, or headers. The URI uniquely identifies the resource and the body contains the state (or state change) of that resource. Then after the server does it’s processing, the appropriate state, or the piece(s) of state that matter, are communicated back to the client via headers, status and response body.

Most of us who have been in the industry for a while are accustomed to programming within a container which provides us with the concept of “session” which maintains state across multiple HTTP requests. In REST, the client must include all information for the server to fulfill the request, resending state as necessary if that state must span multiple requests. Statelessness enables greater scalability since the server does not have to maintain, update or communicate that session state. Additionally, load balancers don’t have to worry about session affinity for stateless systems.

So what’s the difference between state and a resource? State, or application state, is that which the server cares about to fulfill a request—data necessary for the current session or request. A resource, or resource state, is the data that defines the resource representation—the data stored in the database, for instance. Consider application state to be data that could vary by client, and per request. Resource state, on the other hand, is constant across every client who requests it.

Ever had back-button issues with a web application where it went AWOL at a certain point because it expected you to do things in a certain order? That’s because it violated the statelessness principle. There are cases that don’t honor the statelessness principle, such as three-legged OAuth, API call rate limiting, etc. However, make every effort to ensure that application state doesn’t span multiple requests of your service(s).

Cacheable

As on the World Wide Web, clients can cache responses. Responses must therefore, implicitly or explicitly, define themselves as cacheable, or not, to prevent clients reusing stale or inappropriate data in response to further requests. Well-managed caching partially or completely eliminates some client–server interactions, further improving scalability and performance.

Client–server

The uniform interface separates clients from servers. This separation of concerns means that, for example, clients are not concerned with data storage, which remains internal to each server, so that the portability of client code is improved. Servers are not concerned with the user interface or user state, so that servers can be simpler and more scalable. Servers and clients may also be replaced and developed independently, as long as the interface is not altered.

Layered system

A client cannot ordinarily tell whether it is connected directly to the end server, or to an intermediary along the way. Intermediary servers may improve system scalability by enabling load-balancing and by providing shared caches. Layers may also enforce security policies.

Code on demand (optional)

Servers are able to temporarily extend or customize the functionality of a client by transferring logic to it that it can execute. Examples of this may include compiled components such as Java applets and client-side scripts such as JavaScript.

Complying with these constraints, and thus conforming to the REST architectural style, will enable any kind of distributed hypermedia system to have desirable emergent properties, such as performance, scalability, simplicity, modifiability, visibility, portability and reliability.

NOTE: The only optional constraint of REST architecture is code on demand. If a service violates any other constraint, it cannot strictly be referred to as RESTful.

0 0
原创粉丝点击