2

Does it make sense to serialize JSON in relational format? E.g. suppose I have a many-to-many between Order and OrderItem, with many items being shared between orders. Then in the JSON I could put just the OrderItem id's in the Order object, then under that have a list of OrderItems with the expanded OrderItem objects. The advantage of this is that I don't have redundant data and I shorten the amount of data sent over the wire. On the other hand, compression algorithms might make this irrelevant, and there is more work to do expanding out the objects afterwards.

Just wondering what is standard practice: if people feel that JSON should always be in denormalized format, or if a relational format can sometimes make sense. Assume an RDBMS on the backend.

James McCabe
  • 1,879
  • 2
  • 15
  • 22

1 Answers1

3

I feel that the answer to this question, is a classic StackOverflow-special - “it depends"

As you said, the primary focus for this is returning data for a view, I would make the returned JSON payload contain everything needed to render that view.

The advantage of this is that I don't have redundant data and I shorten the amount of data sent over the wire. On the other hand, compression algorithms might make this irrelevant, and there is more work to do expanding out the objects afterwards.

Yes, this dependent on how “heavy” the embedded elements are, however. If your view contains many “heavy” elements, that are not always required to be shown (and the user would not mind waiting for these details to appear) then you could of course return an identifier for that data, to be returned (by subsequent call)

In this instance, you could return a cut down version of orderItems, optionally with a link to retrieve their full details.

Something like:

{
  "id": "1",
  "orderItems": [
    {
      "id": "a",
      "title": "A product",
      "fullDetails": "http://www.url.com/endpoint/order/1/items/a"
    },
    {
      "id": "b",
      "title": "Another product",
      "fullDetails": "http://www.url.com/endpoint/order/1/items/b"
    }
  ]
}

This is bordering on HATEOAS With HATEOAS, the output makes it easy to figure out how to interact with the service without looking up a specification or other external document, or embedding the entire document

Another consideration in your case, is caching. Although I don’t know your domain, I suspect that Orders and their OrderItems may not change often, but may be accessed several times. In this instance, you can cache (locally, or server side) the whole JSON document, which would make retrieving the same data next time a lot more efficient.

Personally, I would usually return view models that are a full model of the current view.

Some links on HATEOAS

http://spring.io/understanding/HATEOAS

http://timelessrepo.com/haters-gonna-hateoas

https://blog.apigee.com/detail/api_design_honing_in_on_hateoas

Alex
  • 37,502
  • 51
  • 204
  • 332
  • Very interesting. I hope other people can comment too. How common is this approach of using other JSON endpoints for dependent objects? Is this architectural style documented elsewhere? – James McCabe Apr 04 '14 at 07:31
  • I've added some links on HATEAOS – Alex Apr 04 '14 at 07:40
  • The practical problem with HATEAOS seems to be that it can lead to an explosion of network calls. So you would want to do a lot of caching on the browser side. Are there any (JavaScript) frameworks that have good support for caching dependent objects in JSON? And flushing stale data and so on? This seems like it could be a big area now or in the future. – James McCabe Apr 04 '14 at 11:06
  • The 'trick' is as i said in my answer, to sculpt your json responses as view models for that view, to reduce network chatter - there are many methods of caching locally, local storage would be one - i would look into http://amplifyjs.com - but that's getting out of scope for your original question – Alex Apr 04 '14 at 21:14
  • I notice for the orderItems above, there is both an id and a link to fullDetails. Since the URI is unique, what about using that as an ID? Would that be more RESTful? – James McCabe Apr 08 '14 at 07:43
  • I guess you could, however, I would return the ID separately, as it is stored in your database, to allow you to do things like /order/56/comments - to navigate to order 56's comments (for example) – Alex Apr 08 '14 at 08:12