rest - RESTfully create or update a resource that references

问题描述:

If I wanted to create (POST) a new resource linking two independent resources, what is the most proper - with respect to HATEOAS and REST principles - way to structure the entity of the request?

Any references in RFCs, W3C documents, Fielding's thesis, etc., about the proper way for a client to request two independent resources be linked together would be most valuable. Or, if what I'm interested in is simply outside the scope of REST, HATEOAS, an explanation of why would also be great.

Hopefully my question above is clear. If not, here's a scenario and some background to ground the question.

Let's say I have two independent resources: /customer and /item, and a third resource /order intended to the two.

If I'm representing these resource to the client in a HATEOAS-like way (say with JSON-LD), a customer might (minimally) look like:

{

"@id": "http://api.example.com/customer/1"

}

and similarly an item like:

{

"@id": "http://api.example.com/item/1"

}

I'm more concerned about what scheme the entity of the POST request should have, rather than the URL I'm addressing the request to. Assuming I'm addressing the request to /order, would POSTing the following run afoul of HATEOAS and REST principles in any way?

{

"customer": {"@id": "http://api.example.com/customer/1"},

"item": {"@id": "http://api.example.com/item/1"}

}

To me, this seems intuitively OK. However, I can't find much or any discussion of the right way to link two independent resources with a POST. I discovered the LINK and UNLINK HTTP methods, but these seem inappropriate for a public API.

网友答案:

The client does not build URIs, so this is wrong unless these resource identifiers or at least their template came from the service. It is okay to use the id numbers instead of the URIs until you describe this in the response which contains the POST link.

The "http://api.example.com/doc/#Comment" contains the property descriptions.

{
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@id": "http://api.example.com/doc/#Comment",
"@type": "Class",
"title": "The name of the class",
"description": "A short description of the class.",
"supportedProperty": [
... Properties known to be supported by the class ...
{
"@type": "SupportedProperty",
"property": "#property", // The property
"required": true, // Is the property required in a request to be valid?
"readable": false, // Can the client retrieve the property's value?
"writeable": true // Can the client change the property's value?
}
]
}

A supported property can have an rdfs:range, which describes the value constraints. This is not yet (2015.10.22.) added to the hydra vocab as far as I can tell, but I don't have time to follow the project. I think you still can use the rdfs:range instead of waiting for a hydra range.

So in your case you could add an item property with a range of http://api.example.com/doc/#Item and so on. I assume you could add the links of the alternatives, something like http://api.example.com/items/, so you could generate a select input box. Be aware that this technology is not stable yet.

So you can send a simple JSON as POST body {item: {id:1}, customer: {id:1}} or something like that, which you generate based on the POST link. The RDF is for the client not for the server. The server can understand the data structure it requires, it does not need RDF. You don't need a dictionary to understand yourself...