Law of Demeter vs. REST - rest

The Law of Demeter (really should be the suggestion of Demeter) says that you shouldn't "reach through" an object to get at their child objects. If you, as a client, need to perform some non-trivial operation, most of the time the domain model you're working with should support that operation.
REST is in principle a dumb hierarchy of objects. It is like a filesystem of resources/objects, where each object could have child objects. You almost always reach through with REST. You can optionally build up by-convention composite object types using REST techniques, and as long as the provider and the client agree on higher-level operations, you can avoid the reach-through.
So, how do you balance REST and Demeter? It seems to me that they are not in conflict, because REST is all about super-loose coupling to the point where it is pointless for the provider to try to anticipate all the needs of the clients, whereas Demeter assumes that logic can migrate to its most natural place through refactoring.
However, you could argue that REST is just a stop-gap until you understand your clients better. Is REST just a hack? Is Demeter unrealistic in any server/client scenario?

Is Demeter unrealistic in any server/client scenario?
I think you answered your own question here. How is REST in this manner different than SOAP or XML-RPC in this regard?
The point of REST is not to provide super-loose coupling, but the following:
Provide a identifier which accurately describes the resource being requested.
Provide services which behave as expected GET requests are idempotent, PUT updates records, POST creates, DELETE deletes
Minimize state being stored on the server
Tear down unnecessary complexity
There are cases where REST isn't the best answer, but REST works remarkably well in general.

I pay that law/suggestion no mind whatsoever. It defeats half the benefit of aggregation and composition, and I won't have it.

A link that is provided by a representation, exposed by a RESTful interface, can be completely opaque without violating any of REST's constraints. Therefore I would suggest that REST is completely consistent with the Law of Demeter. There is no requirement that the link expose the structure of the URL space in its URL.
e.g. in an object oriented scenario, you might replace the call a.b.c with a.bc
In a RESTful representation you could create the following:
<a>
<link href="bc"/>
</a>
instead of doing
GET a
<a>
<link href="b"/>
</a>
GET b
<b>
<link href="c"/>
</b>
GET c
I would have to disagree with altCognito and say that one of the main goals of REST is loose coupling. The uniform interface, standard media types and HATEOAS all combine to produce an extremely loosely coupled interface.
In response to David's comment:
REST is all about super-loose coupling to the point where it is pointless for the provider to try to anticipate all the needs of the clients
Actually, REST is about limiting the clients options by providing only valid links in the representations. Within those constraints the client can attempt to satisfy its own needs. It is by removing the knowledge from the client of when certain requests can be made that you achieve loose coupling. Loose coupling is not achieved by listing a set of resources and saying "ok, you can GET, PUT, POST, DELETE all you want."

I think they're really orthogonal. REST describes a collection of resources addressed by URIs with a set of canonical methods: GET, POST, etc. If REST routine returns a URI, that's not "reaching through" it's identifying a different object with the same method names.

Related

RPC vs restful endpoints

