Normalized Entities

76 views
Skip to first unread message

Michael Tiller

unread,
Nov 16, 2016, 4:03:35 PM11/16/16
to Siren Hypermedia
I'm using Siren pretty successfully in a library I'm developing.  But one thing that troubles me is the fact that I can get deeply nested.  I want the nesting (it conveys structural information that is important about the relations between the resources).  But what I don't really like is nested of the embedded resources.

I've seen a similar discussion somewhere before (HAL mailing list).  But I just wonder whether it would make more sense to have all relations be just links and entities be the actual expanded versions of resources (even for deeply embedded links) keyed off of the URI, e.g.,

{
  
"class": [ "order" ],
  
"entities": [
    
{
      
"class": [ "items", "collection" ],
      
"rel": [ "http://x.io/rels/order-items" ],
      
"href": "http://api.x.io/orders/42/items"
    
},
    
{
       
"class": [ "info", "customer" ],
       
"rel": [ "http://x.io/rels/customer" ],
       
"properties": {
         
"customerId": "pj123",
          
"name": "Peter Joseph"
        
},
        "entities": [
          "class": [ "order" ],
          "rel": [ "http://x.io/rels/order", "http://x.io/rels/lastOrder" ],
          "href": "http://api.x.io/orders/43",
          "properties": {
             "date": "November 10, 2016",
          },
          "links": [
            { "rel": [ "self" ], "href": "http://api.x.io/orders/43" },
            { "rel": 
"http://x.io/rels/order-items" ], "href": "http://api.x.io/orders/43/items" },
            { "rel": [ "previous" ], "href": "http://api.x.io/orders/42" },
          ]
        ]
        
"links": [
          
{ "rel": [ "self" ], "href": "http://api.x.io/customers/pj123" }
        
]
     
}
   
],
   
"links": [
     
{ "rel": [ "self" ], "href": "http://api.x.io/orders/42" },
     { "rel": 
"http://x.io/rels/order-items" ], "href": "http://api.x.io/orders/42/items" },
     { "rel": [ "previous" ], "href": "http://api.x.io/orders/41" },
     
{ "rel": [ "next" ], "href": "http://api.x.io/orders/43" }
   
]
}

would then become:

{

  
"class": [ "order" ],
  "representations": {
      "class": [ "items", "collection" ],
    },
      "class": [ "info", "customer" ],
      "properties": {
        
"customerId": "pj123",
       
"name": "Peter Joseph"
     
},
      "links": {
         { "rel": "http://x.io/rels/order", "http://x.io/rels/lastOrder" ], "href": "http://api.x.io/orders/43" },
      }
    },
      "class": [ "order" ],
      "properties": {
        "date": "November 10, 2016",
      },
      "links": [
        { "rel": [ "self" ], "href": "http://api.x.io/orders/43" },
        { "rel": 
"http://x.io/rels/order-items" ], "href": "http://api.x.io/orders/43/items" },
        { "rel": [ "previous" ], "href": "http://api.x.io/orders/42" },
      ]
    }
  },
  "links": [
     { "rel": [ "http://x.io/rels/customer" ], "href": "http://api.x.io/customers/pj123 },
     { "rel": [ "self" ], "href": "http://api.x.io/orders/42" },
     { "rel": "http://x.io/rels/order-items" ], "href": "http://api.x.io/orders/42/items" },
     { "rel": [ "previous" ], "href": "http://api.x.io/orders/41" },
     
{ "rel": [ "next" ], "href": "http://api.x.io/orders/43" }
  ]
}

To me, this seems a lot easier to deal with.  First, you don't have an issue with infinite recursion.  Also, the depth of the structure is bounded without limiting the expressiveness.  What I mean by that is that you don't have resources embedding other resources.  You all properties, classes and links are either at the root level (if they apply to the requested resource) or the are included in the values of the "representations" hash.  This also has a "compression" effect because it is possible that a resource might be embedded at multiple places within the hierarchy.  In Siren, you could end up with repeated data.  But here, you would simply have multiple links, but only one representation.  Finally, this issue of embedded link subentities vs. links kind of goes a way here.

One concern some people might have would be what happens if the representations of the same resource are different at different places in the response.  In other words, what happens if an entity includes some fields in one location in this Siren hierarchy and others in other places in the Siren hierarchy.  In my current approach, this cannot happen because I use query parameters to control this (and, therefore, they would have different URLs).  But in general, when you assemble the values in "representations", you could simply merge the different representations as well, depending on your needs.

It is entirely possible I'm overlooking some drawbacks to this approach, but so far I don't see one.  It seems like this would actually be more compact, more regular and easier to traverse.

Comments?

Alex Soto

unread,
Nov 16, 2016, 4:15:57 PM11/16/16
to siren-hy...@googlegroups.com
sub entities don't need to be fully expanded.  I use linked entities regularly.


--
You received this message because you are subscribed to the Google Groups "Siren Hypermedia" group.
To unsubscribe from this group and stop receiving emails from it, send an email to siren-hypermedia+unsubscribe@googlegroups.com.
To post to this group, send email to siren-hypermedia@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/siren-hypermedia/398500c9-af41-4bc4-b97d-1e39477983b4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Michael Tiller

unread,
Nov 16, 2016, 4:30:15 PM11/16/16
to siren-hy...@googlegroups.com
Sure, I could use links or linked sub-entities.  But the use case I'm interested in here is one where I WANT the full representation (properties, title, class, links) for those resources.  So the question is really about a potentially better way (in my opinion at least) way of embedding that information that doesn't lead to arbitrarily deep structures.

--
Mike


Reply all
Reply to author
Forward
0 new messages