简体   繁体   中英

REST API: Should we use PUT or DELETE to update resource partially?

We have website like pluralsight where authors and customers register. Authors publish their courses and customers can give rating to these courses. The table structure looks like:

author table: (save basic information of author: one to one)

authorId | name | contact | email | rating

1 | sahil | 9971343992 | shaf@gmail.com | 3.2

authorRating: (save ratings given to author from customers: one to many)

Id | authorId | customerId | rating |

1 | 1 | 101 | 2.7

2 | 1 | 201 | 3.7

The rating in the author table gets updated when some record gets inserted/updated/deleted in authorRating table. There's some complex algorithm which finalize rating in author table based on authorRating table records.

We have created following APIs for that:

PUT api/author/1/rating /: If there's any change in authorRating table, we recompute the rating of that author and trigger this API to pass new rating. This accepts rating and add/update that in author table. If author table doesn't have id=1, it gives back validation error

DELETE api/author/1/rating /: This removes the rating for author id=1 ie set it to NULL. If author table doesn't have id=1, it gives back validation error.

Is this the right API design? OR should we only have PUT API exposed and if they send rating as null in the PUT API, we will set it null in the author table ?

OR should we consider using PATCH here?

至于您只修改一个结构的字段,我认为PATCH在这里更合适,但应将其发送到父资源:

PATCH api/author/1

For these rating operations, I would use something like:

  • To insert a new rating for author 1, use POST /api/author/1/rating
  • To update a rating for author 1, use PATCH /api/author/1/rating . You may want to have more data in the authorRating table that don't want to change (like author and customer ids) but you are only updating some fields, in this case, the rating.
  • To delete author's 1 rating, DELETE /api/author/1/rating , as you explained, makes sense.

It is a common practice to use POST method for RESTful APIs. You can post virtually any message and handle the message by the parameters. You can POST a delete, or update or other command, depending on your needs.

HTTP is a protocol which defines methods that allow to manipulate resources; files or data on the internet so to say. Any business logic triggered by one of the operations invoked are more or less just side effects while manipulating these resources. While certain things can be achived in multiple ways, operations (slightly) differ in their semantics they convey.

PUT as specified in RFC 7231 , which replaces the current representation with the one provided in the request, does state the following about partial updates:

Partial content updates are possible by targeting a separately identified resource with state that overlaps a portion of the larger resource , or by using a different method that has been specifically defined for partial updates (for example, the PATCH method defined in RFC5789 ).

So, you have either the option of "overlapping" resources and update the other resource, which has the effect of also changing the overlapping data and thus the data in the actual resource as well, or use PATCH therefore.

The primer one can easily be thought of that certain information of an other resource is embedded in the actual resource and on updating the other resource the state of the actual resource will also change as a consequence. Think of a user and his address ie

According to Roy Fielding, who wrote the following in his dissertation

The key abstraction of information in REST is a resource. Any information that can be named can be a resource : a document or image, a temporal service (eg "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (eg a person), and so on. In other words, any concept that might be the target of an author's hypertext reference must fit within the definition of a resource. A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time .”

resources should be named and referenced via own, unique identifiers. A direct mapping of entities to resources though is often not desirable as the resource can and probably should contain more information for the client to take further actions.

It is therefore up to you if you consider a rating to be a good entity and/or a good resource. I'm not a big fan of this though, though this is an opinionated position.

DELETE has some special semantics. It actually does not guarantee the removal of a file, though it will make the resource unavailable by removing the association (the URI) for that particular resource. What happens to the deleted resource is actually up to the implementation.

The DELETE method requests that the origin server remove the association between the target resource and its current functionality . In effect, this method is similar to the rm command in UNIX: it expresses a deletion operation on the URI mapping of the origin server rather than an expectation that the previously associated information be deleted.

...

If the target resource has one or more current representations, they might or might not be destroyed by the origin server, and the associated storage might or might not be reclaimed, depending entirely on the nature of the resource and its implementation by the origin server (which are beyond the scope of this specification). ... In general, it is assumed that the origin server will only allow DELETE on resources for which it has a prescribed mechanism for accomplishing the deletion.

Usually DELETE should only be used on resources that where created via PUT or POST previously whose creation was confirmed via an own Location response header.

With that being said, as you aked for whether this is the right API design or not. Actually, there is no right or wrong and which stance you take is primarily an opinionated one. As long as you stay in bounds with the HTTP protocol specification (in your particular case) you don't violate REST architect principles. If you design your rating resources in a way that make them uniquely identifiable you can use delete to unreference the respective rating from the author (and probably delete the data from your DB) or send a put request with the new content of that rating resource to the respective endpoint.

Keep in mind though, that the server should do its best to teach the client what next actions it can take without having the client to have some out-of-band information about your API, otherwise you will couple the client to your API and therefore might cause problems when you change your API in the future.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM