specify an action to run via REST API - rest

Just wondering what the best practice is for specifying an endpoint in rest to say "runSomeAction"? I'm aware of the uses for GET,POST,PUT,DELETE operations and using nouns to specify those endpoints, but what is the preferred method for exposing server functionality that isn't a CRUD type operation?
EDIT:
The result of the action will just kick off a process on the server and return a status of 200 immediately (before process is complete), no body. This process is specifically running some validation rules against saved items in a database.

What is the end result of the action? Typically, you do a PUT/POST to create the resulting resource. For instance, instead of POST /sendEmail, you'd do POST /email-notifications.
EDIT
In your case, I would consider your resource to be the results of the validation. I would suggest either POST /validations or POST /validations/{whateverTypeIsBeingValidated}. You could alternately go with validation-results. Even if you don't support the client viewing the validation results now, you have the option to do so later.
Also, per #MartinBroadhurst, a REST API may not be an ideal tool here.

Related

Are PUT and DELETE HTTP methods indispensable just because of their idempotency property?

I have a REST API and I want to handle all HTTP requests via POST request.
Is there any performance or other kind of issue in using just POST to perform all CRUD operations requested by a user, which sends a JSON containing some data and the operation to be performed?
Technically, the HTML used in the Web only supports GET and POST and this is more or less the reference implementation of a REST architecture.
So, while this is possible I wouldn't advocate for something like that as the idempotency property of PUT and DELETE provide some other benefits in case of network issues where a client can automatically resend the request regardless whether the initial request, whose response might have just got lost mid-way, actually performed its task or not. The result should always be an updated/created resource or a removed URI mapping to the actual resource (or even a removal of the actual resource) as DELETE technically just removes the URI mapping.
In regards to put some operations in the payload, it depends. This actually sounds very RPCy to me, similar to SOAP i.e. If the operation however is defined by a well-defined media-type, like in the JSON Patch case, I guess this is not wrong. Similar to the Web, however, a server should use some resource that is able to teach a client on how to build up a request, like HTML does with forms. This will not only teach the client on what fields the server supports for the target resource but also where to send the request to as well as the media-type and HTTP operation to use, which might be fixed to POST as in the HTML case.

RESTful way to specify commands on a resource

I could not find a universally agreeable way to specify commands in RESTful manner. Consider that I have a resource on which I want to provide 3 commands:
enable
disable
re-trigger
Which is the most RESTful way?
POST /resource/disable
POST /resource?command=disable
Any other way ?
Which is the most RESTful way?
How would you do it with a web site? REST is the architectural style of the world wide web; if you can figure out how you would do it with a web site, that will give you the right idea for how to provide a RESTful API.
On the web, the usual answer would be that we would have forms to collect information from the client, who would then submit a POST request (because we are intending to change the resource) to some endpoint.
Because the form.action property tells the client what URI to use, the server has control over what the URI is -- we can change it later if we want to.
We could, as you suggest, have a different URI for each command. There's nothing wrong with that, but it does miss an opportunity. You see, one of the important ideas in REST is caching; and HTTP defines cache invalidation semantics; the practical aspect of which is that if you use the /resource identifier as the form action, then successful POST requests will automatically invalidate the client's local copies of the resource.
This does imply, of course, that the POST handler in your implementation will have to determine which command was intended -- probably by looking at information included in the body of the post request; a "commandName" parameter or something similar.

REST - Custom Update Actions

I'm working on a REST API and my tickets collection has multiple ways to be updated since it will go through multiple status. Note that some of those status can only be performed by a specific role (RBCA). With that in mind, what would be the best approach?
1) Using sub-methods for the specific actions
PATCH /tickets/:id/validate
PATCH /tickets/:id/update
PATCH /tickets/:id/finish
2) Control what is updated based on the current status of the ticket and the user's role with a single PATCH /tickets/:id
Which one is the best when it comes to the REST best practices?
Which one is the best when it comes to the REST best practices?
Short answer: choice #2.
Longer answer: the reason we care which identifier is used as the target of an request, is that HTTP has cache invalidation semantics built into the protocol: if you successfully patch a resource, the generic components involved know to evict all of the cached representations of that resource. See Invalidation in RFC 7234.
So if we were implementing a web site, and trying to take advantage of cache invalidation, we might have a hierarchy like
# the readable link to a specific tickets collection
/tickets/:id
# a validation form that submits data to /tickets/:id
/tickets/:id/validation
# an update form that submits data to /tickets/:id
/tickets/:id/update
# a finish form that submits data to /tickets/:id
/tickets/:id/finish
So our workflow to "update" the tickets collection might look like...
GET /tickets/:id
GET /tickets/:id/update
POST /tickets/:id
In an API where we aren't restricted by HTML, we could consider using unsafe methods other than POST to do the work.
Note: this does means that the "POST/PATCH" end point in our implementation would need to do additional routing of its own to reach the validation/update/finish logic. With forms, that would mean using the submitted data to determine which behavior is intended -- perhaps a hidden field, or maybe the endpoint just makes a guess based on which keys are in the form data.

