Modeling a more complex entity relationship in a RESTful way (boxes and nodes)
Asked Answered
O

1

14

Here's an example to set up my question. I have a model which contains 'boxes', and they have a REST endpoint:

/boxes, /boxes/{boxId}

This model also contains 'nodes':

/nodes, /nodes/{nodeId}

Nodes can sit on the borders of boxes, and this is a many-to-many type of relationship. Having one node sit on multiple borders is a way to indicate that those borders (partially) overlap, but nodes also have other purposes.

a quick visual example of boxes and nodes

I'm trying to determine how to model this in an non-surprising, RESTful way. I can see a couple of ways to do this. But I'm not sure which I should use:

  1. Model /borders as a fully fledged entity type with its own endpoint. Have boxes reference four borders (top, bottom, left, right). Have borders reference a list of nodes. Have nodes reference a list of borders.

  2. Model /boxNodeRelationships with its own endpoint, and have each such relationship point to a box, a node, and contain a 'border' field (an enum with four options).

Both are similar, and rather 'heavy' for their purpose. The alternative is to be a bit more ad-hoc:

  1. Give boxes a list of { border, node } objects. Give nodes a list of { box, border } objects. These objects would be returned from GET calls and expected from POST/PUT calls, but would not be fully fledged types with an endpoint.

I'd like to know how a RESTifarian would solve this, as well as hear some pros / cons of these approaches. I'd also like to know if there are other approaches that are fundamentally different.

Orbiculate answered 1/9, 2015 at 20:9 Comment(2)
To find the most optimal way to model the API you need to understand use cases for which it's most likely to be used.Chuckwalla
@astr: We need all kinds of ways to approach this data, really, e.g. getting all nodes on a border, getting all boxes connected to a node, getting all boxes connected to another box, etc. So I'm wondering about the most elegant RESTful API that provides full access to the data.Orbiculate
C
4

I would create 3 entities:

  • Box
  • Border
  • Node

And the relationships:

  • A Box can have n Borders
  • A Border can have n Nodes

So you could address them:

To get the first node: /boxes/1/borders/1/nodes/1

You could have some logic:

if /boxes/1/borders contain /nodes/1 and /boxes/2/borders contain /borders/1 then they intersect

And so on.

Crispi answered 3/9, 2015 at 21:5 Comment(6)
This is indeed one of the possibilities I considered and listed in my question. But what is the advantage of this approach over the other approaches? Would this be 'standard' in some sense?Orbiculate
How is option 2 against HATEOAS? It's actually a common technique for many-to-many relationships, as far as I can tell. The disadvantage of option 1 is that 'border' is a relatively useless entity; an extra redirection just for the purpose of solving this problem. They all have pros and cons. I was hoping for an expert's comparative analysis.Orbiculate
In my opinion relationships shouldn't be exposed as web service endpoints as separate entities (/boxNodeRelationship). These are not entities per se. These are not business objects.Crispi
Sure, not as end-points of themselves, perhaps. But the idea would be to have, e.g., /nodes/{id}/boxNodeRelationships and /boxes/{id}/boxNodeRelationships. (Making them available as endpoints would be optional, I guess, for completeness sake.)Orbiculate
I personally don't like this design. Why not /nodes/{id}/box - will return all boxes for the id node?Crispi
Because then I don't know which border of the box that node is attached to (one of four possibilities).Orbiculate

© 2022 - 2024 — McMap. All rights reserved.