I've spent more time than I'd like to admit trying to understand the differences between RPC and restful endpoints. In fact, after going down this rabbit hole, I'm not even sure I fully understand what RPC is anymore. And I'm not alone. I see countless messages repeatedly asking for clarification.
Here's my understanding so far:
RPC and restful endpoints are largely conceptual in nature only. There are no standards.
Both are ways of invoking a function on a remote server.
In the case of restful endpoints, we map HTTP methods to CRUD operations on a resource.
In the case of RPC, we're concerned w/actions on an object.
However, in both cases, we're addressing remote method invocation.
I've read some folks say restful shouldn't be stateful and if it is, it's not restful. But aren't most restful endpoints using state via sessions? I mean, I'm not going to let just anyone delete data w/o being logged in.
And I've also read that functions like domain(.)com/login isn't restful b/c it's an action. This seems to make sense, but since I'm not writing my functions any differently on my server than I would a simple restful function, does it really matter what we call them -- restful vs. RPC.
I truly just don't understand what I'm missing and no posts thus far on StackOverflow appear to address this confusion.
Hoping someone can provide some insight using the above as a guide for understanding. Thanks in advance.
It's an amazing question. There is a huge difference between REST and RPC approaches, I'll try to explain it.
RPC just lets you call some remote computer to make some job. It can be any job, and it can have any inputs and outputs. When you design API, you just define how to name this job operation and which inputs and outputs it will have.
Step 1. Just RPC
For example, you could have operation foo with one input and two outputs like that (I will use JSight API notation because it supports both RPC and REST API types):
JSIGHT 0.3
URL /rpc-api
Protocol json-rpc-2.0
Method foo
Params
{
"input-1": 123 // some integer
}
Result
{
"output-1": 123, // some other integer
"output-2": "some string"
}
When you design your RPC API you can use as many such operations as you want.
So, what's the problem with this? Why do we need REST, if we already have RPC?
The problems are the following:
When you look at the method foo definition you do not have the slightest idea, what it does.
When you design RPC APIs you have absolute freedom, but freedom often can be a bad thing. Because people think in different fashions. You could think, that your API is easy and elegant, but other people would not think so.
Step 2. Standardized RPC
If you are an experienced API designer and you use the RPC style, you will try to follow some pattern to avoid the two faults mentioned above. For example, let's imagine, that your foo method returns a customer entity. Then you will never call it like foo, you will call it getCustomer, like this:
JSIGHT 0.3
URL /rpc-api
Protocol json-rpc-2.0
Method getCustomer
Params
{
"input-1": 123 // some integer
}
Result
{
"output-1": 123, // some other integer
"output-2": "some string"
}
Ok! Now when you just look at this description, you can say, that this method returns a customer; that parameter input-1 is some filter, most possibly, ID; and output-1 and output-2 are some customer properties.
Look, just using the standard way of naming the method, we made our API much more easy-to-understand.
Still, why do we need REST? What's the problem here?
The problem is, that when you have dozens of such RPC methods, your API looks messy. E. g.:
JSIGHT 0.3
URL /rpc-api
Protocol json-rpc-2.0
Method getCustomer
Method updateCustomer
Method getCustomerFriends
Method getCustomerFather
Method askCustomerConfirmation
# etc...
Why it is not easy to understand this bunch of methods? Because it is not the way our brain works. Our brain always groups actions by entity. You naturally think about an entity, and then about actions, you can do with it. E. g. what you can do with a cup? Take, hide, break, wash, turn over. And brain rarely thinks firstly about actions and then about entities. What can I take? Cup, ball, ice cream, ticket, wife. Not very natural.
So, what is REST about?
Step 3. REST
REST is about grouping entities and defining the most standard actions with these entities.
In IT we usually create, read, write, or delete entities. That's why we have POST, GET, PUT, and DELETE methods in HTTP, which is de facto the only implementation of the REST style.
When we group our methods by entities, our API becomes much clearer. Look:
JSIGHT 0.3
GET /customer/{id}
PUT /customer/{id}
GET /customer/{id}/friends
GET /customer/{id}/father
POST /customer/{id}/ask-confirmation
It is much easier to perceive now than in the RPC-style example above.
Conclusion
There are a lot of other issues, concerning differences between RPC and REST. REST has its faults as well as RPC. But I wanted to explain to you the main idea:
REST is a standard, that helps you to organize your API in a user-friendly fashion, that is comfortable for the human brain, so any developer can quickly capture your API structure.
RPC is just a way of calling remote operations.
All the examples above are gathered here: https://editor.jsight.io/r/g6XJwjV/1
I truly just don't understand what I'm missing
Not your fault, the literature sucks.
I think you may find Jim Webber's 2011 guidance enlightening.
Embrace HTTP as an application protocol. HTTP is not a transport protocol which happens to go conveniently through port 80. HTTP is an application protocol whose application domain is the transfer of documents over a network.
HTTP, like remote procedure calls, is a request/response protocol. The client sends a message to the server, the server sends a message back. Big deal.
But in the REST architectural style, we're also following the uniform interface constraint. That means (among other things) that everybody understands requests the same way, and everybody interprets responses the same way.
And that in turn means that general purpose components (browsers, web crawlers, proxies) can understand the request and response messages, and react intelligently to those messages, without needing to know anything at all about the specialization of a particular resource.
In the case of HTTP, we're passing messages about the domain of documents; if I want information from you, I ask for the latest copy of your document. If I want to send information to you, I send you a proposed modification to your document. Maybe you respond to my modification by creating a new document and you tell me to go look at that. And so on.
Useful business activity, then, becomes a side effect of manipulating these documents. Or, expressed another way, the document metaphor is the facade we present to the world.
And I've also read that functions like domain(.)com/login isn't restful b/c it's an action.
See above: the literature sucks.
Consider this resource identifier: https://www.merriam-webster.com/dictionary/login
Does it work like every other resource identifier on the web? Yes. The browser knows how to make a request to GET this resource, and when Merriam-Webster answers that the browser should instead look at https://www.merriam-webster.com/dictionary/log%20on then it fetches that resource as well.
The fact that "login"/"log on" are intransitive English verbs does not matter; it's an identifier, and that's all the browser needs to know.
Alternatively, consider this: URL shorteners work.
Resource identifiers are a lot like variable names in a computer program; so long as the identifier satisfies the production rules of your language, you can use anything you want. The machines don't care.
The key idea is that resources are not actions, they are "information that can be named". https://www.merriam-webster.com/dictionary/log%20on is the name of the document that describes Merriam-Webster's definition of the verb "log on".
Since the machines don't care what names we use, we can use the extra freedom that offers us to choose names that make life easier for people we care about.
I've read some folks say restful shouldn't be stateful and if it is, it's not restful. But aren't most restful endpoints using state via sessions?
Stateless communication is a REST architectural constraint.
each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server.
Cookies are one of the corners where HTTP failed to satisfy the stateless communication constraint.
I'm not going to let just anyone delete data w/o being logged in.
Not a problem: every HTTP request carries its own Authorization metadata; you aren't supposed to "remember" previous messages in the conversation. Instead, you verify the provided credentials every time.

