PUT or DELETE for a logical delete in Web Api - asp.net-web-api

Should we create a PUT or DELETE request for a Logical Delete in Web Api ? I-e setting a flag IsDeleted = 0 or 1

The REST school of thought for Web API maps HTTP verbs to operations on resources, and the typical mapping looks like this:
GET = READ
POST = CREATE
PUT = UPDATE (though sometimes PATCH is used in place of PUT, and PATCH may arguably be more correct)
DELETE = DELETE
The question I'd ask, then, is whether the fact that the delete operation is logical, rather than physical, transparent to the consumer of the API? If the expectation of the API consumer is that they're deleting a record, then I'd use the DELETE verb for the request.
Yes, you could use PUT/PATCH to update the IsDeleted field, and it would not be wrong per se, but I would look at this from the perspective of what the API consumer expects in order to decide which is right in this situation.

Related

HTTP Verbs, WebAPI

I would like to know the usage scenario of POST vs PUT in a WebAPI . I know the basic concepts that POST is for creating resource and PUT is for updating resource but not able to fully understand why we need a PUT over a POST.
I have 2 WebAPI methods which creates/updates data to my SQL store
1. CreateUser(UserDto)
2. UpdateUser(UserDto)
UserDto contains userId, username and email.
I can use POST for both CreateUser and UpdateUser methods which creates and updates user to my store.
Then what is the real advantage of using POST for CreateUser and PUT for updateuser? Is it just a standard/convention?
Thank you
POST always creates something new. PUT updates a existing thing. It is a convention.
You should have:
POST /users : to create a new user. The payload should not include the ID
PUT /user/(id) : to replace a user DTO with the data in the payload. Again, the payload should not contain an user id
PATCH /user/(id): to update specific members of the user, but the id.
It is a design convention, like software design patterns, to make it easy to communicate and understand by whoever has to consume the API.
POST is usually used to add a new resource into collection of resources.
Like this: POST /users.
This operation is NOT idempotent and it will have a side effect at each call.
While PUT is usually used with a replace semantic and you know the exact resource which you want to replace.
Like this: PUT /users/1.
This operation is idempotent and it will not have any side effects on subsequent calls.

JSON API REST endpoint with permissions-restricted fields

JSON API REST endpoint with permissions-restricted fields
I am working on a JSON API-compliant REST api. Some endpoints contain fields that should be restricted (read-only or not available) for certain users.
What is the best way to architect the api to allow that certain users have access to certain fields, while others do not? By "best", I mean:
Most compliant with REST standards, ideally JSON API standards
Most clarity in terms of preventing bugs and confusion on behalf of clients consuming the API
I am considering the following options, each with their set of concerns/ questions. I would be more than grateful for any other solutions!
Option 1: Return null on restricted fields for users without permissions
Different data values would be returned per-user. Is this strictly anti-REST?
Lack of distinction between null meaning "null value" and null meaning "You don't have access to this"
In REST/ JSON API architecture, is it okay for an endpoint to return different data per user, based on permissions? I have the impression that this would be contrary to the spirit of resource-based REST architecture, but I could not find anything specific to point to in any doc or standard (e.g. JSON API). Also applies to Option 2.
Is there any paradigm for adding some sort of "You don't have access" flag in the resource's metadata?
Option 2: Exclude restricted fields entirely for users without permissions
Different data values would be returned per-user. Is this strictly anti-REST?
Possibility of "undefined" errors in client, when trying to retrieve field value
Option 3: Move restricted field(s) onto another endpoint, available as an ?include='field_name' relation for those with permission
Example: /api/entity includes attribute field "cost" which is only available to Admin users. Admin users can request cost data via GET /api/entity?include=cost. For all users, "cost" is exposed as a relation in the resource object, with a "type" and "id".
This is the option I am leaning toward. The main con here is endpoint clutter. I have a lot of relations that would need to be made into separate endpoints, simply to support a permissions-quarantined data on an already-existing endpoint.
In the JSON API specs, I am having trouble determining if it's ok for an endpoint to exist as a relation only, e.g. can we have /api/entity/1/cost, but NOT have a top-level api endpoint, /api/cost. My assumption is that if a resource has a "type" (in this case, the relation type being 'cost'), it also has to live on a top-level endpoint.
In this scenario, the client could get a 401: Unauthorized error response if a non-admin user tries to GET /api/entity?include=cost or GET /api/cost/:id
Note: I have already built a separate permissions schema so that the client can determine which CRUD privileges the user has, per top-level endpoint, before making any requests. Permission sets are indexed by resource type.
Any help on the matter would be very much appreciated! And if anything needs to be clarified, feel free to ask.
I would definitely not use undefined or null to indicate fields that the user is not allowed to see. To me, that feels like a lie and represents that the data is really not there. They would have to really know your API in order to get a grasp of what is really going on.
I would recommend something more like your 3rd option, except I would make it a different endpoint altogether. So in your example, the endpoints would be:
/api/entity/1/cost
and for admins
/api/admin/entity/1/cost
or something like that.
This way your server code for the admin endpoint could just be focused on authenticating this admin user and getting them back all the fields that they have visibility on. If a non admin user tries to hit that route, reject them with an unauthorized status code.
I'm not saying that you should not implement the GET param to be able to specify fields as well. You can if you want to, but I don't think it just won't be necessary in this case.

