RESTful URL for "Activate" - api

I have a resource (project) which can be activated and deactivated.
What's the most RESTful URL endpoint for this purpose?
Right now I'm thinking about /projects/:id/activate and /projects/:id/deactivate, but I don't think that's very RESTful.
In addition, I'm not certain what HTTP method to use.
Can you provide some pointers?
Thanks!

The most conventional way to do this is via POST to /projects/:id, with parameters indicating whether you want to activate or deactivate or something else (always leave room for something else).
note that RESTful URLs should refer to things (like projects), not actions. Then the common methods have clear meanings:
PUT: create or replace the thing
PATCH: set properties of the thing
POST: perform an operation on the
thing
GET: retrieve the thing
DELETE: delete the thing

Your can send your requests just to projects/{id} and use PATCH (as you're updating existing object) verb, e.g.
PATCH /projects/123
[
{ "op": "activate|deactivate", ... }
]
Read more: REST API - PUT vs PATCH with real life examples

I know I am a bit late but maybe this might be useful for others.
You can create a noun from your operation and use it as sub-resource: activate -> activation
Now you can use POST and DELETE on this sub-resource.
For example:
POST /projects/:id/activation <-- activate project
DELETE /projects/:id/activation <-- deleting the activation = deactivate
This pattern can work quite well for operations that toggle between on/off state of something.

Related

what would be the best practice for http request in webapi project with softdelete

I am working on a webapi .Net5 project. I am using SQLserver and EF5 to store my entities. Each of my entities has a property called IsDeleted, which I use for remove(IsDeleted=true) and restore(IsDeleted=false).
I am a bit confused which http request method should I use for my remove/restore endpoints.
I am updating a partial part of my entity (isdeleted), so I was thinking about PATCH
I also don't want to show the client that I am doing soft delete, then for remove, I was thinking about DELETE but I really do not delete any entity from my resources
I was also thinking about PUT, but in both cases, I do not have any request body and therefore it is very rare that a PUT method has not have any body .
I saw in some StackOverflow question and answers that they recommend to use a POST method for restore and DELETE for remove when using the soft delete but did not really understand why.
Anybody knows what would be the correct way of doing that and why?
Using HTTP DELETE to update IsDeleted = true is up to you as the API designer. There's no law saying HTTP DELETE must hard-delete whatever it refers to.
If the client does not know you're soft-deleting the record it'd be entirely appropriate to use DELETE.
I work with a system which has soft-delete, but it is not hidden from the client app / user. So to soft-delete it is either a PUT request to api/some_endpoint/24601 with "status": "ARCHIVED" within the payload, or a POST request to api/some_endpoint/24601/actions with a similar payload. (PATCH may be more appropriate than PUT but the API designers have stuck with PUT throughout.)

How to organize endpoints when using FeathersJS's seemingly restrictive api methods?

I'm trying to figure out if FeathersJS suits my needs. I have looked at several examples and use cases. FeathersJS uses a set of request methods : find, get, create, update, patch and delete. No other methods let alone custom methods can be implemented and used, as confirmed on this other SO post..
Let's imagine this application where users can save their app settings. Careless of following method conventions, I would create an endpoint describing the action that is performed by the user. In this case, we could have, for instance: /saveSettings. Knowing there won't be any setting-finding, -creation, -updating (only some -patching) or -deleting. I might also need a /getSettings route.
My question is: can every action be reduced down to these request methods? To me, these actions are strongly bound to a specific collection/model. Sometimes, we need to create actions that are not bound to a single collection and could potentially interact with more than one collection/model.
For this example, I'm guessing it would be translated in FeathersJS with a service named Setting which would hold two methods: get() and a patch().
If that is the correct approach, it looks to me as if this solution is more server-oriented than client-oriented in the sense that we have to know, client-side, what underlying collection is going to get changed or affected. It feels like we are losing some level of freedom by not having some kind of routing between endpoints and services (like we have in vanilla ExpressJS).
Here's another example: I have a game character that can skill-up. When the user decides to skill-up a particular skill, a request is sent to the server. This endpoint can look like POST: /skillUp What would it be in FeathersJS? by implementing SkillUpService#create?
I hope you get the issue I'm trying to highlight here. Do you have some ideas to share or recommendations on how to organize the API in this particular framework?
I'm not an expert of featherJs, but if you build your database and models with a good logic,
these methods are all you need :
for the settings example, saveSettings corresponds to setting.patch({options}) so to the route settings/:id?options (method PATCH) since the user already has some default settings (created whith the user). getSetting would correspond to setting.find(query)
To create the user AND the settings, I guess you have a method to call setting.create({defaultOptions}) when the user CREATE route is called. This would be the right way.
for the skillUp route, depends on the conception of your database, but I guess it would be something like a table that gives you the level/skills/character, so you need a service for this specific table and to call skillLevel.patch({character, level})
In addition to the correct answer that #gui3 has already given, it is probably worth pointing out that Feathers is intentionally restricting in order to help you create RESTful APIs which focus on resources (data) and a known set of methods you can execute on them.
Aside from the answer you linked, this is also explained in more detail in the FAQ and an introduction to REST API design and why Feathers does what it does can be found in this article: Design patterns for modern web APIs. These are best practises that helped scale the internet (specifically the HTTP protocol) to what it is today and can work really well for creating APIs. If you still want to use the routes you are suggesting (which a not RESTful) then Feathers is not the right tool for the job.
One strategy you may want to consider is using a request parameter in a POST body such as { "action": "type" } and use a switch statement to conditionally perform the desired action. An example of this strategy is discussed in this tutorial.

Using HTTP DELETE method to cancel an action in progress

Background:
I provide a programming interface for people who wish to place orders using my site.
They can use GET and POST methods on /api/v1/orders to place an order and to view list of all orders placed by them. They can also use the GET metod on /api/v1/orders/<order_id> in order to view specific details of one order.
There is a need to provide a way to cancel an order, however the records themselves need to be kept.
I would like to get feedback from more seasoned developers on whether it would be a sane decision to:
a) implement the DELETE verb on /api/v1/current_orders/<order_id>, which would delete it from the list of "current" orders (by marking it as cancelled). The downside is that it will make use of a different noun, which may be confusing.
b) implement the DELETE verb on /api/v1/orders/<order_id> with the same functionality as in a). This is somewhat misleading, as the entity will not really be deleted, and the consumer should be aware of that.
c) implement the POST verb on /api/v1/cancellations/<order_id> (or POST on /api/v1/cancellations with the order_id in the JSON payload). This seems to be less than ideal because a resource will not be created as a result of that request. However, the consequences of using this endpoint seem to be clearer.
d) ...?
Question:
I am aware that there is not always a "perfect" solution to designing endpoints for a REST API, but keeping in mind the need for clarity and intuitiveness and with a high regard for best practices, which of the options is "optimal"?
What about PATCH verb on /api/v1/orders/<order_id> indicating that it is cancelled?
HTTP PATCH : Allows to do partial modifications in an entity. While POST creates a new one, and PUT replaces an existing one, PATCH just updates the properties you are sending, leaves the rest at they are.
You would need only to send something like { isCancelled:true} as HTTP PATCH, then your code would update the entity and take action like cancel any outstanding work.

