Give me a example of non-RESTful design? - rest

I learned the term "RESTful" as a Rails developer. After reading wikipedia, also here and here.
I don't get it. It seems to me, Rails is only using a concise way to describe URLs. It seems to me every URI is RESTful, in it's designed scope.
For example, I think GET /delete?student_id=3 is RESTful in the scope the the application itself.
Can anybody tell me which constrict does it violate? Please refer the constrict from the REST definition.

A GET request should be idempotent and the request should not leave any side-effects on the server. Quoting from the HTTP spec sec 9.1.1:
In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.
Therefore GET /delete?student_id=3 already violates the idempotency assumption of the GET verb, since it will delete a record on the server.
A RESTful interface is a uniform interface, which in other words means that a GET is supposed to behave as required by the HTTP spec. And this is what the spec says:
The GET method means retrieve whatever information (in the form of an
entity) is identified by the Request-URI. If the Request-URI refers
to a data-producing process, it is the produced data which shall be
returned as the entity in the response and not the source text of the
process, unless that text happens to be the output of the process.
...

It seems to me, Rails is only using a
concise way to describe URLs. It seems
to me every URI is RESTful, in it's
designed scope.
URIs are neither RESTful or non-RESTful. REST is an architectural style for which you need to consider the overall application.
GET is the method for the retrieval request. If you want to put this in the context of the REST dissertation, if your GET request has side-effects, it will then break a few other constraints, for example regarding the cache.
You could also potentially design a RESTful system where a GET /delete?student_id=3 request gives you a representation telling you (or asking you to confirm) that you want to delete that student, so long as it doesn't actually perform the delete operation.

A GET should be safe to be RESTful, but obviously combined with a delete it is unsafe.
So it looks RESTful but doesn't act RESTful. So it fails the duck test.

See Section 5.1.5. Your example violates the uniform interface constraint. It does this by violating the HTTP spec.

Related

How do I best define an REST endpoint with a verb in it?

I need to define an end-point for an action the back-end is supposed to take: format the device.
The end-point I have come up with is:
POST /device/{deviceId}/format
without any body.
This, doesn't look RESTful though. Or is it?
Is there any alternative for this ? How can I make it RESTful?
REST doesn't care what spelling you use for your URI.
https://www.merriam-webster.com/dictionary/stop
https://www.merriam-webster.com/dictionary/go
https://www.merriam-webster.com/dictionary/procrastinate
All of these identifiers work fine. The machines don't care, because they aren't trying to extract semantic information from the identifier. General-purpose clients consider the URI to be opaque (aside from certain purely mechanical concerns permitted by RFC 3986).
This, doesn't look RESTful though. Or is it?
It can be fine, there might be better choices. Caching is a very important idea in REST, and if you expect that a successful POST request will change one of the representations that the client may have cached, then you will want to think about how to communicate to the client that some cache entries need to be invalidated.
Another way of expressing the same idea; you might imagine that our API is a collection of objects. What you are trying do here is send a format message to the device. A simple spelling of this might look like
Resource(/device/{deviceId}).FORMAT()
But our problem is that FORMAT isn't part of the uniform interface currently defined by HTTP; and trying to come up with semantics for FORMAT that are consistent across all resources isn't worth the bother.
What's are alternative? It's okay to use POST.
POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”
Resource(/device/{deviceId}).POST()
and that works fine. Of course, sometimes we have more than one action that isn't worth standardizing. How do we discriminate between them?
Resource(/device/{deviceId}).POST(format)
The general purpose components route the request to your post handler, then your bespoke code interrogates the request and forward it to the module in your code that specializes in handling formatting requests.

RESTful API Design and CQRS

