论坛首页 综合技术论坛

求求你们,千万别再说自己是REST了

浏览 45194 次
该帖已经被评为精华帖
作者 正文
   发表时间:2008-12-18   最后修改:2008-12-21
TheOtherMarcus 写道
“Servers must have the freedom to control their own namespace.”

Why is this important?

Can you give an example of a popular hypertext media type that can identify resources, their type and valid operations on them?

HTML lacks type specifications. I have to GET to find out the type, and in the case of POST, I must do the operation to find out which media type will be returned. POST and GET are also the only HTTP methods HTML supports, as far as I know.

If I decide that POSTing to the URI /item will create one new item, how would this be expressed using a suitable media type?

Fielding 写道
TheOtherMarcus: Because implementations change, but cool URIs don’t.

HTTP operations are generic: they are allowed or not, per resource, but they are always valid. Hypertext doesn’t usually tell you all the operations allowed on any given resource; it tells you which operation to use for each potential transition. The client (user or agent) has to decide what transition to take, not what interface to use.

HTML doesn’t need type specifications. No RESTful architecture needs type specifications. Don’t expect REST to act like some other architectural style. You don’t get to decide what POST means — that is decided by the resource. Its purpose is supposed to be described in the same context in which you found the URI that you are posting to. Presumably, that context (a hypertext representation in some media type understood by your client) tells you or your agent what to expect from the POST using some combination of standard elements/relations and human-readable text. The HTTP response will tell you what happened as a result. In HTTP, a single resource-creating POST action will result in a 201 response with another hypertext representation (telling you what happened and what can be done next) or 204 response with the Location header field indicating the URI of the new resource.

TheOtherMarcus 写道
I will describe my current mental model of REST and ask about the contradictions it still contains.

A client takes the application to the next state by selecting one of the possible actions presented in the hypertext representing the current application state. It can look something like this:

CreateItem POST /random/uri

The client must know what CreateItem means, because this is part of the media type. When posting to /random/uri, a new application state will be returned (201).

CreateItem POST /random/uri
Item GET|PUT|DELETE /item/17

Wouldn’t a 204 response mean that the application has terminated? There are no more state transitions to make? Or can any valid operation on the created resource be expected to initiate a transition to the next application state?

Am I overspecifying by saying that GET, PUT and DELETE are allowed on /item/17? Can this instead be an implicit property of the media type for Item?

I would expect the URI /item/17 to be valid until the item is deleted. How is it otherwise possible to bookmark and go back to interesting resources? But what about URI:s representing application state? Is it up to the server to decide how long they are valid? A simple server implementation may choose to invalidate old application state immediately after transition to a new state, but this would make the back button useless. Advanced server implementations would allow the user to go back to an old state and from there select a different transition, possibly splitting the application in two.

Now I return to the case with the 204 response, assuming the application has not terminated. The resource can be used, for example by putting a new representation of the resource. But now the advanced server becomes nondeterministic, because it can choose to proceed with any of the application states that has existed after the resource was created, not only the last one, as none of the application states are represented in the resource URI. Which of my assumptions is wrong here?
* The application has not terminated.
* The resource URI is constant and not dependent on application state.
* The advanced server should be deterministic.

When the number of state transitions grows, perhaps becomes infinite, the media type used to represent the application state must evolve to be able to present an infinite number of transitions in a finite space. This can be accomplished with URI generation rules. A million items can be hidden behind a query URI.

TheOtherMarcus 写道
After a nights sleep, I think I can answer my own questions.

Local resources are assigned URI:s that are unique to a specific application state. Whenever a transition is made, all local resources must be assigned a new URI. This makes it possible for the server to track the application state.

Global resources, like /item/17, are common to all clients. When they are updated, the local application state must not be affected. The most recent local applications state (or any local application state for that matter) is still valid after the global resource is updated.

The union of local and global resources are the total application state.

I am not yet prepared to completely give up global resources, even though they complicate the application design.

Fielding 写道
Hi TheOtherMarcus,

Don’t confuse application state (the state of the user’s application of computing to a given task) with resource state (the state of the world as exposed by a given service). They are not the same thing.

Aside from that, I don’t think that I can give you further guidance on design within blog commentary. My guess is that you are thinking of OOD or ER modeling and trying to project that onto a resource space, but I really can’t say what would be an appropriate design without extensive knowledge of the application requirements and context.

