Monday, August 08, 2011

Some progress with REST for RHQ and new questions

As written some time ago on the rhq-devel mailing list, I've started implementing a RESTful interface for RHQ. A page on the RHQ wiki shows the requirement and some progress about the implemented API. Development currently happens in a personal feature branch in order to have some code to play around and gather some experience from.

One thing that I found out over the weekend is that at least with JAX-B setting up the interface and REST resource classes is far from trivial and I have been surprised a lot by interesting error messages.

Anyway, the current state of the API is already in a somewhat usable shape (mostly read-only at the moment). The implementation has been done via RESTeasy (RE). Security integration with the RHQ security model is also done and the session bean methods can just use a Subject called caller.

So, having solved some stuff rises even more questions:

  1. Would stuff get easier when not trying to support XML, but only Json?
  2. How to use much / more of the original RHQ domain model without running into LazyLoadExceptions all over the place (RE runs as a servlet to do the marshalling - at this point in time the connection to the entity manager is already closed).
  3. How to implement linking between related classes / concepts. E.g. a Resource can have Alerts. Now instead of embedding Alert elements when returning a Resource object, I would like to at most have a list of Links to /alert/{id}. I feel that the answer may have to do with the next question
  4. In RHQ we often pass just primitive ids around (e.g. int resourceId) How can easily turn them into a link to the target Resource (given that Resource lives below /resource/{id})
  5. In the Atom-PUB linking I would add links to sub-resources like e.g. /resource/1234/availability or /resource/1234/schedules without the need to first obtain those values from the database.
  6. Does it make sense to transfer date/times as long? Especially as Json seems to have some issues there. Complex date strings require a lot of processing on server and client.
  7. Is there a preferred way to expose id elements ((XML) attribute, element, not at all? With Atom-PUB links present, I think the id would not need any special treatment at all, as it is available in the URI of the resource and in the link.

A part of the solution to questions 3+4 seem to be to only use Objects in REST domain objects, as the marshalling will skip elements where the corresponding object is null, so for e.g. the parent Resource it is enough to initialize its resource with the Resource id to only include this, but not all the other fields that should then be obtained from their real URI.


But then I am not sure how much my ideas are RESTful at all :-)

I would love to get some feedback here.


Charles Crouch said...

Have you seen this

Jeremy H said...

I am comforted to see the same questions I have asked myself when doing some REST api work! I will throw out some ideas we have bounced around in solving these issues - for what its worth.

Re 1: I too have found the XML parsing to be problematic when using RE. 80% of the errors we hit are Resource parsing exceptions (although I think JSON may have the same issue - just in different ways).

Re 2: We solved this by doing a "short" version of the objects. So we would have a CustomerShort and a Customer. The customerShort would just be used when a few fields were needed instead of the whole object. That we we don't need to do a lazy load - just pull either the short or full objects.

Re 3: The server is supposed to be in control of the linking - and you are "supposed" to sending links with every object (which state transitions you can make). So if you ask for resource, you should get a list of linked alerts (or maybe a portion of them or starting page for them if the list is long).

Re 4: The item's representation can include a "self" link (including a link to the "full object" from the "short object". I would contend that if you are using ints for resourceId, you are doing things right. You should have some json/xml representation of even an ID so that links can be added.

Re 5: You are free to create whatever resources you want! You can create a resource that is just a "starting page" for the resource - without having to list all the values. That way you can get to the information, but don't have to incur the roundtrip lookup. Use the representations to your advantage - you have total control over those!!

Re 6: I would NOT use longs for date/times. For XML and JSON you should use the standard date and datetime formats defined in the spec (ISO 8601). It drastically improves interoperability and allows a consistent format. Both .net and Java clients have built in parsers for this format (and it behaves nicely with timezones).

Re 7: You are correct that the atom-pub links have the ID in the URLs, but what a pain to have to parse that - and if you are doing REST properly, those can change on a whim! So you parser would have to be sophisticated. It is not much overhead to include the element in all resources. I don't know that you need to specially identify it in the list since they should not be used to generate the link (the server should control the links if you are really doing REST).

Anyway, these are all questions I have had too - so it actually makes me think I am not on my own island. You may have better/different solutions as many of these may be specific to what you are doing, but these were our ideas!