Laravel DELETE request as API

When you want to delete an item from the db, I know that you can use /resource/{id} and use the contrller#destroy action.
What is the advantage of passing a parameter in the URL as oppose to send a DELETE request and pass the parameter $id via an Input?
You can certainly do both, but the first method (using the dedicated /resource/{id} URL) is following the RESTFUL design pattern. Here is a very good video on that.
To highlight some important points:
We avoid verbs in URLs, unless they're used for very specific actions. We should try to use nouns instead if it's possible, so a url like /resource/deleteis not advisable.
When someone used to the REST way of communicating with an API uses 'DELETE' on the /resource url, he/she expects to delete ALL resources. If he/she uses it on /resource/{id}, then only that specific item should be removed.
Hope this made sense =)

Should I use REST style URLs with PUT and DELETE in my web app?

I have a SPA (single page application) so it uses AJAX extensively for getting and saving data to and from the server. In one case I allow the admin to view/add/edit/delete users. Some current urls for this area looked something like:
(GET) /users?userId=1 // get user with id of 1
(POST) /users?userId=1&firstName=Jim // update the first name of the user with id 1
(POST) /users?firstName=Bob // create a new use with the first name Bob
(POST) /users?userId=1&delete=true // delete user with id of 1
Having spent some time working on a RESTful API in a related project, I'm wondering if it's preferred to use HTTP types (GET, POST, PUT, DELETE) in a web app as well. Also, is it better to use a path parameter for user id instead of a query parameter? So are these urls (rewrite of the ones above) a better option in the long run:
(GET) /users/1 // get user with id of 1
(PUT) /users/1?firstName=Jim // update the first name of the user with id 1
(POST) /users?firstName=Bob // create a new use with the first name Bob
(DELETE) /users/1 // delete user with id of 1
In theory yes you should. You should be as RESTful as possible which means using HTTP semantics to their fullest. However the reality is a bit more murky, several older browsers, I don't need to name names, don't support anything but GET and POST. So the current recommendation until those browsers go out of support, or until you drop support for those browsers, is to have backup methods that do the same thing but on POST, usually with an extra parameter or segment in the url.

GET vs POST in AJAX?

Why are there GET and POST requests in AJAX as it does not affect page URL anyway? What difference does it make by passing sensitive data over GET in AJAX as the data is not getting reflected to page URL?
You should use the proper HTTP verb according to what you require from your web service.
When dealing with a Collection URI like: http://example.com/resources/
GET: List the members of the collection, complete with their member URIs for further navigation. For example, list all the cars for sale.
PUT: Meaning defined as "replace the entire collection with another collection".
POST: Create a new entry in the collection where the ID is assigned automatically by the collection. The ID created is usually included as part of the data returned by this operation.
DELETE: Meaning defined as "delete the entire collection".
When dealing with a Member URI like: http://example.com/resources/7HOU57Y
GET: Retrieve a representation of the addressed member of the collection expressed in an appropriate MIME type.
PUT: Update the addressed member of the collection or create it with the specified ID.
POST: Treats the addressed member as a collection in its own right and creates a new subordinate of it.
DELETE: Delete the addressed member of the collection.
Source: Wikipedia
Well, as for GET, you still have the url length limitation. Other than that, it is quite conceivable that the server treats POST and GET requests differently; thus the need to be able to specify what request you're doing.
Another difference between GET and POST is the way caching is handled in browsers. POST response is never cached. GET may or may not be cached based on the caching rules specified in your response headers.
Two primary reasons for having them:
GET requests have some pretty restrictive limitations on size; POST are typically capable of containing much more information.
The backend may be expecting GET or POST, depending on how it's designed. We need the flexibility of doing a GET if the backend expects one, or a POST if that's what it's expecting.
It's simply down to respecting the rules of the http protocol.
Get - calls must be idempotent. This means that if you call it multiple times you will get the same result. It is not intended to change the underlying data. You might use this for a search box etc.
Post - calls are NOT idempotent. It is allowed to make a change to the underlying data, so might be used in a create method. If you call it multiple times you will create multiple entries.
You normally send parameters to the AJAX script, it returns data based on these parameters. It works just like a form that has method="get" or method="post". When using the GET method, the parameters are passed in the query string. When using POST method, the parameters are sent in the post body.
Generally, if your parameters have very few characters and do not contain sensitive information then you send them via GET method. Sensitive data (e.g. password) or long text (e.g. an 8000 character long bio of a person) are better sent via POST method.
Thanks..
I mainly use the GET method with Ajax and I haven't got any problems until now except the following:
Internet Explorer (unlike Firefox and Google Chrome) cache GET calling if using the same GET values.
So, using some interval with Ajax GET can show the same results unless you change URL with irrelevant random number usage for each Ajax GET.
Others have covered the main points (context/idempotency, and size), but i'll add another: encryption. If you are using SSL and want to encrypt your input args, you need to use POST.
When we use the GET method in Ajax, only the content of the value of the field is sent, not the format in which the content is. For example, content in the text area is just added in the URL in case of the GET method (without a new line character). That is not the case in the POST method.

Resources