Must Resource ID and URL ID be the same?


#1

I have two resources with a strict parent/child hierarchical relationship, where the child has no existence without the parent, and where the child ID must be a monotonically increasing number starting from 1 within the parent resource, so not unique within the global resource set. Lets call them Foo and Bar, where Foo is the parent:

Foo: ABC
  |- Bar: 1
  |- Bar: 2
  |- Bar: 3
Foo: QWE
  |- Bar: 1
  |- Bar: 2

Within the database, we store this in a table with a simple compound natural key:

Foo | Bar | Value
===================
ABC | 1   | shizzle
ABC | 2   | bizzle
ABC | 3   | fizzle
QWE | 1   | lorem
QWE | 2   | ipsum

Now, after reading some other comments here, I understand that the Type / ID combination must be unique within a document to allow the included resources to be correctly linked to, so to create a unique Bar ID here we would have to join the compound key as say Foo_Bar, i.e. ABC_1 and QWE_1. Ugly and bringing some issues around the client needing to have knowledge of the key composition and the joining char, but fair enough, and we can always add the natural key as either data or meta for the client to use instead.

My question comes with the url for the child resource. For internal consistency with the document ID, the url might look like:

https://example.com/api/v1/foos/ABC/bars/ABC_1

but that seems rather redundant repeating the ‘ABC’, not to mention ugly, and inconsistent with our main website urls. I’d much prefer using:

https://example.com/api/v1/foos/ABC/bars/1

Is this allowed by the standard, or sensible? In general are urls required to have any logical relationship to the internal Resource Type/ID? I suspect I’m free to do what I want, but I suspect this may cause issues for some of the libraries out there if they make the assumption that they are the same.

Cheers!

John.


#2

I believe it is allowed, and I think it’s sensible so long as you’re not also exposing bars via URLs in the following format: example.com/api/v1/bars/{id}.

Another option to consider would be whether bars is an array inside foo's attributes rather than a related collection.

My understanding is that such a relationship is recommended, but not required.

That might depend on whether your API is a hypermedia API or not.