Does anybody know of an implementation of a REST client that embraces the constraint of Hypermedia as the Engine of Application State (HATEOAS)?
The Sun Cloud API seems to be a good candidate, judging from the way it's documented and a statement by the author to the effect that Ruby, Java, and Python implementations were in the works. But so far I've found no trace of the code.
I'm looking for anything - even a partial implementation would be helpful.
The very first thing you should look at is the common web browser. It is the standard for a client that embraces HATEOAS (at least to some degree).
This is how Hypermedia works. It's so simple that it's almost painful:
you point your browser to http://pigs-are-cool.org/
the browser loads the HTML page, images, CSS and so on.
At this point, the application (your browsing experience) is at a specific URI.
The browser is showing the content of that URI
you see a link in the application
you click the link
the browser follows the link
at this point, the application is at a different URI
The browser is showing the content of the new URI
Now for a short explanation of how the two terms relate to the web browsing experience:
Hypermedia = HTML pages with the embedded links
Application state = What you're seeing in the browser at any point in time.
So HATEOAS actually describes what happens in a web browser when you go from web page to web page:
HTML pages with embedded links drive what you see in the browser at any point in time
The term HATEOAS is just an abstraction of this browsing experience.
Other examples of RESTful client applications include:
RSS and Feed readers. They traverse links given to them by users
Most AtomPub blog clients. They need merely a URI to a services document, and from there they find out where to upload images and blog posts, search and so on.
Probably Google Gadgets (and similar), but they're merely browsers in a different skin.
Web crawlers are also RESTful clients, but they're a niche market.
Some characteristics of RESTful client software:
The client works with with any server, given that it is primed with some URI and the server responds with an expected result (e.g. for an atom blog client, an Atom services document).
The client knows nothing about how the server designs its URIs other than what it can find out at runtime
The client knows enough media types and link relations to understand what the server is saying (e.g. Atom or RSS)
The client uses embedded links to find other resources; some automatically (like <img src=) some manually (like <a href=).
Very often they are driven by a user, and can correctly be termed "user agents", except for, say GoogleBot.
Restfulie is a Ruby, Java, and C# framework which aims to enable building clients and servers which employ HATEOAS. I haven't used it, but it does look interesting.
Here's some example code from their java project:
Order order = new Order();
// place the order
order = service("http://www.caelum.com.br/order").post(order);
// cancels it
resource(order).getTransition("cancel").execute();
Again, I'm not sure exactly what this does, or how well it works in practice, but it does seem intriguing.
The problem with REST HTTP and HATEOAS is that there is no common approach to specifying links so it is hard to follow links since their structure might change from a service provider to another. Some would use <link href="..." /> others would use proprietary structure for of links ex. <book href="..." />. It is not like in HTML or atom were link are part of a standard defined.
A client can't know what a link is in your representation is it doesn't know your media type unless there is a standard or conventional representation of a link
The HATEOAS design principle (REST is a set of design principles also) means that each resource should have at most a single fixed URL.
Everything else related should be discoverable dynamically from that URL through "hypermedia" links.
I just started a wikipedia stub here
In the meanwhile, there is the Spring HATEOAS project. It has also a client implementation:
https://docs.spring.io/spring-hateoas/docs/current/reference/html/#client
Map<String, Object> parameters = new HashMap<>();
parameters.put("user", 27);
Traverson traverson = new Traverson(URI.create("http://localhost:8080/api/"), MediaTypes.HAL_JSON);
String name = traverson
.follow("movies", "movie", "actor").withTemplateParameters(parameters)
.toObject("$.name");
Related
I'm new to web services world. I have created a rest api in ERP software that creates sales order. How will anyone outside the world know what parameters to send to this and in what format ? From all the videos I have watched and all materials read they talk about no api documentation is needed as it is REST service, People just know what request payload to send. I m not sure if I understand how that is possible. Its like I give somebody the url and tell them go figure. I tried sending orders with different parameter list and it is creating errors. But, if I send it in the way it accepts then it is working fine. Not sure if I understand the concepts well. Should I be creating documentation of this api telling what the request payload should look like ?
I completely disagree with the answer given by Joessel, which just propagates a typical RPC take on it, which is NOT REST at all!
In regards to how a service utilizing the REST architecture style should inform clients about what properties a resource supports and stuff like that, just look at traditional HTML pages. How are Web server able to tell your Browser what input it expects?
HTML is a media type that specifies the syntax to use as well as the semantics of each of the elements and attributes wich are admissible in a HTML document. I.e. HTML Forms enables a server to inform a client on the respective properties a resource support. In addition to that, a server also teaches a client on the respective target URI to send the request to, the HTTP operation to use upon sending the request as well as the media type to use for marshalling the request to a respective representation format. This is why you DON'T NEED any other documentation to interact with Web pages. Most arbitrary Web clients support HTML documents by default and therefore you don't need to reimplement the wheel to process such documents.
For non-HTML resources it is also just a matter of whether your client supports the respective media type or not. I.e. PNG files also follow a certain standard which allows arbitrary clients to show images instead of the actual bytes on your screen.
Most of those so called "REST APIs", which are truely RPC ones, just use custom JSON based message structures. JSON itself just defines the basic syntax but no semantics for any elements, attributes or other properties. It doesn't even add support for links. JSON Hyper-Schema is an extension which at least triest o add support for it, though it already requires to use an other media type than application/json. Though, if such formats are not well-defined and standardized, widespread adoption will not be possible on the long run. Hence creating a common media type is of importance to increase interoperability for such media types. I.e. for JSON based formats, HAL+JSON, HAL Forms, ION, and others provide definitions for basic JSON based message structures, with support for links and other features like form-support and other things.
So, if you take a closer look at the Web, you will find many concepts that you can reuse for a truely RESTful design. After all, REST just takes the ideas used on the Web for decades and attempts to offer the benefits resulting from these concepts to applications rather than humans alone. As such, it is always a good idea to first design the interaction flow as if one would interact with a traditional Web page and then take the concepts used in that design and apply it onto your application domain model.
As you don't need external documentation to interact with Web pages, so you don't need external documentation to interact with well defined message formats that follow a common media type as well. Through content-type negotiation both server and client will communicate with representation formats both support. So, the more (different) media types you support, the more likely you will be in the end to interact with different parties in that environment and if all of the supported media types are standardized you might not need any external documentation at all.
If you follow the academic definition of REST defined by Dr Fielding in his dissertation, it is true that such a service doesn't need any documentation. Hovewer, the chance are high that your service is not RESTful by his definition and that you need a documention to help your consumers. You can find an informative discussion about why a REST api doesn't need a documentation here.
That being said, you will probably need a documentation in most case. Depending on your needs and consumers of your api, a simple text file could be enough; maybe a markdown that you can easily share with other developers. Just remember to add all information needed to understand each route (verb, path, query, body, response...), and you can even throw some example code to make it easy to start.
And if you need something more robust, I can only advise you to follow the open api specification. One of the easiest way to get started is to use the swagger editor . You will even be able to publish your documentation in a nice way using one of the many tools out there (ex: redoc).
Writing a documention is never fun but nobody will use a product that they cannot understand, however great the product is.
Good luck,
Edit:
I rewrote the introduction as it was misleading, thanks to #Roman Vottner for pointing it out. THe previous intro was:
I don't know who told you that a documentation is not needed for a REST Api but I find this highly misleading for newcomers... A documentation is (super) important, especially if you are not the sole consumer of your API, and in that case I would say it's mandatory.
I have been trying to understand what a RESTful API/Web Application is supposed to look like and I cant help but wonder if the Web is already built under a RESTful architecture. Every website is basically a collection of web pages (A specific representation of the state of the Web App) and you change states by clicking links. Therefore you have Representational State Transfer!
Am I wrong in thinking this? Also, every SO answer to the question 'What is REST?' which I have managed to find fails to provide an example and show the difference between a non-RESTful API and a RESTful API.
Can someone provide that please? It would help in clearing things up. I do not want abstract terms in the answer because it would be more helpful to fit the abstract answer into an example rather than try to figure out an example from an abstract answer. Beginner speaking :)
Deepak,
in a nutshell, REST in an architectural style which helps your application make the most of the Web. The term was coined in the thesis by Roy Fielding called Architectural Styles and the Design of Network-based Software Architectures.
While a lot of REST services use HTTP and JSON, they are not limited to the aforementioned protocol and format. To tell whether a service is RESTful or not, one can use the so-called Richardson Maturity Model. The services that are not at the level three of the model are sometimes called RESTlike.
First of all, REST services are stateless, that is if you receive a huge list from the server, which is paginated, such as a list of books from the Amazon, the page you are on isn't stored at the server side, it is the responsibility of the client to inform the server about the next page's number. Also URIs are used to identify resources, e.g. each book's description can be retrieved using its unique URI, and HTTP methods such as GET and POST are used to work with resources, for instance, the former can be used to retrieve the book info and the latter to add a new book.
The crux of the style is a concept called Hypermedia As The Engine Of An Application state(HATEOAS). A simplistic explanation of what it is could be that the representations of resources (book info can be in JSON, XML, HTML etc.) should use hyperlinks to make those representations self-describing, e.g. if the book info can be edited, the link to do so should be added.
There are various proposals how to add hypermedia to representations. One possible format is Hypertext Application Language (HAL). Others include but not limited to JSON API, JSON-LD, UBER.
Personally I ventured to elaborate on the topic in my blog:
What is REST?
REST: Uniform interface
Introduction to Hypertext Application Language (HAL)
Regards, Dmitry
In an effort to grasp the underlying purpose of a RESTful API, I've begun delving into HATEOAS.
According to that wikipedia page,
A REST client needs no prior knowledge about how to interact with any particular application or server beyond a generic understanding of hypermedia. By contrast, in a service-oriented architecture (SOA), clients and servers interact through a fixed interface shared through documentation or an interface description language (IDL).
Now, I don't really understand how that's supposed to work, unless there exists prior knowledge of what is available in an API, which decries the stated purpose of HATEOAS. In fact, tools such as Swagger exist for the express purpose of documenting RESTful APIs.
So while I understand that HATEOAS can allow a webservice to indicate the state of a resource, I am missing the link (haha) demonstrating how a client application could possibly figure out what to do with the returned follow-up links in the absence of some sort of "fixed interface".
How is HATEOAS supposed to accomplish this?
You're confusing things. Tools like Swagger don't exist for the express purpose of documenting RESTful APIs. They exist for the express purpose of documenting HTTP APIs that aren't RESTful! You need tools like that for APIs that are not hypertext driven and focus documentation on URI semantics and methods instead of media-types. All those fancy tools that generate lists of URIs and HTTP methods are exactly the opposite of what you are supposed to do in REST. To quote Roy Fielding on this matter:
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.]
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
HATEOAS doesn't preclude the need for all documentation. HATEOAS allows you to focus your documentation on your media-types. Your application is supposed to conform to the underlying protocol -- HTTP, most of the time -- and the authoritative documentation on that protocol is all your clients should need for driving the interaction. But they still need to know what they are interacting with.
For instance, when you enter Stack Overflow, you know there are users, questions and answers. You need documentation on what exactly are those things, but you don't need documentation detailing what a click on a link or a button does. Your browser already knows how to drive that, and that's how it works everywhere else.
To quote another answer, REST is the architectural style of the web itself. When you enter Stack Overflow, you know what an User, a Question and an Answer are, you know the media types, and the website provides you with the links to them. A REST API has to do the same. If we designed the web the way people think REST should be done, instead of having a home page with links to Questions and Answers, we'd have a static documentation explaining that in order to view a question, you have to take the URI stackoverflow.com/questions/, replace id with the Question.id and paste that on your browser. That's nonsense, but that's what many people think REST is.
There are various answers to this question depending on the level of autonomy of the client interacting with the service ...
Lets first look at a human driven client - the browser. The browser knows nothing about banks, concerts, cats and whatever else you find on the net - but it certainly knows how to render HTML. HTML is a media type with support for hypermedia (links and forms). In this case you have a perfectly working application with a client that only understands generic hypermedia. The "fixed interface" here is HTML.
Then we have the autonomous clients or "scripted" clients that are supposed to interact with a service without human interaction. This is probably the kind of client you are thinking of when comparing REST to SOA(P). You could find such clients in integration scenarios where two independent computer system exchange data in some predefined way.
Such autonomous clients must certainly agree on something in order to interact with each other. The question is what this "something" is or is not.
In a service oriented architecture the clients agree on specific URLs/endpoints and specific "methods" to invoke on those endpoints (RPC) - this adds coupling on the URL structure used. It also forces the client to know which method to call on what service - the server cannot change URLs and it cannot move a "method" from one service to another without breaking clients.
REST/hypermedia based systems behaves differently. In such a system the client and server agrees on one common entry URL where the client can lookup (GET) a service document, at runtime, describing all the possible interactions with the server using hypermedia controls such as links or forms. These hypermedia controls informs the client about how to interact with the service (the HTTP method and payload encoding) and where to interact with the service. Which in essence means we do not have "a service" anymore but possibly many different services as the client will be told, at runtime, where and how to interact with them.
So how does the client know which hypermedia controls it should look for? It does so by agreeing on a set of identifiers the server will use to identify the relevant controls. For links this is often referred to as "link relation types".
This leads us to what kind of "something" it is that servers and clients agree on - it is 1) a hypermedia enabled media type, 2) the root service index URL, 3) the hypermedia control identifiers and 4) the payload expected for each of the controls. At runtime the client then discovers the remaining URLs, HTTP methods and payload encoding (such as JSON, XML or URL-encoded key/value pairs).
Currently there are a small set of general purpose media types for hypermedia APIs - Mason, HAL, Sirene, Collection JSON, Hydra for JSON-LD and probably a few more.
If your are interested then I have covered this topic in various blog postings:
The role of media types in RESTful web services
Media types for APIs
Selling the benefits of hypermedia in APIs
Hypermedia API documentation example
RESTful resources are not typed
In learning about REST architecture, I've noticed that Hypermedia seems to be an important part of the uniform interface constraint to become RESTful; however, I'm having a hard time understanding how this concept of hypermedia is to be consumed by a client based off of the definition of hypermedia found across the web.
From what I understand about REST, hypermedia is/are basically the links that are provided to a client in a rest response containing the representation of a resource (so that the client only has to know about the base entry point url to a REST service). The links are essentially there to help the client know what options it has regarding the representation it received (for example, if I request the /children/ resource, I might receive an xml list of children that also contains links to /children/youngest, /children/oldest/, children/create, etc... This is exactly what i have a hard time understanding... Why does the server have to return these "hypermedia" links to the client? Shouldn't the client have already known about those links? The client isn't going to read the links on its own and follow them correctly... Somebody has to write client code (html and/or javascript for example) beforehand. What good do these links do for the client if the client should have already known about them? What am i missing?
Hypermedia is indeed an important part of creating RESTful interfaces. However, I see a full hypermedia client (sometimes referred to as HATEOAS) as just a point on the spectrum of becoming more RESTful. The Richardson Maturity Model describes 3 steps to becoming more RESTful and I've found these as good guidelines when considering how much of a RESTful patten to adopt on particular projects.
IMO, the best example of a full hypermedia client is a web browser. The web browser understands that the html <a href> tag represents a link. The key to a link is that a user can discover functionality as they move through their journey. So, when designing a RESTful API, the same principle can be applied.
Why does the server have to return these "hypermedia" links to the
client?
So, one reason is that clients (if written to expose links) can allow state transitions to be discoverable.
Another benefit to using links is your API becomes responsible for the structure and data of each link. So, the server-side API is generating the links for each request. This means that the server API can make changes (version or structure) to the links without breaking the client.
You can build a RESTful API without links (Richardson Level 2), but then what if you want to change the URL for one of your API requests? You need to either implement a versioning strategy (through the url or headers) or you need to create a new url for the new feature. Through time, this can get out of hand.
Think about how browsing a web-page works. REST is very similar (although you're actually describing a related topic HATEOAS). The intent is that your client will retrieve the initial data, then have some way of deciding whether or not to request the referenced data. In a browser, some references (such as css, javascript, images) are immediately requested, and others, such as hrefs, are simply displayed to the user, and only retrieved if the user chooses to click the link. The same is true of your REST client -- you will decide for yourself, based on your requirements, which references to automatically request, and which to display to a user for decision making.
If you have an app that shows a person, along with their address, then your app would be written to automatically find the address reference in the person data and retrieve it. If your app shows a person and an option to show related data, then you'd show the person along with hyperlinks (or something similar) that allows the user to choose to retrieve and display the address data.
The issue really comes when you think about how the client visually represents the information it is retrieving. For this, the REST style suggests that you should allow the server to return javascript to dynamically parse the new data (for example, the address in my example above). Maybe the returned data also contains css-like references that will help. Maybe it'll contain javascript links to allow dynamic user interaction (which sounds dangerous to me, but what the hell, it works for the web).
Fielding defined the uniform interface constraint in order to decouple the clients from the implementation of the service. This is just the same as defining a new interface in any oo language. You define it to decouple a class from the implementation of its dependency.
To decouple the client from the URI structure you need links in the response, which contain semantic annotation and the URI. So your client can decide which link to follow based on the semantic annotation (e.g. link relation or a term in a related RDF vocab). This way it does not need to know anything about the URI structure.
You need to decouple clients from the implementation details of the services to make them reusable. At the end you can create general clients like a web browsers today. The difference that these clients will understand what they do, so they won't necessary rely on humans.
What good do these links do for the client if the client should have already known about them?
They make state transitions more directly a part of the interface. They tell the client whether these links or state transitions are available to be used (or not if they are not present!) in the current state.
If the client did not take notice of this, it could potentially still try to generate and follow an URL for an option (state transition) that was actually not available. It might be necessary to replicate the logic to determine what is possible in a particular state on both sides to be sure to avoid this.
If an invalid link/state transition is attempted, the server should report back an error.
On the other hand, if the client never allowed generating/following a link not provided by the server, it could have awareness and provide feedback about the problem earlier (normally resulting in a clearer situation or error message), and while the server should handle the invalid request correctly, in case it didn't it would be less of a problem as it is much less likely to happen in the first place.
Something like this.
var discountDetails = new AddDiscountForm()
{
promotionId = 123456,
discountType = "Promotion",
discount = UnitValue.FromFloat(14.00)
};
await journey
.SelectRoot()
.SelectRelation("product-finder", new { barcode = "23409-23097" })
.SelectItem(0)
.SelectRelation("add-discount", discountDetails)
.RunAsync();
In fact I took the idea from my response and built it.
https://github.com/lukepuplett/surfdude-csharp
Roy Fielding writes
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.
How do you do this for system-to-system interfaces? Say the client wants to create an order in the server at http://my.server.org How is it supposed to learn that for creating an order it is supposed to use the url http://my.server.org/newOrder and not http://my.server.org/nO or anything else?
For a human interface (i.e. browser), I guess the server would provide some form of link (possibly in a form element) and the text around and in that link would tell a user which of the forms on that page is the correct one for creating an order (as supposed to creating a user or navigating to some search result)
What are the mechanics used for implementing this on the client side? And also: are they actually used or does the majority of people just hardwire the urls into the client?
How do you do this for
system-to-system interfaces? Say the
client wants to create an order in the
server at http://my.server.org How is
it supposed to learn that for creating
an order it is supposed to use the url
http://my.server.org/newOrder and not
http://my.server.org/nO or anything
else?
It doesn't learn. Machine clients, generally, can't "learn". Not yet at least, we're still pre-Skynet. You have to "teach" them.
But what the key is that you don't teach them URLs. You teach them relations.
Consider, in HTML...
<a rel="order" href="http://my.server.org/newOrder"/>
and
<a rel="order" href="http://my.server.org/nO"/>
You'll notice that the rel is the same, "order", but the URL is not.
In a "perfect" world, you system will have a single entry point, say, http://my.server.org/ and from there the client can find all of the rels that it needs to know about.
In practice, many systems have several "well known", and defined entry points from which the client can start, just as an expediency so the client does not alway have to start at the root of the system. These well known entry points have an implied commitment from the provider that these URLs won't be changing any time soon. That they're long lived, and the server will support them very well.
But once passed the entry point, any URL you find likely does not have such a promise behind it. The URL can be a one use only URL. It could be directed to different machines for, say, load balancing. Who knows. But as a consumer of the service, you really don't care what the URL is, you only care about the relation. The relation tells you the detail of the URL to use.
The documentation of your hypermedia API explains how to apply the uniform interface to each of the rels that your client will encounter. The client can't "intuit" that either, it has to be taught.
Basically, by teaching the client how to navigate the relations that it will or MAY find in the payloads it processes is how the client manipulates the hypermedia API. The payloads contain sign posts to show the way, but the server dictates where those sign posts go.
As for how often it is used, in the machine to machine world, likely not very much. Most systems aren't large enough where the URLs change enough to matter, and the clients are so few that changing the clients is not a significant burden. So most just hard code away.
But then, in the end, you just have bad clients. Nothing a REST system can do with a bad client. It can't tell them apart at runtime anyway.
No matter how you publish an API (to be consumed by machines), it is possible to make breaking changes.
When wrapping your API behind a UI (such as HTML forms), you have the freedom to change the URI without breaking the user, but that is because the user is consuming an abstraction you provided. Change the URL schema without changing your form, and you'll still break the client.
A couple ways to avoid breaking machine clients (basically, supporting backward-compatibility):
Build in some sort of URL versioning
Do redirection from old URL schemas to your new schema
We've quite sucessfully approached it the following way: expose a WADL file at the very root URL of the application describing the media types as well as where to find links in it and their semantics. I know this (WADL) is something seen critical by some in the REST community but I always felt intimidated by very URL focus of WADL only. Beyond all the religious debates we liked having a well defined way of documenting representations. There is a way to get around the URL focus of WADL and rather point out where links can be found in the representation and then rather document that. See that blog post (currently down because of maintenance so you might want to look at it in the Google cache) for details on the approach.
This results in only a single URL to be known by the client as he can find out about it accessing the WADL, and from then on just learn about the representation and where to find links, what HTTP method needs what parameters when being invoked and so on.