TheOtherMarcus 写道
I agree that we won’t get any further with this discussion. I just want to know if there are any known media types besides HTML that is suitable for REST interfaces. As I see it, HTML is not ideal for an API intended to be used by a machine. I would have to use an AI if I want it to be able to figure out that a submit button that yesterday was called “Send order” is the same as the button now called “Submit order”. More formalization is needed.

TheOtherMarcus是一位使用C# WebServer的Web开发者,C# WebServer宣称自己支持REST:
http://www.codeplex.com/site/users/view/TheOtherMarcus
http://www.codeplex.com/webserver
0 请登录后投票
   发表时间:2008-12-18   最后修改:2008-12-21
jdubray 写道
Roy:

When you say “Hypertext doesn’t usually tell you all the operations allowed on any given resource; it tells you which operation to use for each potential transition. The client (user or agent) has to decide what transition to take, not what interface to use.”, could you please explain how an agent without prior knowledge of the possible transitions could decide on the fly what to do? Don’t you think that an agent’s implementation (unlike a human) has to have an understanding of the expected transitions as part of a resource lifecycle?

Now assuming the agent has an a priori knowledge of these transitions (semantically or via the definition of what would appear to be a list of actions, i.e. an interface) how could the agent “adapt” on fly to any changes in the possible transitions when the “resource implementation” changes.

If your answer is yes, i.e, there is an a priori knowledge of these transitions, then, what is the point of hypertext in agent-to-agent communication? I can appreciate that it provides a de facto limitation on the possible actions that can be invoked, but it also introduces some constraints when you consider that an agent has to store the hypertext or fetch it just prior to invoking the action (as this hypertext could possibly change between the time the resource representation is received and the time the action is invoked).

In other words I see absolutely no gains when compared to a traditional interface based interaction. Both mechanisms are pretty much equivalent (again, in an agent-to-agent scenario, not human to agent). In both cases you need a priori knowledge of both the actions and the order in which these actions can be invoked (choreography of the interaction).

Ironically, REST exposes transitions but does not make the “states” of the resources explicit. As you get a resource state, you actually have no idea what is the precise lifecyle of this resource. I can easily understand how a human can deal with this situation, but as a developer I can only see how hard it is to write code without a precise knowledge of the interaction, not to mention, how does the code I just wrote survives when the resource lifecycle (states and transitions) changes.

JJ-

Fielding 写道
Hi jdubray,

Of course the client has prior knowledge. Every protocol, every media type definition, every URI scheme, and every link relationship type constitutes prior knowledge that the client must know (or learn) in order to make use of that knowledge. REST doesn’t eliminate the need for a clue. What REST does is concentrate that need for prior knowledge into readily standardizable forms. That is the essential distinction between data-oriented and control-oriented integration.

It has value because it is far easier to standardize representation and relation types than it is to standardize objects and object-specific interfaces. In other words, there are fewer things to learn and they can be recombined in unanticipated ways while remaining understandable to the client.

That doesn’t mean that I think everyone should design their own systems according to the REST architectural style. REST is intended for long-lived network-based applications that span multiple organizations. If you don’t see a need for the constraints, then don’t use them. That’s fine with me as long as you don’t call the result a REST API. I have no problem with systems that are true to their own architectural style.

Jean-Jacques Dubray(jdubray)是资深的SOA专家,Wrox的《Professional ebXML Foundations》的作者之一。他曾经在InfoQ上发表过很多篇文章:
http://www.infoq.com/cn/news/2007/07/saas-iphone
http://www.infoq.com/cn/news/2008/08/is-data-as-a-service-a-bad-idea
http://www.infoq.com/cn/news/2008/10/process-and-agility-zh
http://barelyenough.org/blog/2008/05/resthttp-service-versioning-reponse-to-jean-jacques-dubray/
0 请登录后投票
   发表时间:2008-12-18   最后修改:2008-12-21
tlainhart 写道
Hi Roy -

You say this:

    What needs to be done to make the REST architectural style clear on the notion that hypertext is a constraint?

One negative reaction I’ve come across often with this architectural style is how to implement it efficiently. E.G. often folks will want to implement PROPFIND-y variants to get a bunch of resources in one roundtrip. Is it safe to assume that you might advocate using caching services as one way of efficiently implementing this architectural style?

