Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to design Multiple Patch requests in WebApi Core

I would like to know what's the best way to design multiple updates to the resource(s) in WebApi .Net Core.

For example, I would like to enable the following features for users resources

  • Update User Password
  • Update User role
  • Update User Details (such as Firstname, last name, etc.)

So, according to REST tutorials and articles, I learnt that I need to use PATCH method to update partial resource.

We did some discussions in the team and we are confused with these two options:

Option 1

implement multiple PATCH routes for different actions

  • PATCH /api/users/{id}/password
  • PATCH /api/users/{id}/role
  • PATCH /api/users/{id}/details

Option 2

implement ONLY single PATCH action for the whole resource. Users will send application/json-patch+json for partial updates.

  • PATCH /api/users/id (accepts JsonPatchDocument parameter)

I tried to find the best practices for Restful Route Namings and most of them only cover for simple CRUD activities or nested resources.

For this kind of multiple UPDATE operations, may I know what's the best practice for naming the routes? Or the term for it to study in-depth? Thanks.

like image 712
TTCG Avatar asked Sep 16 '19 12:09

TTCG


1 Answers

PATCH requests are used to update parts of single resources, i.e. where only a specific subset of resource fields should be replaced. The semantic is best described as "please change the resource identified by the URL according to my change request".

  • PATCH requests are usually applied to single resources as patching entire collection is challenging
  • PATCH requests are usually not robust against non-existence of resource instances
  • on successful PATCH requests, the server will update parts of the resource addressed by the URL as defined by the change request in the payload
  • successful PATCH requests will usually generate 200 or 204 (if resources have been updated with or without updated content returned)

Note: since implementing PATCH correctly is a bit tricky, I strongly suggest to choose one and only one of the following patterns per endpoint.In preference order:

  1. use PUT with complete objects to update a resource as long as feasible (i.e. do not use PATCH at all).
  2. use PATCH with partial objects to only update parts of a resource, whenever possible. (This is basically JSON Merge Patch, a specialized media type application/merge-patch+json that is a partial resource representation.)
  3. use PATCH with JSON Patch, a specialized media type application/json-patch+json that includes instructions on how to change the resource.
  4. use POST (with a proper description of what is happening) instead of PATCH, if the request does not modify the resource in a way defined by the semantics of the media type.

Option 1 seems like bad design, because you will have a lot of endpoints for each property.

Option 2 is following by REST recommendation and specified in RFC 6902

You can implement it in following ways:

  • Delta (part of Microsoft ASP.NET WebAPI OData): it has some problems with numbers when using JSON. You also need to install the package with all its non-trivial dependencies;
  • JSON Patch: the client must organize the data per operation and the size of the request is not optimized.
  • Use Simple.HttpPatch that allows to easily apply partial updates
  • One more SimplePatch implementation

Route Namings

  • use plural nouns for resource name. Do not mix up singular and plural nouns. Keep it simple and use only plural nouns for all resources(users, instead of user)

  • if you have two base URLs per resource then the first URL is for a collection (list); the second is for a specific element in the collection (/users and /users/1)

  • if you have relations, use sub-resources for it

/users/1/phones - returns a list of phones for user 1
/users/1/phones/1 - returns phone #1 for user 1

  • keep verbs out of your base URLs. Use HTTP request methods GET, POST, PUT/PATCH, DELETE with two base URLs to CRUD operations. The point is that developers probably don't need the documentations to understand how the API behaves.In other way you will have a long list of URLs and no consistent pattern making it difficult for developers to learn how to use your API

  • complex things need to be hidden behind the ?. Almost every API has a lot of parameters that you can read, update, filter and work with them in any other ways. But all these parameters should not be visible in the base addresses. It is best to specify the parameters within the reference to the base addresses.

GET /users/1234?firstName=Bill&PhoneNumber="1111"

Also see links

  • Microsoft REST API Guidelines
  • Zalando RESTful API
  • Web API Design
like image 198
Roman Marusyk Avatar answered Oct 21 '22 10:10

Roman Marusyk