Domain specific media types and REST
Below is a thread posted to rest-discuss. I’ve reposted my response here for easy linking and reading.
http://tech.groups.yahoo.com/group/rest-discuss/message/17650
Daniel Roussel posts:
I’ve been reading a lot about how to do “proper” REST this week and the more I read, the more I’m lost, especially the HATEOAS part I fear.
First, to give some context, the company I work for develops mobile applications for clients. Most of the time, they want to get an iPhone native application, an Android application and a traditional Web based Application to cover the other mobile phones out there.
The way we are currently doing things is the good old (bad?) RPC over HTTP way. We define a bunch of URI which are coded inside the different apps, we exchange data as JSON, etc. This week, trying to do things in a better way, I’ve begin a more serious study of REST and how to do it properly.
What I really can’t wrap my head around is how, technically, have HATEOAS in a native application? I mean, when building a native application, I have tables to display lists, buttons to do some things, etc. My understanding is that all those should be displayed based on the data (hypermedia) received from the server. Is that right?
A concrete example would be a hotel room rental service. The person would open the application and have fields to enter the from/to dates. It would then tap a “Get Available Rooms”. The app would call the server and get back a list of rooms along with prices and other details. From there the person could select one room and rent it.
The RPC way of coding this is obvious to me but I have no idea how I’d do that in a proper REST way! What bugs me is that every way I look at it, the client application would still be tightly coupled to the service. I understand how I would only need to GET the http://rent-a-room.com URI hardcoded and then in the response I would have the http://rent-a-room.com/available-rooms URI given. But… My application would expect each “call” to return some pre-defined data and “rel”, those can’t appear out of the blue?!
I guess what I’m trying to say is that both the business process and the data exchanged must be known to my client application at the moment of coding it, and those can’t change without breaking existing clients. But reading about REST, every is talking about loose coupling and not breaking clients… I just don’t see it.
What am I missing?
Thanks a lot and sorry if it is a stupid question!
Daniel, Here are 3 ways you might use self-descriptive messages in your API
1) Create many domain specific media types (one for each view)
Content-Type: application/rent-a-room+xml
2) Create one domain specific media type
Content-Type: application/vnd.hotels.com+xml
3) Create zero domain specific media types
Content-Type: application/json Link: </schema/rent-a-room>; rel="describedBy"
All three of these approaches could be seen as satisfying the self-descriptive messages constraint.
If you create many DSMs (domain specific media types), your application might bind the media type to the view class via some sort of client-side configuration.
"application/rent-a-room+xml" => RentARoomView
If you create one DSM, your media type might specify the semantics by which a representation specifies details about itself which could be used in rendering the representation in a GUI.
{"_type": "rent-a-room", ... }… which you might then bind to a view …
"rent-a-room" => RentARoomView
If you create zero DSMs, your application might bind the value of the describedBy link header to a view in the gui.
"/schema/rent-a-room" => RentARoomView
–
An alternative approach would be to create one DSM with a richer semantics which would effectively allow you to compose the interface from the server side using code-on-demand and/or more granular views
{"_links":[
{"rel":"view","type":"text/javascript","href":"/views/RentARoomView.js"}
{"rel":"commentable","type":"text/javascript","href":"/attributes/commentable.js"}
]}This Code-on-demand approach would take greatest advantage of the constraints of REST to create a highly evolvable service by never binding anything directly to a view class within the application. Instead, your application would become a user agent, parsing representations and fetching additional computational resources as necessary to render the view.
Code-on-demand may be significantly less feasible if your client is written in object C, but perhaps it’s something to think about. The embedded links might not be javascript or CSS, but perhaps some other language used for GUI composition, such as XUL or a simple DSL.
Finally I’m sure it goes without saying that whatever way you wind up rendering a representation for a view, the UI would contain links which you would click to navigate to new screens which are built using the data and metadata from the representation of the resource identified by the link.
And there you have a few takes on creating an engine of application state with self-descriptive messages and code-on-demand.
Comments(0)