RESTful interfaces http://rest.elkstein.org/ (but not Section 11) http://net.tutsplus.com/tutorials/other/a-beginners-introduction-to-http-and-rest/ and for a laugh (or cry) : http://www.looah.com/source/view/2284 https://dev.twitter.com/docs/api/1.1
Other architectures are externally built or expanded Some applications provide a platform for development, and they do not ultimately know what kinds of tools will sit on their platform. Operating systems are obviously a massive example of this, and are totally geared to application-layer expansion (but obviously not optimised for OS expansion). But there are less enormous examples: plug in or extension architectures, (Eclipse, Chrome, Firefox) Server APIs (via RPC or RESTful interfaces)
Data over Tools (John Weigand -- living architectures podcast SE radio) tools are manipulating data (requirements, test cases, source code, etc). tools are interesting, but the data is MORE interesting, independent of the tools. Old view in software tooling: focus on the tools; the data is a side effect. New view: more attention to the data, and tools just facilitate data-manipulation. (point to debate: this is another version of OO!?)
Thinking in a RESTful way (John Weigand -- living architectures podcast SE radio) You need to look at things differently. The traditional framework solution focuses on the call chain much more centrally, and the data gets to be something that s carried along.! Whereas in RESTful approaches, the focus is on understanding the concepts, and making sure you get the right resources in place, and that s the central focus. So yes, it s a different mindset. And it takes practice. But the importance of having a good interface applies just as well in both cases.
Neutral RESTful architecture; OO tools (John Weigand -- living architectures podcast SE radio) The Java language is going to continue to be valuable.! But in terms of establishing loosely coupled architecture, the boundary that you want when you re language neutral doesn t want to talk about inheritance.! It really wants to focus on the data and how does it connect. And then enable a range of ways for that data to be exposed.! So they re complementary: we don t try to have the whole world talk in terms of OO concepts, but in local toolkits, we still leverage that.
API for the CanaFind sys. CLIENT Camera GPS Finder UI Searcher UI ItemList=findItem(image,loc) submititem(image, loc) Finder API Searcher API Indexer/Tagger SERVER DATABASE This isn t an extensible ( living ) architecture BUT: We don t know what people who build the clients are going to do. We know they re constrained significantly (all they can do is submit items, and get lists of items) But there might be a lot they can do within those constraints. We might want to think of *all* the directions they can go, and provide an API that allows more freedom and extensibility.
This is an RPC approach CLIENT Camera GPS Finder UI Searcher UI ItemList=findItem(image,loc) submititem(image, loc) Finder API Searcher API Indexer/Tagger This approach involves Remote Procedure Calls Note that the calls are specialised verbs (submitimage( ), find( )) The data must be pre-defined, meaning we both the client and the server must agree on data types. SERVER DATABASE
RESTful Interfaces the web is an existence proof of a massively scalable distributed system that works really well, and we can take ideas from that to build integrated systems more easily. Martin Fowler "Representational State Transfer is intended to evoke an image of how a well-designed Web application behaves: a network of web pages (a virtual statemachine), where the user progresses through an application by selecting links (state transitions), resulting in the next page (representing the next state of the application) being transferred to the user and rendered for their use." - Roy Fielding
Another way: REST REpresentative State Transfer http://en.wikipedia.org/wiki/representational_state_transfer
The Basics request CLIENT SERVER response
If your Client is a browser CLIENT request response SERVER BROWSER URL HTML SERVER
If your Client is an Application CLIENT request response SERVER GET, POST, PUT, DELETE HTTP request APP RESTful URI SERVICE some structured data
REST principles Resources are identified by Uniform Resource Identifiers (URIs) Resources are manipulated through their representations Messages are self-descriptive and stateless Multiple representations are accepted or sent
RESTful APIs Instead of using application specific verbs, the operations are pre-set verbs from the HTTP operations: GET, PUT, DELETE, POST. RESTful APIs provide a uniform interface to a set of (typically) hierarchically arranged Resources (the nouns) Resources are located at URI s: Universal Resource Identifiers which are stored in Representations Requests are sent to the server, and the server responds with a text record that can be parsed into a response object.
The HTTP API HTTP provides a really simple set of operations GET (retrieve a resource) POST (store a new resource) PUT (store a resource at an existing URI) DELETE (remove a resource) Requests are sent to the server, and the server responds with a text record that can be parsed into a response object.
Overall architecture CLIENT GPS Camera Finder UI Searcher UI GET {image, location, radius} POST {image, location} Finder API Searcher API Indexer/Tagger SERVER DATABASE
Getting a web page: Cana Find Provides media type for message. Such as: text, html, structured data (xml...), images (jpeg...) GET /index.html 200 OK... Content/Type: text/html... <entire web page> RESTful SERVICE response codes such as: 200: OK 201: Created 400: Bad Request 404: Not Found 500: Internal Server Error content or payload of the message. In this case, a web page.
Using Parameters GET /photos?loc=49.2609...+-123.249...&radius=400 Cana Find 200 OK... Content/Type: xml... <photo> <id>1</id> <purl>/photos/1.jpg</purl> <loc> 49.2609...+-123.249</loc> </photo> <photo> <id>18</id> <purl>/photos/18.jpg</purl> <loc> 49.2609...+-123.249</loc> </photo> RESTful SERVICE
Using Parameters POST /photos data= {"loc"=49.26..+-123.249..., "photo"=...image data...} Cana Find 200 OK... Content/Type: json... {"id": 239877870, "lat":49.26.., "lon":123.249.., "purl":/photos/239877870.jpg } RESTful SERVICE
Client and Server (pseudo)code uri="/photos?loc=49.26..." response=open(uri).read() GET /photos?loc=49.2609...+-123.249...&radius=400 Cana Find photolist=xmlparse(response, "photo") foreach photo in photolist: dosomethinggood(photo) 200 OK... Content/Type: xml... <photo> <id>1</id> <purl>/photos/1.jpg</purl> <loc> 49.2609...+-123.249</loc> </photo> <photo> <id>18</id> <purl>/photos/18.jpg</purl> <loc> 49.2609...+-123.249</loc> </photo> RESTful SERVICE r=elisasparserequest($_get) if ($r.resource=='photos'): //find all relevant photo objs plist=canasearch(r.loc, r.rad) header="200 OK" content=plist
Principles... Safe systems: HTTP is a robust protocol. To maintain that robustness, GET, PUT and DELETE operations must be idempotent. meaning: you can run them again and again with no duplication of functionality. Stateless: All client state remains on the client. The server doesn t retain any state about the client. Connectedness: Do not force the client to recall internally the structure of the resources on the server. Provide relevant links inside returned resources. URI design: URIs represent nouns not verbs. Put resources there, not behaviour. Each resource has four behaviours: GET, PUT, POST, DELETE.
GET; PUT; DELETE: Idempotence is Important! Even if you don t get a response from an idempotent operation, you can safely perform it again. https://mathieu.fenniak.net/wp-content/uploads/2013/05/idempotent_prototype_4.html#
Canafind resources /photos: GET: returns a list of photo objects DELETE: you can t do that. Bad request: 400 PUT: you can t do that. Bad request: 400 POST: inserts a new photo into photos.! /photos/id: GET: returns the photo resource DELETE: deletes the photo resource PUT: you can t do that. Bad request: 400 POST: you can t do that. Bad request: 400 http://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/ 200 OK Everything is working 201 OK New resource has been created 204 OK The resource was successfully deleted! 304 Not Modified The client can use cached data! 400 Bad Request The request was invalid or cannot be served. The exact error should be explained in the error payload. E.g. The JSON is not valid 401 Unauthorised The request requires an user authentication 403 Forbidden The server understood the request, but is refusing it or the access is not allowed. 404 Not found There is no resource behind the URI. 422 Unprocessable Entity Should be used if the server cannot process the enitity, e.g. if an image cannot be formatted or mandatory fields are missing in the payload.! 500 Internal Server Error API developers should avoid this error. If an error occurs in the global catch blog, the stracktrace should be logged and not returned as response.
CanaFind API spec GET PUT POST DELETE /photos (id, loc, rad) returns of photo objects s/f: 200/404 400 (bad request) (id, loc, rad) inserts new photo into /photos/ s/f: 200/404 400 (bad request) /photos/id (id, loc, rad) returns photo resource s/f: 200/404 400 (bad request) 400 (bad request) deletes photo resource s/f: 200/404 /photos/ searchjob/ 400 (bad request) 400 (bad request) (string) returns a job id for the search s/f: 202 (accepted) 400 (bad request) /photos/ searchjob/id returns currently available results for job 400 (bad request) 400 (bad request) deletes the search job (cancels search) s/f: 200/404
Twitter s RESTful(???) API could have used DELETE request DELETE statuses/id/ could have used DELETE request DELETE direct_messages/id/
So remember: All resources must elegantly handle: GET/PUT/POST/DEL Resources are nouns, not verbs Don t ask the client to remember the internal server structure send back links in your XML/JSON if you need the client to surf over to another resource location Use the most precise possible response code Make sure GET/PUT/DEL are idempotent All behavioural state must remain client-side.