Is it REST if I pass the following URI /apps/{id}?control=start

I'm in the process of designing a REST API for our web app.
POST > /apps > Creates an app
PUT > /apps/{id} > Updates the app
I want to start the apps.
Is this REST and if not, how can I make it more RESTful?
POST > /apps/{id}?control=start
Sun Cloud API does this: http://kenai.com/projects/suncloudapis/pages/CloudAPISpecificationResourceModels
Or is it better to:
2. PUT /apps/{id} and include a status parameter in the response Json/XML?
3. POST /apps/{id} and include a status parameter in the response Json/xml?
4. POST /apps/start?app={id}
I think the right question here is more whether the HTTP verbs are being used as intended rather than whether the application is or is not as RESTful as possible. However, these days the two concepts are pretty much the same.
The thing about PUT is that whatever you PUT you should be able to immediately GET. In other words, PUT does a wholesale replacement of the resource. If the resource stored at apps/5 is something that has a "control" attribute as part of its state, then the control=start part should be part of the representation you put. If you want to send just the new piece of the resource, you are doing a PATCH, not a PUT.
PATCH is not widely supported, so IMHO you should use a POST. POST has no requirements of safety or idempotency; generally you can do whatever you want with a POST (more or less), including patching parts of a resource. After all that is what you do when you create a new item in a collection with a POST. Updating a portion of a resource is not really much different.
Generally though you POST new data in the request body, not as query parameters. Query parameters are used mostly for GETs, because you are, well, querying. :)
Does starting an app changes it state? (to "running", for example) If it does what you're actually doing is updating the state of the resource (application). That seems like a good use for the PUT operation. Although as Ray said, if control is part of the state of the resource, the body of the PUT request should contain the state you're updating. I believe a partial update would be possible (CouchDB uses this).
On the other hand, if starting an app means creating a new resource (representing the app execution, for example), the POST method would be a great fit. You could have something like this:
POST /app/1/start
Which would result in a HTTP/1.1 201 Created. Then, to access the information on the created execution, you could use a URL like this:
GET /app/1/execution/1
To me, this would seem like a good "Restful" approach. For more information, check out this article.
PUT apps/{id}
I would PUT the app to update it's status from off to on
I like to do something like,
POST /runningapps?url=/app/1

