1

OK I can GET POST PUT DELETE simple resources (entities) in my RESTful web service

ex.

/rest/foos
/rest/foos/1 

/rest/bars
/rest/bars/1

But how to handle adding relationships ex. @OneToMany, @ManyToMany between this relationships using RESTful web service. Suppose I have several Foo entities and several Bar entities how to establish relationships Bar 1 has Foo 3 , etc.

I have such approach to GET this relationships:

GET /rest/bars/1/foos 

Above returns collection of foos related with Bar(id=1)

I cosider maybe doing it this way:

POST /rest/bars/1/foos   { # Foo json object } 

Above will create new Foo object and make association between this new object and Bar(id=1).

PUT /rest/bars/1/foos/2  { # Foo json object } 

Above updates Foo(id=2) if there is such association with Bar(id=1) or if there isn't such association and Foo(id=2) exists in Foo table such association will be made.

If I would like to add/update only Foo without association i made sth like below:

POST /rest/foos
PUT  /rest/foos/2 

If I would like to remove Foo(id=2)

DELETE /rest/foos/2 

And if I only want to delete association between Bar(id=1) and Foo(id=2)

DELETE /rest/bars/1/foos/2 

What do you think about such approach? And how would you handle this correctly?

Michał Ziobro
  • 10,759
  • 11
  • 88
  • 143

1 Answers1

0

Regarding your OneToMany relation How to model parent child entities via REST might help you.

The association with its parent is an attribute of the child resource so the OneToMany relation should be managed on the many side.

PUT /rest/bars/1/foos/2  { # Foo json object }

Is OK if your foos are only possible in connection with a bar but if they can also exist without a bar you should use a dedicated foo resource not subordinate to the bar resource. Think aggregation or composition.

And if I only want to delete association between Bar(id=1) and Foo(id=2)

DELETE /rest/bars/1/foos/2

I would not use this approach instead update the foo with id=2 to not be associated with bar 1 anymore. A DELETE /rest/bars/1/foos/2 should delete the full foo resource instead of only the association in my opinion.

Regarding ManyToMany relations you'll need a third resource to manipulate the join table directly. To simplify this a little bit this resource will only need the POST and DELETE actions defined. POST to add a new associated pair: to ids, one for bar and one for foo. DELETE to remove such a pair.

Community
  • 1
  • 1
Johannes Thorn
  • 902
  • 6
  • 13
  • Ok in the case of \@OneToMany relationship it makes sense to make this associations on the Many side as there I can post/put/delete such association. But in the case of \@ManyToMany relationship I consider how I can access Join Table directly in order to POST/DELETE this association wouldn't be DELETE /rest/bars/1/foos/2 be a good approach indicating what is deleted i.e. Bar 1 and Foo 2 relationship? other approach seems to be something like DELETE /rest/bar-foo-relationship/1+2 – Michał Ziobro Sep 12 '15 at 17:22
  • Is `foo` a child of `bar`? If not why isn't it `rest/foos/2/bars/1`? I would use something like the second approach your first approach has a problem because you create a new `foo` by posting to `bars/1/foos` so I would expect `bars/1/foos/2` to be a resource representing a `foo` but it would represent only the association between them. This would mix two different resource meanings. – Johannes Thorn Sep 12 '15 at 20:41
  • Ok I have for instance Provider and Industry. There is many to many relationship between them i.e. Provider can belong to many Industries and Industry can have defined in it many Providers. So Industries should be accessed and created without Providers, like /rest/industries and /rest/industries/1 also Providers should be accessed independently like /rest/providers/1. But to access on Provider its related Industries i think /rest/providers/1/industries will be logical. But how the best make association and remove it? Do you think /rest/provider-industry-relationship/{id1}+{id2} will be better – Michał Ziobro Sep 12 '15 at 21:43
  • First try to find a better name for this relationship which is more domain centered. If there is no better fitting name use this path but drop the `relationship` and use plural nouns. Or use `providersToIndustries/1to2` or use any separator you want. I think API design should be about semantics. You could also use query parameters to describe id1 and id2. – Johannes Thorn Sep 12 '15 at 22:49
  • so maybe I finally do something like /rest/providers-industries/1+2 or /rest/providers-industries?providerId=1&industryId=2 – Michał Ziobro Sep 13 '15 at 08:49
  • My additional consideration is what about JAX-RS resource classes if I have ProviderResource class with @Path("/providers") and IndustryResource class with root path @Path("/industries") should I for this relationship create separate class ProviderIndustryRelationship class and add path @Path("providers-industries") or some bettern pattern is possible? – Michał Ziobro Sep 13 '15 at 09:07
  • Yes I would create a standalone `ProviderIndustryRelationship` because the path `/providers-industries` is a REST resource in itself representing the `provider` - `industry` associated pairing. Maybe call it `...Pairing`. Creating a standalone resource class is also supporting the single responsibility concept and is expected in my point of view. And if the Pairing should become more than a simple join model you can simply expand your class. – Johannes Thorn Sep 13 '15 at 10:22