I have a server-side service (using ASP.NET Core) that should provide a REST API to various clients.
Behind the service, I use a SQL server for data storage.
The controller has the following route attribute:
[Route("api/[controller]")]
[ApiController]
public class CustomDataController : ControllerBase
{…}
There are data provider methods:
[HttpGet(nameof(GetDataForGuest))]
public async Task<IQueryable<Specs>> GetDataForGuest(int skip, int take, Guid organizationID) => await dataProvider.GetDataAsync<Specs>(skip, take, organizationID);
There are methods to create or update data on the server:
[HttpPost(nameof(SaveDataToServer))]
public async Task SaveDataToServer([FromBody] List<Specs> specs) => await dataProvider.SaveDataAsync<Specs>(specs, isNewData: true);
According to many articles (like this one), GET
is for returning some resource, POST
is for creating and PUT
is for updating:
- GET — For returning resources
- POST — For creating a new resource
- PUT — For updating a resource
- PATCH — For updating a resource
- DELETE — For deleting a resource
However, as you can see, my methods are only facades, the data is saved by the data provider, and I can decide based on a bool variable to insert or update an incoming record.
As you can also guess, I don't use traditional REST URLs (like api/user/1
), as I need complex data, so my URLs look like this:
https://192.168.0.101:8080/api/customdata/GetDataForGuest?skip=0&take=10&organizationID=58b77372-abbc-435e-9a5b-d77bc05129c7
Currenty I get data with the HttpPost
for both inserting new records and updating existing ones (and it works normally). My concerns are about best practice: should I use HttpPut
when I want to update an existing record?
According to the specifications, using PUT
is idempontent by definition while POST
is not, so executing the query should not depend on how many times it was called.
On the client side, I use some query building (based on parameters) and I call the method with a POST
action:
public async Task SaveDataToServer(string methodName, List<T> data, bool isNewData)
{
var parameters = GetParameters(methodName, isNewData);
var baseUri = new Uri(baseUriString, methodName);
var targetUri = UriBuilding(baseUri, parameters).AbsoluteUri;
var result = await httpClient.PostAsync<List<T>>(targetUri, data);
}
So using only POST
is considered as best practice? Or should I separate the update actions to another method marked with HttpPut
? Does it matter considering that the logic behind the methods decides what will happen and not the verb?
httpClient
you use definitively "speak"HTTP
but you are using it to speakwhat-ever-your-protocols-is
. It's like hiring a spanish-speaking to make it speak chinese.