| /////////////////////////////////////////////////////////////// |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| /////////////////////////////////////////////////////////////// |
| |
| [[library-rest-client-primer, HATEOAS Primer]] |
| = ReST - HATEOAS Primer |
| |
| The Zestâ„¢ ReST Client implements HATEOAS (Hypermedia As The Engine Of Application State) to the full extent intended |
| by Roy Fielding. The ReST Client Library enables the creation of HATEOAS applications that are NOT using the URL space, |
| and it is NOT about doing RPC calls over HTTP using a common exchange format (like JSON). |
| |
| The <<library-rest-server>> is a corresponding library for creating usecase-driven ReST servers, and with that the |
| corresponding client becomes very thin, as all business rules remain on the server where they belong. |
| |
| *The main point is to support exposing REST resources that focus on use cases and hypermedia.* |
| |
| On the client, we have been thinking a lot about what Roy wrote in his thesis, which boils down to "client makes GET |
| request, based on relation of link invoked and response (headers+hypermedia) make a decision, and then follow links or |
| invoke forms to perform state transitions". |
| It's a state machine. |
| This is different from your average REST client today in that this model explicitly says that you need to do a GET |
| first (otherwise you have nothing to react to), that the "rel" of the link you followed is important (otherwise context |
| is unknown), and that the client should not make assumptions about what comes back (otherwise you cannot deal with |
| exceptions, on system and application level). |
| |
| The current REST client approach which is imperative: |
| [source,java] |
| -------------- |
| result = client.get(somelink) |
| -------------- |
| does not allow for any of the above. Instead, the client code should first register handlers for what to do in various |
| circumstances, and then simply perform one operation: "refresh". This will trigger the first GET to the bookmarked URL, |
| and after that the handlers will do all the work, based on the result. A handler may continue the work by invoking new |
| requests, or it may abort. "refresh" does not return any value, and usually does not throw any exceptions. |
| |
| Example: |
| [snippet,java] |
| ----------- |
| source=libraries/rest-client/src/test/java/org/qi4j/library/rest/client/docsupport/RestPrimerDocs.java |
| tag=1 |
| ----------- |
| |
| The client first builds up the set of handlers, and describe what they should react to. The client then invokes |
| "refresh" which will trigger the first GET on the bookmark URL. This will return a representation of that context as a |
| Resource, and the handler for that is invoked. This then invokes the link with relation "querywithoutvalue" with no |
| input (no request parameters needed). The result of that is then handled by another handler, and the invocation of |
| "refresh" then returns successfully. Note that the first handler may not directly handle the "result" of |
| client.query("querywithoutvalue, null) as it cannot be assumed what happens next. All you know is that you are |
| following a link. |
| |
| On crc (ContextResourceClient) it is also possible to registers handlers that are always applied, such as error |
| handlers. Here is the setup of crc: |
| |
| [snippet,java] |
| ----------- |
| source=libraries/rest-client/src/test/java/org/qi4j/library/rest/client/docsupport/RestPrimerDocs.java |
| tag=2 |
| ----------- |
| |
| These general handlers cover what to do for login and error handling, for example. |
| In the traditional REST client this is not as easy to do, as you are more or less assuming a "happy path" all the time. |
| In the above scenario there could be any number of steps between doing "refresh" and getting to the meat of the use |
| case, such as doing a signup for the website, login, redirects to other servers, error handling and retries, etc. |
| It becomes possible to blend general application and error handling logic with use case specific handlers. |
| |
| That's basically it. This is where I want to go with support for REST, as a way to truly leverage the REST ideas and |
| make it very easy to do REST applications *and* clients based on Zest, by keeping the application logic on the server. |
| In the long run there would also be a JavaScript version of the client, with the same characteristics, so that you can |
| easily build a jQuery UI for Zestâ„¢ REST apps. |
| |