Confused about Http verbs

I get confused when and why should you use specific verbs in REST?
I know basic things like:
Get -> for retrieval
Post -> adding new entity
PUT -> updating
Delete -> for deleting
These attributes are to be used as per the operation I wrote above but I don't understand why?
What will happen if inside Get method in REST I add a new entity or inside POST I update an entity? or may be inside DELETE I add an entity. I know this may be a noob question but I need to understand it. It sounds very confusing to me.
#archil has an excellent explanation of the pitfalls of misusing the verbs, but I would point out that the rules are not quite as rigid as what you've described (at least as far as the protocol is concerned).
GET MUST be safe. That means that a GET request must not change the server state in any substantial way. (The server could do some extra work like logging the request, but will not update any data.)
PUT and DELETE MUST be idempotent. That means that multiple calls to the same URI will have the same effect as one call. So for example, if you want to change a person's name from "Jon" to "Jack" and you do it with a PUT request, that's OK because you could do it one time or 100 times and the person's name would still have been updated to "Jack".
POST makes no guarantees about safety or idempotency. That means you can technically do whatever you want with a POST request. However, you will lose any advantage that clients can take of those assumptions. For example, you could use POST to do a search, which is semantically more of a GET request. There won't be any problems, but browsers (or proxies or other agents) would never cache the results of that search because it can't assume that nothing changed as a result of the request. Further, web crawlers would never perform a POST request because it could not assume the operation was safe.
The entire HTML version of the world wide web gets along pretty well without PUT or DELETE and it's perfectly fine to do deletes or updates with POST, but if you can support PUT and DELETE for updates and deletes (and other idempotent operations) it's just a little better because agents can assume that the operation is idempotent.
See the official W3C documentation for the real nitty gritty on safety and idempotency.
Protocol is protocol. It is meant to define every rule related to it. Http is protocol too. All of above rules (including http verb rules) are defined by http protocol, and the usage is defined by http protocol. If you do not follow these rules, only you will understand what happens inside your service. It will not follow rules of the protocol and will be confusing for other users. There was an example, one time, about famous photo site (does not matter which) that did delete pictures with GET request. Once the user of that site installed the google desktop search program, that archieves the pages locally. As that program knew that GET operations are only used to get data, and should not affect anything, it made GET requests to every available url (including those GET-delete urls). As the user was logged in and the cookie was in browser, there were no authorization problems. And the result - all of the user photos were deleted on server, because of incorrect usage of http protocol and GET verb. That's why you should always follow the rules of protocol you are using. Although technically possible, it is not right to override defined rules.
Using GET to delete a resource would be like having a function named and documented to add something to an array that deletes something from the array under the hood. REST has only a few well defined methods (the HTTP verbs). Users of your service will expect that your service stick to these definition otherwise it's not a RESTful web service.
If you do so, you cannot claim that your interface is RESTful. The REST principle mandates that the specified verbs perform the actions that you have mentioned. If they don't, then it can't be called a RESTful interface.