I was thinking of how to make a RESTFul API more intention revealing. A common patter I see around various blogs on this is that conventional REST API results in
Ban a Player -> POST /players.
But I were to change to a more intention revealing interface , I could use
Ban a Player -> POST /players/{ playerid }/banPlayer
The second one I feel is more intention revealing.
The common objection I get from the team is that the second one does not comply with start REST style.
Also currently I cannot move away from a RESTful API.
I would like to hear your thoughts on this.
With Restful API design there are two schools of thought around how to apply actions to a resource.
You describe the action to be taken against the resource in the Uri:
Request Uri:
POST /players/{id}/ban
Note: Just use ban - we already know the resource is a player, its in the base Uri.
You can have the action in the body of the request:
Request Uri:
POST /players/{id}
Request Body:
{ 'action': 'ban' }
You can pick either way - whichever you prefer, there is lots of discussion on both but ultimately both are correct.
Note:
My assumption here that banning a player is more than just updating a part of it, but rather a system action (or state transition) relating to the player. Otherwise if it was just an update to the player resource you should handle with a PATCH or PUT as appropriate.
Some discussions for reference:
http://restful-api-design.readthedocs.io/en/latest/methods.html
https://github.com/interagent/http-api-design/issues/58
https://nordicapis.com/designing-a-true-rest-state-machine/
https://softwareengineering.stackexchange.com/questions/141410/restful-state-changing-actions
With plenty more if you do some Googling...
Long story short: it shouldn't be mandatory to be intention revealing but if you want to add some DDD on how this API looks like then it is nothing that prevents you from doing that
According to HATEOAS constraint of a RESTful web API (this constraint is an essential part of the "uniform interface" feature of REST, as defined in Roy Fielding's doctoral dissertation), the software clients of your API should not care about the URLs. Every possible&permitted action should be included in the response, with the corresponding link relation and URI. In this way you have to hardcode only the link relations.
This constraint does not however prevent you from making the API more intention revealing for the Human clients that try to understand the overall architecture. I recommend you to choose this path, as Human users are at least as important as the software that they write.
Roy Fielding wrote about this on his blog post.
Since you asked for the RESTful way not the best way, here's my thoughts.
Your RESTful URI options include:
/players
/players/{ playerid }/banPlayer
/player-banning
/entities?action=ban_player&method=PUT
/banana
anything else, REST doesn't dictate what your URIs should look like
The RESTful way is to expose knowledge of the next available states purely through hypertext. To do REST, you must use Hypertext As The Engine Of Application State (HATEOAS). Relying on client knowledge of the URI is depending on out-of-band knowledge, which is antithetical to REST.
Your resources do not need to map directly to your business objects. If you choose, you can represent user intent itself as a resource, e.g. a banned player event resource. You can POST to it with some info on which player to ban, and subsequent GETs will provide information on the event.
Oh and just because REST doesn't care what your URIs are, doesn't mean you shouldn't. You'll just have to use a different standard to decide what's best.
According to the REST API approaches, you need to use your entities in URI, so, as banPlayer is not an entity, you cannot use it.
I suggest to UPDATE your record with PUT method.
Here you can read more about rules. Actually, the first section about URIs is just about your case.
The common objection I get from the team is that the second one does not comply with start REST style.
The easy answer is this: consistency in the API has value, whether REST or not. So "that's not how we do it here" is going to trump "but REST says".
The spelling of URI in an API is a lot like the spelling of method names in your code. There are a lot of different arguments for different styles, but "local convention" is a strong argument by itself.
That said -- REST does not care what spelling you use for your identifiers.
This is what Fielding had to say in 2008
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. Any effort spent describing what methods to use on what URIs of interest should be entirely defined within the scope of the processing rules for a media type (and, in most cases, already defined by existing media types). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]
In band would be including the URI in the representation of the resource -- putting it into the description of a form in the HTML document. Out of band is documenting the URI, and expecting people to do the right thing with it.
Note: there's nothing wrong with human-readable URI, or documenting the URI that should be used. But notice that you can post questions to stackoverflow even though the people who wrote your browser didn't read stack overflow's API documentation -- that's REST.
This Google Cloud article API design: Understanding gRPC, OpenAPI and REST and when to use them clarifies the REST vs RPC debate. REST is more relevant for entity-centric API whereas RPC is more relevant for action-centric API (and CQRS). The most mature REST level 3 with hypermedia controls works well only for entities with simple state models.
Understand and evaluate first the benefits of REST for your case. Many APIs are REST-ish and not RESTful. OpenAPI is actually RPC mapped over and HTTP endpoints but it doesn't prevent it to be widely adopted.

