Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST API design: linking resources

Supposed I have two top-level resources Foo and Bar. Now the Foo need to be linked to some of the Bar. In a Java class this might look something like this:

public class Foo {

  Set<Bar> bars;
}

public class Bar { … }

I'd like to shape the XML representation of Foo to something like this:

GET /foos/1

<foo>
  …
  <atom:link rel="self" href="/foos/1" />
  <atom:link rel="bars" href="/foos/1/bars" />
</foo>

So I pretty much expose all Bar assigned to a Foo as nested resource. That means Bar resource have an individual lifecycle (aggregation instead of composition). The nested resource might then expose all linked Bar something like this:

GET /foos/1/bars

<bars>
  <atom:link rel="bar" href="/foos/1/bars/1" />
  <atom:link rel="bar" href="/foos/1/bars/2" />
</bars>

Alteratively I could inline the collection in the <foo>element upfront. However I am still stuck with some questions: While this allows me to nicely remove a Bar from a Foo by triggering a DELETE request to e.g. /foos/1/bars/1 but how would one assign a Bar to a Foo then? Assuming the client would access /bars getting:

GET /bars

<bars>
  <bar>
    …
    <atom:link rel="self" href="/bars/4711" />
  </bar>
</bars>

and deciding it wants to assign /bars/1 to /foo/1/bars. I was thinking about a POST request to /foo/1/bars but was unsure about what to actually submit. A link element pointing to the Bar resource such as the following?

POST /foos/1/bars

<atom:link href="/bars/4711" />

This seems quite okay as the clients would still not need to create URLs and we still satisfy REST constraints. However it feels a bit weird to POST links to the server. Is there a better solution to this scenario?

like image 755
Oliver Drotbohm Avatar asked Jan 11 '12 10:01

Oliver Drotbohm


1 Answers

I think about this in terms of the resources understood by the server rather than the XML representations that flow in response to (say) a GET request. I have RESTful services that return either JSON or XML, or potentially other representations.

So I agree with your POSTing or PUTing to

 /foos/{fooId}/bars

to specify either the complete list of bars or the addition of some bars.

The format of the posted payload can be whatever is the natural serialised form for the media-type your're using. In my case it's often a JSON string and so in my service implementation would deserialise and see an array of resoruce reference URL strings.

If your

<atom:link href="/bars/4711" /> 

also deserialise nicely then I don't see a problem if the serialised form is a little, um, ornamental.

Summary: do what's natural for your (de)serialiser.

like image 84
djna Avatar answered Oct 13 '22 20:10

djna