开发者

Does the REST architectural style require physically separate clients and servers?

开发者 https://www.devze.com 2023-01-07 15:34 出处:网络
Is it a requirement that RESTful interactions occur between physically separate clients and servers?i.e. does the interaction need to involve the network stack in some way?Is there any benefit to empl

Is it a requirement that RESTful interactions occur between physically separate clients and servers? i.e. does the interaction need to involve the network stack in some way? Is there any benefit to employing an HTTP-like "calling convention" between the various components of an application?

It seems to me that the benefits of REST, such as they are, are almost as applicable to communication between components of the same application as to communication between physically separate clients and servers, and that REST's constraints and guiding principles can be satisfied without the network stack being involved. (I'm not suggesting that it's a good idea for every function call to "look like HTTP", but for certain function calls or interactions, it might make sense for the interaction to be HTTP-like.)

For example, in a web application it m开发者_运维知识库ight be useful to access ("internal") user information via URLs like http://api.local/user/34 and an "HTTP client" that routes and dispatches requests internally, rather than going through a standard HTTP routing and dispatch process. Instead of providing a conventional library and associated documentation, the developer of the user component would provide URL endpoints (resources), which could be manipulated with the standard HTTP verbs. Since developers are already familiar with HTTP, less documentation would be required, and there would be more consistency and uniformity across components.

(I think that thinking about REST in this way also helps clarify the difference between REST and RPC mechanisms like SOAP--there's no reason to ever use SOAP for "internal" calls, but the understood behaviour and semantics of REST may make it useful for "internal" calls in some situations. And of course if you're using REST for internal calls (REST Level 0?), it's trivial to convert such interactions into external calls if the need arises.)


Using REST principles and HTTP semantics in-process definitely does make sense, but probably only if your application also eventually is a client or server communicating with HTTP.

The hard part is honoring the layered constraint of HTTP since it's so easy to call that singleton on the other sie of the layer, since it's just a function call away.

One benefit, however is that you can in fact move a layer from one place to another. It's probably hard to achieve this fully, but I think it's doable, although I'll hazard a guess that it's never been done.

In my own thought experiments for this all of the benefits of HTTP come into play, in ways that mere memcached or in-process caches can't handle it. Take, for example cache validation, or conditional puts. Imagine being able to make a function call with the expressiveness of a HTTP request:

retrieve this thing from this service, but only if its ETag isn't "A" or "B" or W/"C", since those are the ones I have at the moment

Or

store this over here, but only if the ETag W/"DEF" is still valid, since that's the tag I used when I did my GET just now.

and

I'd like to search for widgets like this, and have the result preferably as an IAtomCollection, but i'll take a List instead (Accept). The last time I asked this question I got an ETag of "foo" (If-None-Match), so I don't need it if it didn't change, but if you don't mind, I'd like to verify the validity of my cache with the origin server (Cache-Control: must-revalidate). Oh and by the way here are my credentials (Authorization).

Questions like these are so easy to do in HTTP, and we all know how to forge such complicated queries.

The same goes for HTTP responses:

Hi, I found your IAtomCollection, and I did actually verify it with the origin server. The thing you have isn't valid any more, so here's a new one for you. It has the ETag of "bar", and you're allowed to consider it fresh for two minutes without revalidating with me, but if I'm gone the next time you ask, you can extend the freshness period for another minute. And of course the response varies based on your credentials (goes without saying, right?) and your preferences.

Again, plain old HTTP. Imagine being able to make method calls that are that smart!

As for HATEOAS, putting some thought into encapsulating identifiers would make it possible to honor that constraint too. But my thought experiments haven't gone very far in this direction...


The ideas behind REST are largely driven by the economics of data transfer, remoteness and architecture neutrality. It is expensive to access a remote resource; you want an architecture that encourages cacheability, addressability and minimalistic semantics. However, for in-process communications, sending data between subsystems within is extremely cheap, and usually amounts to passing a pointer, which satisfies or obviates all three goals.

I admit I haven't thought deeply about this, so a return question might be in order: how would in-process HTTP make my life easier?


In a RESTful system that emphasizes the resource, rather than the function behind it, the resource's URI is often the most natural way to address the resource. That's what the resource is known by, so why not use it?

In some systems, it is not always clear which function calls are to be executed in order to get the data that is provided by a resource. Again, simply addressing the resource through its URI (even from within your code) might be most convenient.

In RESTx, we catered for that by giving you as the component author a very simple means to access the data of a resource that's hosted on this server. At the same time, this abstraction makes it also possible to refer to data that's hosted on other servers using the exact same syntax. But instead of doing a manual HTTP request, you call the accessCode(<uri>) method. Of course, if the uri refers to a local resource then there won't be an actual HTTP request, but that's something you don't have to worry about. Here is an example of what that looks like.

Naturally, you don't have to use hard-wired URIs in your code. RESTx is about reusable code, which is configured as needed in order to create a new RESTful resource. So, oftentimes the URIs you are referring to are part of the component's configuration.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号