开发者

RESTful Many-to-Many possible?

How to I represent a complex resource for a REST post?

Hello, Currently I have an application which when the user hits "save" it iterates over all of the form elements and creates one mass object which manages a:

  var = params = [{ 
   attributes1: form1.getValues(),
   attributes2: form2.getValues(),  
.. ..
}];

I then send this mass object via a RPC POST to my "Entity" model service. This entity which I wish to persist data for is quite complex. All in all, the data is spread accross about 30 tables. To help explain my actual question, the "entity" is a building (as in a physical property/house/apartment).

What I would like, is to be able to turn my mess into a RESTful API for saving properties. The problem I have is that, saving details for a single model that spans a single table is fine. How do I structure my data object for transport when the model has

  • many to many relationships
  • one to many relationships
  • one to one relationships

For example:

Here is a WATERED down version of what I might have on a property and the sample开发者_JAVA百科 data

propertyId: 1,
locationId: 231234,
propertyName: "Brentwood",
kitchenFeatures: [
             { featureId: 1, details: "Induction hob"},
             { featureId:23, details: "900W microwave"}
],
propertyThemes: [ 12,32,54,65 ]

This actually goes on a lot more.. but you can get the general gist. kitchenFeatures would be an example of a many-to-many, where I have a featuresTable which has all of the features like so:

`featureId`, `feature`
1             "Oven Hob"  
23            "Microwave"

and propertyThemes would be an example of another many-to-many.

How am I expected to form my "object" to my RESTful service? Is this even possible?

ie. If I want to save this property I would send it to:

http://example.com/api/property/1


The approach I would use here is hypermedia and links:

/property
/property/{id}
/property/{id}/features/{id}

Depending on your domain you might even get away with:

/property/{id}/features/{name}

or

/property/{id}/features/byname/{name}

Thus you can do REST operations and serve JSON or XHTML hypermedia.

Property details:

Request: GET /property/1
Response:
{
  ..
  "name": "Brentwood",
  "features": "/property/1/features"
  ..
}

Brentwood's features:

GET /property/1/features
{
  ..
  "Kitchen": "/property/1/features/1",
  "Dog Room": "/property/1/features/dog%20room",
  ..
}

GET /property/1/features/1
{
  ..
  "Induction hob": "/property/1/features/1/1",
  "900W microwave": "/property/1/features/1/23",
  "nav-next" : "/property/1/features/dog%20room",
  ..
}

To add a relation you can do something like this:

POST /property/1/features
{
  ..
  "Name": "Oven Hob"
  ..
}

If you know what the relation will be you use a PUT:

PUT /property/1/features/23
{
  ..
  "Name": "Oven Hob"
  ..
}

You can serve multiple media types:

GET http://host/property/1/features/dog%20room.json

GET http://host/property/1/features/dog%20room.xhtml

For the response in xhtml the response can use named links like this:

..
 <a href="http://host/property/1/features/1" rel="prev">Kitchen</a>
..

There are other aspects of REST that you can use such as response code which I did not include above.

Thus, to model relations you make use of links which can be in itself a resource that can be operated on with GET, PUT, POST and DELETE or even custom verbs such as ASSOCIATE or LINK. But the first four are the ones that people are used to. Remember PUT is idempotent but not POST. See PUT vs POST in REST

Edit: You can group your links into JSON arrays to give structure to your hypermedia.


I think you're really asking, "How do I represent complex data in a form suitable for transmission within a POST?", right? It's less to do with REST and more to do with your choice of media type. I would suggest starting with a pure JSON representation, using arrays and cross-referenced ID fields to map the relationships. You could also do this with XML, of course.

The examples you gave look right on the money. You just need to ensure that both parties (browser and server) agree on the structure and interpretation of the media type you use.


I'm dealing with the exact same thing. I opted to not use id's anywhere, but use urls everywhere an id would normally be expected.

So in your case, the kitchenfeatures could simply be an array with urls to:

/feature/1
/feature/23

And the themes to

/propertyTheme/12
/propertyTheme/32
etc..

In the case of many-to-many relationships, we update all the relations as a whole. Usually we simply dump the existing data, and insert the new relationships.

For one to many relationships we sometimes extend the urls a bit where this makes sense. If you were to have comments functionality on a 'property', this could look like

/property/1/comment/5

But this really depends on the situation for us, for other cases we put it in the top-level namespace.

Is this helpful to you?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