I’m intuiting that PROPFIND is outside your architectural principles, but I can’t articulate it based on your principles as described here. If true, can you shed light on this?

Something else occurs to me as well - as an architectural style, I wonder if giving examples of systems where the style is not appropriate is a way of raising consciousness.

Fielding 写道
Hi tlainhart,

Caching is important (and desirable), but that isn’t generally the answer to your question about batch operations. People perceive a need for batch operations because they don’t understand the scope of resources.

Resources are not storage items (or, at least, they aren’t always equivalent to some storage item on the back-end). The same resource state can be overlayed by multiple resources, just as an XML document can be represented as a sequence of bytes or a tree of individually addressable nodes. Likewise, a single resource can be the equivalent of a database stored procedure, with the power to abstract state changes over any number of storage items.

If you find yourself in need of a batch operation, then most likely you just haven’t defined enough resources.

Todd Lainhart(tlainhart)是Rational公司的软件工程师:
http://www.linkedin.com/pub/0/12a/aa1
0 请登录后投票
   发表时间:2008-12-18   最后修改:2008-12-18
Robert Cerny 写道
Hi Roy,

I am very thankful that you throw out some more prose, so one can decide whether a given API is RESTful or not. After all i still have a bad feeling of making such a claim myself. You, as a knowledgeable human being, are obviously able to decide on RESTfulness by inspecting an abstract description of the interface. Since i doubt that you are looking into a crystal ball, the following question crosses my mind: Is it possible for a machine to make such a decision? Would it be enough to pass it a sample transcript of a client server dialog? If that does not suffice, which other information would be necessary to decide on RESTfulness? Additionally, to the simple fact, whether or not an API is RESTful based on a sample, this would create the benefit that an API creator could read and understand the program and learn how to create an API that deserves this predicate. After all programmers prefer to read code over prose. If you think it is not possible or very difficult, i would be interested why.

Fielding 写道
Hi Robert,

The short answer: “follow your nose”. That is the phrase we usually use to distinguish the process of following information-provided transitions/semantics versus following a set procedure or interface declaration outside of that flow of information. Basically, how far ahead is the client looking?

The difficulty in providing any trace criterion for REST is that what matters is how the client decides to take transitions. A client that has been pre-programmed to make a sequence of requests (regardless of the response) is going to produce the same network trace as one that examines each response and makes deliberate decisions based on the content.

In terms of testing a specification, the hardest part is identifying when a RESTful protocol is actually dependent on out-of-band information or if the authors are just overspecifying things for the purpose of documentation. What I look for are requirements on processing behavior that are defined outside of the media type specification. One of the easiest ways to see that is when a protocol calls for the use of a generic media type (like application/xml or application/json) and then requires that it be processed in a way that is special to the protocol/API. If they are keying off of something unique within the content (like an XML namespace declaration that extends the semantics of a generic type), then it’s okay. Usually, however, what they do is assume that the response has a specific structure beyond that defined by the media type. When the structure changes, the client will break.

Robert Cerny是一位德国的软件开发者:
http://www.cerny-online.com/resume/en/
0 请登录后投票
   发表时间:2008-12-18   最后修改:2008-12-18
Dima 写道
Roy,

do you think any of the public API’s out there are truly RESTful?

One problem I have is how to do security and keep it pure RESTFul

In order to have secure call I have to do something like:

GET /resource/11231231/token=KJGHY7687JKGH

Unless I do POST - is there a better way you see for this?

Dima.

Fielding 写道
Dima,

I am not sure why you think that having an obscure URI format will somehow give you a secure call (whatever that means). Identifiers are public information.

RESTful systems perform secure operations in the same way as any messaging protocol: either by encapsulating the message stream (SSL, TLS, SSH, IPsec, …) or by encrypting the messages (PGP, S/MIME, etc.). There are numerous examples of that in practice, and more in the future once browsers learn how to implement other authentication mechanisms.

Dima Berastau是Flex开发框架Ruboss的作者:
http://www.iteye.com/news/4369-ruboss-combination-of-flex-and-rails-framework
0 请登录后投票
   发表时间:2008-12-18   最后修改:2008-12-18
billburke 写道
Roy,

