8

I am learning REST principles and I have a doubt on working with complex resources.

Let's say we have two resources, Foo and Bar, and for every Foo I must have a Bar. I want to make the dependency of bar from foo clear to developers using my API, so:

1) I will use links from Foo instances to Bar instances, and viceversa

GET /foos/1
Foo: {
    'name': 'Foo instance',
    'rel_bar': '/foos/1/bar'
}


GET /foos/1/bar
Bar: {
    'name': 'Bar instance',
    'rel_foo': '/foos/1',
}

2) I will use a URI templating that shows the dependency from Foo towards Bar (this is just for humans, as URI should be opaque for REST).

/foos               --> Foo resource collection
/foos/{foo_id}      --> An instance of a Foo resource
/foos/{foo_id}/bar  --> The bar instance associated to the foo instance foo_id

So again, there are not bar without a corresponding foo.

Now I wish to create a Foo resource.

POST /foos
{
   'name': 'Yet again another foo instance',
}

And let the server to create the corresponding Bar default (or empty) resource, so the next read will give:

GET /foos/2
{
   'name': 'Yet again another foo instance',
   'rel_bar': '/foos/2/bar'
}

And...

GET /foos/2/bar
{
   'name': null,  --> Let's say that null is the default value.
   'rel_foo': '/foos/2/bar'
}

Is 'RESTfully correct' do this? My concerns are:

  1. is correct to let the server to automatically create a related resource? Or should I split the creation of Bar and Foo in two steps?
  2. is correct to POST a representation (just the 'name' attribute) and GET back a different one ('name' and the assigned 'rel_foo').

My personal thought is that since Bar has no meaning without a Foo, probably yes, I should let the server to create it.

Any idea?

Ameba Spugnosa
  • 1,204
  • 2
  • 11
  • 25
  • 1
    HTTP URIs are intended to represent a single "resource". You can certainly craft your URIs to [represent nested resources](http://stackoverflow.com/questions/11430778/how-to-handle-nested-resources-in-web-api-rest-when-not-found/11433851#11433851) but that approach is neither standards compliant nor true to the REST architectural style. Since you're already considering relationship links in your design, leverage these link to get all benefits of the [hypermedia constraint in REST.](http://kinderman.net/2010/06/23/approaching-pure-rest-learning-to-love-hateoas) – Sixto Saez Nov 06 '12 at 19:26
  • @SixtoSaez I agree with you, I could have had URIs such /45feda e /cba0a1 and it would have the same from the REST point of view. I believe that having a meaningful URIs design can be a plus for the developers that are going to use the API. – Ameba Spugnosa Nov 06 '12 at 23:05

1 Answers1

5

I am not sure if what you describe are independent resources Foo and Bar. You say:

for every Foo I must have a Bar

Together with the 'JSON' and the URIs your describe, I would call this a sub-resource relation: For every Foo there must be one and only one Bar which can not exist outside this Foo.

If this interpretation is correct, I would keep your URIs but change the represenation to this:

GET /foos/1

{
    'name': 'Foo instance',
    'Bar': {
        'name': 'Bar instance'
    }
}

Notice that I didn't include the rel_bar and the rel_bar which are not necessary.

You can GET only the Bar sub-resrouce:

GET /foos/1/bar

{
    'name': 'Bar instance'
}

Notice that in this represenatation there is no link element back to the parent Foo. Such a link is unnecessary since the URI makes the resource/sub-resource relation clear.

Your questions 1:

is correct to let the server to automatically create a related resource? Or should I split the creation of Bar and Foo in two steps?

It is not important if a bar sub-resource is actually created in some backend. What matters is that it is reachable as a member of a representation of Foo. After only POSTing a Foo represenation, the represenation of the Bar sub-resource will have default values as you describe. It could be overriden later:

PUT /foos/1/bar

{
    'name': 'A name for this Bar'
}

Your questions 2:

is correct to POST a representation (just the 'name' attribute) and GET back a different one ('name' and the assigned 'rel_foo').

Yes, that is correct. The client can POST or PUT a represenation that is incomplete. The important thing is to always handle such incomplete represenations in a consistent way. I find it totally agreeable that a Bar sub-resource is created for each new Foo.

  • I think that one should choose to use resource composition instead of linking depending on: a) complexity of the inner resource (http://stackoverflow.com/questions/7104578/rest-complex-composite-nested-resources), b) typical usage of the external resource (maybe I am using the Bar.name on the 1% of the accesses and I don't want to download the whole related structure every time), c) to facilitate a consistent caching, d) the need to update inner resources separately. – Ameba Spugnosa Nov 06 '12 at 23:18
  • @ameba-spugnosa (c) is not valid for selecting between the two. caching works fine whether your resources are sub-resources or not. – Nicholas Shanks Nov 08 '12 at 16:24