Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
997 views
in Technique[技术] by (71.8m points)

json - REST: Updating Multiple Resources With One Request - Is it standard or to be avoided?

A simple REST API:

  • GET: items/{id} - Returns a description of the item with the given id
  • PUT: items/{id} - Updates or Creates the item with the given id
  • DELETE: items/{id} - Deletes the item with the given id

Now the API-extension in question:

  • GET: items?filter - Returns all item ids matching the filter
  • PUT: items - Updates or creates a set of items as described by the JSON payload
  • [[DELETE: items - deletes a list of items described by JSON payload]] <- Not Correct

I am now being interested in the DELETE and PUT operation recycling functionality that can be easily accessed by PUT/DELETE items/{id}.

Question: Is it common to provide an API like this?

Alternative: In the age of Single Connection Multiple Requests issuing multiple requests is cheap and would work more atomic since a change either succeeds or fails but in the age of NOSQL database a change in the list might already have happend even if the request processing dies with internal server or whatever due to whatever reason.

[UPDATE]

After considering White House Web Standards and Wikipedia: REST Examples the following Example API is now purposed:

A simple REST API:

  • GET: items/{id} - Returns a description of the item with the given id
  • PUT: items/{id} - Updates or Creates the item with the given id
  • DELETE: items/{id} - Deletes the item with the given id

Top-resource API:

  • GET: items?filter - Returns all item ids matching the filter
  • POST: items - Updates or creates a set of items as described by the JSON payload

PUT and DELETE on /items is not supported and forbidden.

Using POST seems to do the trick as being the one to create new items in an enclosing resource while not replacing but appending.

HTTP Semantics POST Reads:

Extending a database through an append operation

Where the PUT methods would require to replace the complete collection in order to return an equivalent representation as quoted by HTTP Semantics PUT:

A successful PUT of a given representation would suggest that a subsequent GET on that same target resource will result in an equivalent representation being returned in a 200 (OK) response.

[UPDATE2]

An alternative that seems even more consistent for the update aspect of multiple objects seems to be the PATCH method. The difference between PUT and PATCH is described in the Draft RFC 5789 as being:

The difference between the PUT and PATCH requests is reflected in the way the server processes the enclosed entity to modify the resource identified by the Request-URI. In a PUT request, the enclosed entity is considered to be a modified version of the resource stored on the origin server, and the client is requesting that the stored version be replaced. With PATCH, however, the enclosed entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version. The PATCH method affects the resource identified by the Request-URI, and it also MAY have side effects on other resources; i.e., new resources may be created, or existing ones modified, by the application of a PATCH.

So compared to POST, PATCH may be also a better idea since PATCH allows an UPDATE where as POST only allows appending something meaning adding without the chance of modification.

So POST seems to be wrong here and we need to change our proposed API to:

A simple REST API:

  • GET: items/{id} - Returns a description of the item with the given id
  • PUT: items/{id} - Updates or Creates the item with the given id
  • DELETE: items/{id} - Deletes the item with the given id

Top-resource API:

  • GET: items?filter - Returns all item ids matching the filter
  • POST: items - Creates one or more items as described by the JSON payload
  • PATCH: items - Creates or Updates one or more items as described by the JSON payload
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could PATCH the collection, e.g.

PATCH /items
[ { id: 1, name: 'foo' }, { id: 2, name: 'bar' } ]

Technically PATCH would identify the record in the URL (ie PATCH /items/1 and not in the request body, but this seems like a good pragmatic solution.

To support deleting, creating, and updating in a single call, that's not really supported by standard REST conventions. One possibility is a special "batch" service that lets you assemble calls together:

POST /batch
[
  { method: 'POST', path: '/items', body: { title: 'foo' } },
  { method: 'DELETE', path: '/items/bar' }
]

which returns a response with status codes for each embedded requests:

[ 200, 403 ]

Not really standard, but I've done it and it works.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...