Sub-resource creation url

Lets assume we have some main-resource and a related sub-resource with 1-n relation;
User of the API can:
list main-resources so GET /main-resources endpoint.
list sub-resources so GET /sub-resources endpoint.
list sub-resources of a main-resource so one or both of;
GET /main-resources/{main-id}/sub-resources
GET /sub-resouces?main={main-id}
create a sub-resource under a main-resource
POST /main-resource/{main-id}/sub-resouces: Which has the benefit of hierarchy, but in order to support this one needs to provide another set of endpoints(list, create, update, delete).
POST /sub-resouces?main={main-id}: Which has the benefit of having embedded id inside URL. A middleware can handle and inject provided values into request itself.
create a sub-resource with all parameters in body POST /sub-resources
Is providing a URI with main={main-id} query parameter embedded a good way to solve this or should I go with the route of hierarchical URI?
In a true REST environment the spelling of URIs is not of importance as long as the characters used in the URI adhere to the URI specification. While RFC 3986 states that
The path component contains data, usually organized in hierarchical form, that, along with data in the non-hierarchical query component (Section 3.4), serves to identify a resource within the scope of the URI's scheme and naming authority (if any). The path is terminated by the first question mark ("?") and number sign ("#") character, or by the end of the URI. (Source)
it does not state that a URI has to have a hierarchical structure assigned to it. A URI as a whole is a pointer to a resource and as such a combination of various URIs may give the impression of some hierarchy involved. The actual information of whether URIs have some hierarchical structure to it should though stem from link relations that are attached to URIs. These can be registered names like up, fist, last, next, prev and the like or Web linking extensions such as https://acme.org/rel/parent which acts more like a predicate in a Semantic Web relation basically stating that the URI at hand is a parent to the current resource. Don't confuse rel-URIs for real URIs though. Such rel-URIs do not necessarily need to point to an actual resource or even to a documentation. Such link relation extensions though my be defined by media-types or certain profiles.
In a perfect world the URI though is only used to send the request to the actual server. A client won't parse or try to extract some knowledge off an URI as it will use accompanying link relation names to determine whether the URI is of relevance to the task at hand or not. REST is full of such "indirection" mechanism in order to help decoupling clients from servers.
I.e. what is the difference between a URI like https://acme.org/api/users/1 and https://acme.org/api/3f067d90-8b55-4b60-befc-1ce124b4e080? Developers in the first case might be tempted to create a user object representing the data returned by the URI invoked. Over time the response format might break as stuff is renamed, removed and replaced by other stuff. This is what Fielding called typed resources which REST shouldn't have.
The second URI doesn't give you a clue on what content it returns, and you might start questioning on what benefit it brings then. While you might not be aware of what actual content the service returns for such URIs, you know at least that your client is able to process the data somehow as otherwise the service would have responded with a 406 Not Acceptable response. So, content-type negotiation ensures that your client will with high certainty receive data it is able to process. Maintaining interoperability in a domain that is likely to change over time is one of RESTs strong benefits and selling points. Depending on the capabilities of your client and the service, you might receive a tailored response-format, which is only applicable to that particular service, or receive a more general-purpose one, like HTML i.e.. Your client basically needs a mapping to translate the received representation format into something your application then can use. As mentioned, REST is probably all about introducing indirections for the purpose of decoupling clients from servers. The benefit for going this indirection however is that once you have it working it will work with responses issued not only from that server but for any other service that also supports returning that media type format. And just think a minute what options your client has when it supports a couple of general-purpose formats. It then can basically communicate and interoperate with various other services in that ecosystem without a need for you touching it. This is how browsers operate on the Web for decades now.
This is exactly why I think that this phrase of Fielding is probably one of the most important ones but also the one that is ignored and or misinterpreted by most in the domain of REST:
A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. (Source)
So, in a true REST environment the form of the URI is unimportant as clients rely on other mechanisms to determine whether to use that URI or not. Even for so called "REST APIs" that do not really care about the true meaning of REST and treat it more like old-school RPC the question at hands is probably very opinionated and there probably isn't that one fits all solution. If your framework supports injecting stuff based on the presence of certain query parameters, use that. If you prefer the more hierarchical structure of URIs, go for those. There isn't a right or wrong in such cases.
According to the URI standard when you have a hierarchical relationship between resources, then better to add it to the path instead of the query. https://datatracker.ietf.org/doc/html/rfc3986#page-22 Sometimes it is better to describe the relation itself, not just the sub-resource, but that happens only if the sub-resource can belong to multiple main resources, which is n:m relationship.

How to model REST API for designing a calculator service

I have been reading about the best practices for designing API's for REST services that will be exposed to customers. For example, we should use Nouns to name all the URI's exposed. Further the verbs should obey the semantics of the HTTP commands. For example, a GET request should never modify the resource, instead PUT request should be used here. I was asked this question during an interview and couldn't answer this satisfactorily-- I am designing a calculator that provides following functions, add, multiply, divide, subtract on two operands. How do I expose these methods to clients following REST principles. What URI to use for these operations? And I am not sure whether to map an add operation to GET,PUT or POST. Same for the other operations (divide, multiply etc). What are the guidelines here ?
What are the guidelines here ?
How would you do it with a web site?
That should be your first heuristic any time somebody asks you about REST. REST is an
architectural style, designed for "long-lived network-based applications that span multiple organizations". The reference application for this architectural style is the World Wide Web.
I am designing a calculator that provides following functions, add, multiply, divide, subtract on two operands. How do I expose these methods to clients following REST principles.
There are three pieces of information that the client has, which need to be communicated to the server - the operation and the two operands. One the web, the usual way to collect that sort of information is to provide a form. In this case, it might be a dropdown list of operations, and a couple of text controls to accept numbers. Because a pure function is a safe, we would probably use GET as the form method. So the HTML processing rules would take the values described by the form and transcribe them as key value pairs in the query part.
So the url would look something like
/22520c7f-6207-490e-99c9-bd1bb37f4056?op=add&firstArg=6&secondArg=9
The key generalization is to realize that the HTML form is playing the role of a URI Template - the server passes the template to the client, the client fills in the details and uses the result as the target of the request.
What this implies is that if you wanted to replace HTML with some other media type, you would need to specify a description for URI Templates, some mechanism for describing the acceptable ranges and what values might be reasonable defaults.
What URI to use for these operations?
With REST? absolutely does not matter. That's part of the point -- the client treats URI as opaque values.
URI are just identifiers; you can think of them like variable names in a program. The machines just don't care what the spellings are (so long as those spellings are consistent with RFC 3986).
Since the spelling doesn't matter, you can use whatever the local spelling conventions happen to be. A lot of people favor "hackable" URI -- the spelling of the identifier communicates useful information to the human reader.
URI are identifiers of resources; "any information that can be named can be a resource". This motivates some of the "nouns not verbs" noise -- the resources are web pages, or documents, or images, or scripts, or ... the "resource" concept is deliberately vague, so that it can be used flexibly.
I am not sure whether to map an add operation to GET,PUT or POST.
The key is to look at the semantics of the client's request. Anytime what you are doing is a query/lookup, something that is OK for the machine to do automatically for the user, then you are looking at safe semantics, and the method is likely to be GET or HEAD (special circumstances).
If we were asking the server to change the representations of its own resources, then PUT and POST come into play.
In this case, all of these operations are just doing lookups, so GET is appropriate.
(An interesting thing to note is that the none of these operations depend on server state; they are pure functions. So it might make sense to serve the client with code on demand -- javascript or some reasonable replacement -- and use the client's processor to perform the calculations rather than doing a bunch of round trips across the network).
I think one issue with the term REST is that it can have a different meaning to different people. It's possible that the interviewer has a different understanding of REST. When something like this comes up, my first inclination is to try to figure out what REST means to them. Do they mean hypermedia? Do they care about the verbs and nouns being used correctly as you mentioned? Or is in their mind REST just some HTTP endpoint that returns JSON. All of these are possible.
I would be inclined to answer the question as follows I think:
GET /add/1/2
GET /multiply/5/6
etc..
Others with much more experience than myself have answered with examples of good ways to do this.
I'd just like to point out what a really excellent question this is. I'm reading a paper by Richard Taylor and others from UC Irvine. Richard Taylor was Roy Fielding's advisor back when Fielding described REST in his PhD thesis. In a discussion comparing REST and SOAP, the paper includes this:
"...the closer the service semantics are to those of content, the more likely the service is to have a rich REST API.
...
the division between REST and SOAP may reflect a lack of design guidance; how can
services that are not content-centric, such as auction bidding
... be cleanly constructed in a REST-consistent manner?"
When they say "closer to content" they mean that the service looks more like some dynamic or static information to be retrieved by the end user, as opposed to a service looks like something that actively performs some function or calculation for the user.
They go on to provide additional guidance on this - but I haven't finished reading the paper yet, so I'll let you look that up for yourself. :-)
Search the web for: From Representations to Computations: The Evolution of
Web Architectures, Richard N. Taylor, UCI

How can I define my REST API?

I have 3 models: tournament, championship and competitor:
A tournament has many championships;
A championship belongs to tournament;
A championship has many competitors.
So, to list all the competitors from all the championships, the URL is:
GET https://base.com/tournament/{slug}/competitors
but to add a competitor, it is related to championship so:
POST https://base.com/championships/{id}/competitors
Is it ok that for the same model, two verbs (GET and POST) has differents URI? Otherwise, how should I do?
I fell like doing:
POST https://base.com/tournaments/{slug}/championships/{id}/competitors
has a no necessary field.
Is it ok that for the same model, two verbs (GET and POST) has differents URI?
This is likely to cause confusion for the API consumers, so I advise you use the same URI.
Bear in mind that the REST architectural style, described in the chapter 5 of Roy T. Fielding's dissertation, defines a set of constraints for applications build on the top of such architecture. But it says nothing about what the URIs must be like.
The examples shown in a popular article written by Martin Fowler explaining a model defined by Leonard Richardson suggest a URI structure that looks friendly and easy to read. While it may be desirable, it's not mandatory for REST applications.
There are plenty of valid approaches you could go for. If a competitor requires a championship to exist and a championship requires a tournament to exist, you could express such hierarchy using:
/tournaments/{slug}
/tournaments/{slug}/championships/{id}
/tournaments/{slug}/championships/{id}/competitors/{id}
But the last URI may be considered too long and may be hard to remember. So you could simply split it, then you don't need to send many parameters around:
/tournaments/{slug}
/championships/{id}
/competitors/{id}
If you need to perform any filtering, you could use query parameters. For example:
/championships/{id}?tournament={slug}
Reminder: REST doesn't care what spelling you use for your URI
Is it ok that for the same model, two verbs (GET and POST) has differents URI? Otherwise, how should I do?
It's OK, but there are certain costs associated with it.
Let's review what Fielding had to say (2008)
REST is intended for long-lived network-based applications that span multiple organizations.
The REST interface is designed to be efficient for large-grain hypermedia data transfer, optimizing for the common case of the Web, but resulting in an interface that is not optimal for other forms of architectural interaction.
One of the replication styles that Fielding identifies in his thesis is the cache; he goes on to add that style to his definition of REST
In order to improve network efficiency, we add cache constraints to form the client-cache-stateless-server style.... Cache constraints require that the data within a response to a request be implicitly or explicitly labeled as cacheable or non-cacheable. If a response is cacheable, then a client cache is given the right to reuse that response data for later, equivalent requests.
In HTTP, the semantics of caching are defined in RFC 7234; Section 4.4 describes invalidation.
A cache MUST invalidate the effective Request URI (Section 5.5 of [RFC7230]) as well as the URI(s) in the Location and Content-Location response header fields (if present) when a non-error status code is received in response to an unsafe request method.
This means that communication passing through generic clients, that know nothing of the specifics of your protocols, can invalidate their local copy of stale representations, based on the metadata in the request and response.
(This was a bigger deal in the past, when we weren't encrypting all of the traffic; but it still applies to (a) the client's local cache and (b) the caching reverse proxy sitting in front of the domain model).
As far as REST is concerned, URI are opaque; there's no fundamental relationship between
/A
/A/B
/A/B/C
/A/B/D
/A/E
So if the caches see that /A/B should be invalidated, they can do that, but they won't do anything with the other URI.
For PUT, DELETE, PATCH -- the semantics of these methods is very specific to the effective request URI.
If you apply that same approach to POST, then you get cache invalidation "for free".
Walking through a simple example; imagine a web site, where we have
GET /superCoolResource
GET /superCoolResource/editForm
We want to induce some change in /superCoolResource, so we load the edit form, and submit it....
POST ...?
If we POST to /superCoolResource/editForm, then we are telling the client that the cached copy of the form should be reloaded if the POST is successful. But that probably isn't what we want -- it's more likely that the form stays the same, and the /superCoolResource is the thing that changes. That means we probably want to make /superCoolResource the target URI
GET /superCoolResource/editForm
200 OK
... <form action="/superCoolResource" method="POST"> ....
and magically the client's cache, the origin server's cache, and any intermediate caches that are privy to the conversation know to evict their old copy of /superCoolResource when the POST succeeds.

what's the real added value in REST routes?

AFAIU, RESTful API use http nomenclature to organize API.
From an exemple taken best practices you'll end up with:
http://api.college.com/students/3248234/courses/physics
What's the real advantage, from more naïve approach such as:
http://api.college.com/course_show?STUDENTID=3248234&COURSETYPE=physics
http://api.college.com/ratings_show?STUDENTID=3248234&COURSETYPE=physics
From my view point, first uri mixes stuffs: objects (students, courses) and their params (id for students, type for course). I fell it's a mess.
Moreover, we don't really know what's shown. It is the course taken by this student ? Or the rating our student achieved ? We can suspect that ratings would have been added at the end like .../courses/physics/ratings, but we can't be sure, since the last word is a parameters, not an object.
Second approach is more object oriented, like Course.show(**kwargs), and anyway has the advantage to separate function (or call it method) and parameters (or call it arguments).
Additional point, with this semantic, you can do CRUD but can be more detailed in your interface, like /course_delete or /course_suspend or /course_postpone
So two questions:
1- what's the real advantage of REST nomenclature on web API routing ? Isn't just hype ?
2- from security viewpoint, in my exemples, I suspect first url is less secure than second (flask had a problem with that if I remember well), is it correct ?
what's the real advantage of REST nomenclature on web API routing ? Isn't just hype ?
REST doesn't care what spelling you use for your identifiers.
URI Templates are a convenient way to generalize identifiers for different resources; this convenience is most frequently seen in mapping resource identifiers to implementations in the server, but are also sometimes seen as a means to describe a family of identifiers to a client that understands hypermedia representations.
Judicious use of path segments when describing a hierarchy of resources, allows you to take advantage of the client's ability to resolve relative references.
from security viewpoint, in my exemples, I suspect first url is less secure than second (flask had a problem with that if I remember well), is it correct ?
No? Neither of them offers any security at all; they are just identifiers.