What about the usecase of a distributed queue? The queue should not care about the media types it is exchanging between senders and receivers, yet it can quite easily satisfy the addressability, uniform interface, and statelessness constraints of a RESTful architecture. Can’t a service that is media-type agnostic be a RESTful API? Such a service would require assigning semantic meaning to a specific HTTP method and URI pattern and would not receive state transition information from its exchanged media types (as the service doesn’t care or need to know about the media types). I hope I am explaining myself well.

For example:
POST /{queue-name} sends a message to the queue
GET /{queue-name}/top is the current message waiting to be processed. It returns
Location: /messages/111
DELETE /messages/111 tells server you are done processing that message.

There are specific state transitions for the receiver, but why does the media type have to contain information on how to process a received message?

Assigning a little bit of semantics to the URI and HTTP methods adds a lot of simplicity to the overall architecture without requiring an “envelope” format to exchange data. I also think it is far easier to maintain and re-use over the long term.

Fielding 写道
Bill,

A distributed queue is an implementation choice. You can certainly implement some applications by having them interact with a queue-like resource in a RESTful manner. However, if your client relies on the resource being a queue, then it certainly isn’t a RESTful API. Do you see the difference? Encoding knowledge within clients and servers of the other side’s implementation mechanism is what we are trying to avoid.

If a client is receiving instructions on how to interact with a resource just before acting only on those instructions, then the client doesn’t care if the resource is a distributed queue. It simply doesn’t need to know how the resource is implemented. All it needs to know is the meaning of those instructions and some idea of what it wants to do next, whether that purpose be user-driven, configuration-driven, or some sort of AI-driven.

Bill Burke是JBoss公司的首席架构师,他还是REST开发框架RESTEasy的作者。
http://www.oreilly.com.cn/author.php?n=Bill+Burke
http://www.jboss.org/resteasy/
0 请登录后投票
   发表时间:2008-12-18  
snoopdave 写道
I think my poorly written proposal has caused some confusion. I never meant to claim that the OpenSocial or SocialSite RPC APIs were RESTful. There’s more on my blog.

Fielding 写道
The OpenSocial RESTful protocol is not RESTful. It could be made so with some relatively small changes, but right now it is just wrapping RPC results in common Web media types.

A truly RESTful API looks like hypertext. Every addressable unit of information carries an address, either explicitly (e.g., link and id attributes) or implicitly (e.g., derived from the media type definition and representation structure). Query results are represented by a list of links with summary information, not by arrays of object representations (query is not a substitute for identification of resources). Resource representations are self-descriptive: the client does not need to know if a resource is OpenSocialist because it is just acting on the representations received.

Think of it in terms of the Web. How many Web browsers are aware of the distinction between an online-banking resource and a Wiki resource? None of them. They don’t need to be aware of the resource types. What they need to be aware of is the potential state transitions — the links and forms — and what semantics/actions are implied by traversing those links. A browser represents them as distinct UI controls so that a user can see potential transitions and anticipate the effect of chosen actions. A spider can follow them to the extent that the relationships are known to be safe. Typed relations, specific media types, and action-specific elements provide the guidance needed for automated agents.

Dave Johnson(snoopdave)是《RSS and Atom in Action》的作者,Sun的SocialSite项目的作者:
http://rollerweblogger.org/roller/page/about
http://www.china-pub.com/37505
0 请登录后投票
   发表时间:2008-12-18  
REST已经过去了,现在流行滴是:社会化

俺们做滴是社会化滴XXX网站……
2 请登录后投票
   发表时间:2008-12-18  
感觉最精华的就是这个:
引用

Query results are represented by a list of links with summary information, not by arrays of object representations (query is not a substitute for identification of resources). Resource representations are self-descriptive: the client does not need to know if a resource is OpenSocialist because it is just acting on the representations received.


个人理解 REST 应该是 hypertext 告诉客户端应该做什么。
(hypertext  的定义 Roy 有自己的解释)
例如  /people/1  那么客户端能做的事情就是查询 id=1 的人。
0 请登录后投票
   发表时间:2008-12-18   最后修改:2008-12-18
很多年以来,Web基础架构(URI、HTTP、HTML等等)的设计者(Tim Berners-Lee、Roy T. Fielding等等)对于Web架构的理解和Web架构的使用者(普通的Web应用开发者)对于Web架构的理解之间存在着非常大的断层,希望这些深入的讨论有助于弥补这个断层。
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics