Does HATEOAS imply that query strings are not RESTful?
Asked Answered
F

6

13

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.

Funicular answered 5/1, 2011 at 7:35 Comment(0)
N
4

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.

Neolith answered 5/1, 2011 at 14:12 Comment(5)
It sounds like buggy software is at risk of being written through possibly flawed interpretations of "human-meaningful" identifiers. To prevent flawed interpretations, it appears out of band information is necessary to properly build URIs. If out of band information is necessary modify links then what is the point of saying that hypermedia have to drive the state of the application? If you need out of band information, then why bother having the server send a bunch of links?Funicular
OK, to answer my own question about the server sending links, I know it is a good idea to have the client start with only one well known resource and so servers sending links is a good idea and the query strings might be convenient for historical reasons or because they map to a legacy namespace on the other side of a gateway. However, for Fielding to say he wants to maximize serendipitous use of URIs is not exactly the same as encouraging people to mangle query strings (safely by using out-of-band info, or unsafely). It's the query strings that are at the heart of my concern.Funicular
Mangling query strings looks like tight coupling. Is REST really encouraging tight coupling?Funicular
@broiyan URI templates are one way to allow clients to resolve uris without creating an unreasonable amount of coupling.Philan
@zoul, at this REST tutorial rest.elkstein.org, article 9, suggests the same as you did where responses should be lists of actual URLs that can be used by the client without the need for the client to assemble the query string.Funicular
D
7

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.

Dusen answered 8/10, 2013 at 13:27 Comment(0)
H
5

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

Herbage answered 5/1, 2011 at 15:31 Comment(1)
My understanding of this would be this: discoverability and "Hypermedia as the Engine of Application State" do not imply a method of construction of URIs (or, for that matter, any particularly human-comprehensible set of URIs). Construction of resource identifiers based upon client-side discovered state can, in my understanding, occur in any way possible.Aphrodisiac
N
4

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.

Neolith answered 5/1, 2011 at 14:12 Comment(5)
It sounds like buggy software is at risk of being written through possibly flawed interpretations of "human-meaningful" identifiers. To prevent flawed interpretations, it appears out of band information is necessary to properly build URIs. If out of band information is necessary modify links then what is the point of saying that hypermedia have to drive the state of the application? If you need out of band information, then why bother having the server send a bunch of links?Funicular
OK, to answer my own question about the server sending links, I know it is a good idea to have the client start with only one well known resource and so servers sending links is a good idea and the query strings might be convenient for historical reasons or because they map to a legacy namespace on the other side of a gateway. However, for Fielding to say he wants to maximize serendipitous use of URIs is not exactly the same as encouraging people to mangle query strings (safely by using out-of-band info, or unsafely). It's the query strings that are at the heart of my concern.Funicular
Mangling query strings looks like tight coupling. Is REST really encouraging tight coupling?Funicular
@broiyan URI templates are one way to allow clients to resolve uris without creating an unreasonable amount of coupling.Philan
@zoul, at this REST tutorial rest.elkstein.org, article 9, suggests the same as you did where responses should be lists of actual URLs that can be used by the client without the need for the client to assemble the query string.Funicular
N
2

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.

Neolith answered 5/1, 2011 at 8:24 Comment(1)
Re: search, if you're willing to model a particular search as a resource of its own, then you can delegate URL creation to the server. For example, POST a partial representation of the looked-for item (all that you know about it, e.g. { "id": 37 }) to /items/search, and the server could respond with a Link: </items?id=37>; rel=results header. That way the client never has to assemble a URL. (This suggestion is based on the idea that content types and link relationships must be part of a REST application's public contract for clients to be able to use the application at all.)Vivid
P
2

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]

Philan answered 5/1, 2011 at 13:5 Comment(3)
But a query string that indicates "where to return to after a successful login" is not a URI so it would seem that HATEOAS is being violated.Funicular
The login url is a URI. The redirect query string parameter is a URI. I don't understand what constraint you think is being violated.Philan
OK I understand that you are saying there is a URI inside a URI.Funicular
H
0

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.

Hereby answered 26/12, 2016 at 11:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.