Does it violate the RESTful when I write stuff to the server on a GET call?

I would like to record user actions on my website, not only on POST requests, but on GET requests as well. For example, suppose the user tries to search for a city with the following GET request:
/search_city?name=greenville
This request would return a list of cities with the name "greenville". I'd also like to save this keyword to the server, as the "search history" for a user. I'm planning to just do the save this information during the processing of the GET call.
Is this a violation to RESTful principles? If yes, how do I do this the right way?
I see this kind of audit logging as an invisible side-effect. If the next person to call
/search_city?name=greenville
still gets the same answer then your GET is valid. A similar case would be some kind of cache building, the caller of GET doesn't (need to) know that you're doing some extra work.
Focus on the formal API - send this request get this response.
If there's some resource available in the API where the user search history is available, then it's not OK to do that, since your GET request has a visible side-effect. For instance, a client caching responses is under no obligation to know that any resource changed because he did a GET request to anything else. I think the only way to do this and stay compliant is to explicitly mark the side-effected resource as uncacheable.
In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.
Naturally, it is not possible to ensure that the server does not generate side-effects as a result of performing a GET request; in fact, some dynamic resources consider that a feature. The important distinction here is that the user did not request the side-effects, so therefore cannot be held accountable for them.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
If that's kept only for internal usage, I guess it's fine to do it that way, but I still recommend against it.

Actions vs. CRUD in REST

Is it appropriate to perform actions with REST, other than simple create (POST), read (GET), update (PUT), and delete (DELETE)? I'm kind of new to the whole RESTful theology, so bear with me, but how should I accomplish the following:
I have a web service that needs to talk to another web service. Web service A needs to "reserve" an object on Web service B. This object has a timeout of validity, but can be deleted immediately if need be. It's essentially a glorified permissions system which requires web services to reserve a space on web service B before taking any actions.
My initial thought was to 1. enable authentication of some sort, 2. in the serverside response to a GET call, reserve the space and return the result, and 3. provide immediate "unreservation" of the object via a DELETE call. Is this still being RESTful?
Yes, it's OK to perform actions with rest. What matters is that these actions should be guided by the representations you exchange.
If you think about the way the web works (via a browser), you do this all the time: you get an HTML form that lets you choose a number of actions you can perform. Then, you submit the form (typically via POST) and the action is performed.
It's good to be able to use DELETE via a programmatic client (which is something that non-AJAX requests in browsers wouldn't support), but the overall approach of a RESTful system should be very similar to what you find for websites (i.e. the focus should be on the representations: the equivalent of web pages in your system).
GET shouldn't have side effects, so don't use GET to make the reservation itself, use something like POST instead.
No - unlikely to be restful
From your description ...
2. in the serverside response to a GET call, reserve the space and return the result
GETs should be idempotent. For this reason alone, your service is unlikely to be restful because the state of the system after the first GET is different.
You really need to consider that a Reservation is a resource and should be created with a POST to a reservations container which will return the URI of the new resource in the Location header of the HTTP response. This UrI can be used by Get to return the resource and updated with a PUT
Post should be used to extend an existing resource and Put for replacing the state of a resource. In your case, consider the Post to be updating a list of Reservations and returning the URI of the new resource (not just the I'd). Put can be used for changing the state associated with the resource identified by the UR
You're on the right track, but your reservation of the object should be with a PUT; you're PUTting a reservation on the object, i.e. changing the underlying object.
PUT is the right verb here, since you know what resource you're modifying, and it should be idempotent for multiple requests.