If an API only provides POST requests functions, is it RESTful?

I'm not sure I understand correctly the notion of RESTful API. If I understand correctly, such an API should provide functions you can trigger with GET, POST, PUT & DELETE requests. My question is: if an API only provides POST requests functions, is it still RESTful?
You should probably watch this lecture and read this article.
REST a such has nothing to do with how much of available HTTP methods you use. So, the quick answer is: yes, it could be considered "restful" (whatever that actually means).
Buuut ... it most likely - isn't. And it has nothing to do with the abuse of POST calls.
The main indicator for this magical "RESTfulness" has nothing really to do with how you make the HTTP request (methods and pretty URLs are pointless worthless as a determining factor).
What matters is the returned data and whether, by looking at this data, you can learn about other resources and actions, that are related the resource in any given endpoint. It's basically about the discover-ability.
REST is a misused term for some time and the community especially at Stackoverflow doesn't even care about its actual intention, the decoupling of clients from server APIs in a distributed system.
Client and server achieve the decoupling by following certain recommendations like avoiding stateful connections where client state is stored at and managed by the server, using unique identifiers for resources (URIs) and further nice-to-have features like cacheability to reduce the workload both server and clients have to perform. While Fieldings dissertation lists 6 constraints, he later on explained some further rules applications following the REST architectural style have to follow and the benefits the system gains by following these. Among these are:
The API should not depend on any single communication protocol and adhere to and not violate the underlying protocol used. Altough REST is used via HTTP most of the time, it is not restricted to this protocol.
Strong focus on resources and their presentation via media-types.
Clients should not have initial knowledge or assumptions on the available resources or their returned state ("typed" resource) in an API but learn them on the fly via issued requests and analyzed responses. This gives the server the opportunity to move arround or rename resources easily without breaking a client implementation.
So, basically, if you limit yourself only to HTTP you somehow already violate the general idea REST tries to impose.
As #tereško mentioned the Richardson maturity model I want to clarify that this model is rather nonsense in the scope of REST. Even if level 3 is reached it does not mean that this architecture follows REST. And any application that hasn't reached level 3 isn't following this architectural style anyways. Note that an application that only partially follows REST isn't actually following it. It's like either properly or not at all.
In regards to RESTful (the dissertation doesn't contain this term) usually one regards a JSON based API exposed via HTTP as such.
To your actual question:
Based on this quote
... such an API should provide functions you can trigger with GET, POST, PUT & DELETE requests
in terms of REST architectural style I'd say NO as you basically use such an API for RPC calls (a relaxed probably JSON based SOAP if you will), limit yourself to HTTP only and do not use the semantics of the underlying HTTP protocol fully; if you follow the JSON based HTTP API crowd the answer is probably it depends on who you ask as there is no precise definition of the term "RESTful" IMO. I'd say no here as well if you trigger functions rather than resources on the server.
Yes. Restful has some guidelines you should follow. As long as you use HTTP verbs correctly and good practices with regards to URLs naming having only POSTs would be OK. If, on the other hand, a POST request in your application can also delete a record, then I would not call it Restful.

Using POST as a workaround for the URL character limit

If you have an API and support the POST operation only because of URL length limitations and the passing of complex parameters in the request, can you still say that you have a RESTful architecture?
What the above basically implies is that for this particular (read-only) API, there is no semantic difference between a GET and a POST, so what can be done with a GET can also be done with a POST (but not vice versa due to the limitations).
Would this still make the style of the architecture a RESTful one?
Technically you are not violating any constraints. However you are severely reducing the self-descriptiveness of requests. This will result in the loss of the ability to cache responses. Being able to cache responses is an essential feature that is needed to build effective REST systems.
You will definitely lose functionality HTTP provides for GET requests. Proxies for instance make certain assumptions about GET requests (idempotence, cachability).
There's nothing wrong with POST perse, but maybe the REPORT method is more appropriate.
So the question here is about restful architecture not for restful web services.If we go by the information given on Wiki-RestfulArch-Constraints , Yes it is.
The term Representational State Transfer was introduced and defined in 2000 by Roy Fielding in his doctoral dissertation. Section 6.3 explains how to apply REST to HTTP: http://www.ics.uci.edu/~fielding/pubs/dissertation/evaluation.htm#sec_6_3
Fielding does not claim that the use of POST is forbidden.
Wikipedia also mentions POST as a legal HTTP operation for RESTful web services:
http://en.wikipedia.org/wiki/Representational_State_Transfer#RESTful_web_services
Why don't you simply switch to including a body in the GET instead of using the query string?
Update
The RFC says the following:
A server SHOULD
read and forward a message-body on any request; if the request method
does not include defined semantics for an entity-body, then the
message-body SHOULD be ignored when handling the request
Theres nothing in the specification that says that a body cannot be included in any of the methods. And all proxies, servers etc are obliged to include the body. It's up to the handler (you) to ignore the body or not.
As for the GET method, nothing states that it can not include a body.
This means that you can use a GET body as long as your web server supports it.

Does HATEOAS imply that query strings are not RESTful?

Does the HATEOAS (hypermedia as the engine of app state) recommendation imply that query strings are not RESTful?
Edit: It was suggested below that query strings may not have much to do with state and that therefore the question is puzzling. I would suggest that it doesn't make sense for the URI to have a query string unless the client were filling in arguments. If the client is filling arguments then it is adulterating the server-supplied URI and I wonder if this violates the RESTful principle.
Edit 2: I realize that the query string seems harmless if the client treats it as opaque (and the query string might be a legacy and therefore convenient). However, in one of the answers below Roy Fielding is quoted as saying that the URI should be taken to be transparent. If it is transparent then I believe adulterating is encouraged and that seems to dilute the HATEOAS principle. Is such dilution still consistent with HATEOAS? This raises the question of whether REST is calling for the tight coupling that URI building seems to be.
Update At this REST tutorial http://rest.elkstein.org/ it is suggested that URI building is bad design and is not RESTful. It also iterates what was said by #zoul in the accepted answer.
For example, a "product list" request could return an ID per product, and the specification says that you should use http://www.acme.com/product/PRODUCT_ID to get additional details. That's bad design. Rather, the response should include the actual URL with each item: http://www.acme.com/product/001263, etc. Yes, this means that the output is larger. But it also means that you can easily direct clients to new URLs as needed
If a human is looking at this list and does not want what he/she can see, there might be a "previous 10 items" and a "next 10 items" button, however, if there is no human, but rather a client program, this aspect of REST seems a little weird because of all the "http://www" that the client program may have no use for.
In Roy Fielding's own words (4th bullet point in the article):
A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). Servers must have the freedom to control their own namespace. Instead, allow servers to instruct clients on how to construct appropriate URIs, such as is done in HTML forms and URI templates, by defining those instructions within media types and link relations.
In other words, as long as the clients don't get the pieces they need to generate URIs in out-of-band information, HATEAOS is not violated.
Note that URI templates can be used in URIs without query strings as well:
http://example.com/dictionary/{term}
So the question is more about whether it is RESTful to allow the client to construct URLs than whether it is RESTful to use query strings.
Notice how the amount of information served to the client in the example above is exactly equivalent to serving an exhaustive list of all the possible terms, but is a lot more efficient from a bandwidth point of view.
It also allows the client to search the dictionary while respecting HATEAOS, which would be impossible without the in-band instructions. I am quite confident that Roy Fielding is not promoting a Web without any search feature...
About your third comment, I think Roy Fielding is encouraging API designers to have "transparent" URIs as an extra feature on top of HATEAOS. I don't interpret his quote in zoul's answer as a statement that clients would use "common sense" to navigate an API with clear URIs. They would still use in-band instructions (like forms and URI templates). But this does not mean that transparent URIs are not way better than dark, surprising, opaque URIs.
In fact, transparent URIs provide added value to an API (debugging is one use case I can think of where having transparent URIs is invaluable).
For more info about URI templates, you can have a look at RFC6570.
My take on it is that REST itself says nothing about whether URI are opaque or transparent but that REST app should not depend on the client to construct URI that the server hasn't already told it about. There are a variety of ways for the server to do this: for example, a collection which may include links to its members, or an HTML form with the GET method will obviously cause a URI with params to be created client-side and fetched, or there are at least a couple of proposed standards for URI templates. The important thing for REST is that the description of valid URI should be defined somehow by the server in the responses it gives to clients, and not in some out-of-band API documentation
URI transparency is a good thing in the same way as transparency anywhere is a good thing - it promotes and permits novel and unplanned uses for resources beyond what the designer had originally imagined - but (at least in my understanding) nice URIs are not required to describe an interface as RESTful
I would suggest that it doesn't make
sense for the URI to have a query
string unless the client were filling
in arguments.
That does not seem true to me. If you ask server for a handful of photos, it’s perfectly valid for the server to return something like this:
<photos>
<photo url="http://somewhere/photo?id=1"/>
<photo url="http://somewhere/photo?id=2"/>
</photos>
You could use /photo/id/xx path instead, but that’s not the point. These URLs are usable even without the client changing them. As for your second point:
If the client is filling arguments
then it is adulterating the
server-supplied URI and I wonder if
this violates the RESTful principle.
I guess this is the heart of your question. And I don’t think you have to treat URLs as opaque identifiers, see this quote by Roy Fielding himself:
REST does not require that a URI be
opaque. The only place where the word
opaque occurs in my dissertation is
where I complain about the opaqueness
of cookies. In fact, RESTful
applications are, at all times,
encouraged to use human-meaningful,
hierarchical identifiers in order to
maximize the serendipitous use of the
information beyond what is anticipated
by the original application.
I don’t see what query strings have to do with state tracking. The point of the HATEOAS principle is to refrain from tracking the state on the client, from “cheating” and going to “known” URLs for data. Whether those URLs have query strings or not seems irrelevant to me.
Oh. Maybe you’re interested in something like search URLs where a certain part of the URL has to change according to search criteria? Because such URLs would seemingly have to be known beforehand, thus representing the out-of-band information that we seek to eliminate with REST? I think that this can be solved using URL templates. Example:
client -> server
GET /items
server -> client
/* …whatever, an item index… */
<search by="color">http://somewhere/items/colored/{#color_id}</search>
This way you don’t need no a priori URL knowledge to search and you should be true to the hypermedia state tracking principle. But my grasp of REST is very weak, I’m answering mainly to sort things in my head and to get feedback. Surely there’s a better answer.
No HATEOAS does not mean query strings are not RESTful. In fact the exact opposite can be the case.
Consider the common login scenario where the user tries to access a secured resource and they are sent to a login screen. The URL to the login screen often contains a query string parameter named redirectUrl, which tells the login screen where to return to after a successful login. This is an example of using URIs to maintain client state.
Here is another example of storing client state in the URL: http://yuml.me/diagram/scruffy/class/[Company]<>-1>[Location], [Location]+->[Point]
To follow-on from what Darrel has said, you do not need to alter the URL to include a second URL.
For cookie-based authentication you could return the login form within the body of the 401 response, with an empty form action, and use unique field names that can be POSTed to and processed by every resource. That way you avoid the need for a redirect entirely. If you can't have every resource process log-in requests, you can make the 401 form action point to a log-in action resource and put the redirect URL in a hidden field. Either way, you avoid having an ugly URL-in-a-URL, and the first way avoids the need for both an RPC log-in action and a redirect, keeping all the interaction focused on the resource.