I am in the process of designing an HTTP API.
I have a Card resource which has an Balance property, which clients can add/subtract to.
At first I thought this should be implemented as PUT, because it's a form of Update to the resource, but then I read that PUT is idempotent, but adding to an amount isn't idempotent.
As it's not a creation of an object, I think I'm left with referring to it as a controller, something like:
POST example.org/card/{card-Id}/AddToBalance
data: value=10
will add 10 to the balance.
Is there a better way?
Yea, use cases like these are not where REST excels (expressing operations, particularly when they only affect a small subset of an entities data). Your particular case is pretty simple though, you can handle it with a slight change to your verb and endpoint:
PUT example.org/card/{card-Id}/balance
{"value" : 100}
Basically read as "Update the balance of card {id} to 100". On the server side you will still need to validate the transaction, and determine wether its a valid add based off the existing value of the balance.
Design Looks good as for as REST principals are concerned.
PUT action should be Idempotent. But it depends upon you requirement
Other thing you can use PATCH, as you are just doing partial amount of Updates rather than complete replacement of resources.
Related
I'm building an API to allow the client of the API to send notifications to remind a user to update an Order status. So far, there are two notifications:
when the user hasn't marked the order as received;
when the user hasn't marked the order as done.
I want to build this API to make it simple to extend to other notifications related to the order, but keep a simple URI for the clients of this API.
How can I define my resources in order to keep my API RESTFul?
I was thinking about having one of these structures:
Option 1:
POST: /api/ordernotification/receive/{id}
POST: /api/ordernotification/complete/{id}
Option 2 (omit the status from the resource and post it instead):
POST: /api/ordernotification/?id={id}&statusID={statusID}
EDIT
Option 2.1 (keeping an articulated URI, as suggested by #Jazimov):
POST: /api/ordernotification/{statusID}/{id}.
Which option is more appropriate? Is there any advantage that one option has over the other? Or are there any other option I haven't thought of?
I would go with something along these lines
POST /api/order/1234/notifications/not-received
POST /api/order/1234/notifications/not-completed
Which can later be accessed via
GET /api/order/1234/notifications/not-received
GET /api/order/1234/notifications/not-completed
Or
GET /api/order/1234/notification/8899
There's no real limitation on how semantically rich a URI can be, so you might as well take advantage of that and be explicit.
If I understand you correctly, you have two types of ordernotifications: those for notifying receive and those for notifying complete. If those are two separate data models then I think nesting them is a good idea (i.e. a table called ReceiveOrderNotification and CompleteOrderNotification). If that's the case then you may want to expose two different endpoints entirely, such as POST /api/receiveordernotification and POST /api/completeordernotification.
But I don't think that's the best you can do, given so many overlapping similarities there probably are between order notifications. Now, option 2 is more like a GET, since you're using query parameters, so with your first option let's collapse them into this:
POST: /api/ordernotification/
and then pass it some JSON data to create the notifications
{
"orderId": "orderId",
"userId": "userId",
"prompt": "not marked received/not marked done"
}
I also removed the /{id} because when you POST you create a brand new thing and the id has not been created yet, usually. Even if the client is creating an id and sending it to the API it is a good practice to leave it open so your API can handle creating a new, unique resource in its own way.
This is RESTful is because a POST creates a resource ordernotification with certain data points. Your first option made actions a resource in themselves but that's probably not represented in any data model in your backend. To be as RESTful as possible, your API endpoints should represent the database domains (tables, collections, etc). Then you let your controllers choose what service methods to use given the data sent in the request. Otherwise REST endpoints expose all the logic up front and get to be a long list of unmaintainable endpoints.
I think, to update status of already inserted records, your endpoint should be PUT instead of POST.
You can use
PUT: /api/ordernotification/:id/status/
with clients json data
{
"status": "your_status"
}
according to request data, endpoint should update the record.
I'm learning how to design a RESTful API and I've come across a quandary.
Say I have a POST endpoint to perform an action. The action has a certain cost associated with it. The cost depends on what the action is, particularly, on the body of the POST. For example, given these two requests:
POST /flooblinate
{"intensity": 50, "colorful": true, "blargs": [{"norg": 43}]}
POST /flooblinate
{"intensity": 100, "colorful": false, "blargs": []}
Say the first one costs 500 and the second one costs 740.
I want to create a method which will tell me what the cost of posting the action will be. Since I am not creating or updating anything, it seems that GET is the most appropriate verb. However, a request body with GET should not have any meaning. This means that I'd have to put the data in the query string, say by URL encoding the request body to be passed to the POST:
GET /flooblinate/getCost?body=%7B%22intensity%22%3A+50%2C+%22colorful%22%3A+true%2C+%22blargs%22%3A+%5B%7B%22norg%22%3A+43%7D%5D%7D
This seems less than ideal since it's two data formats for the same thing. But the following:
POST /flooblinate/getCost
{"intensity": 50, "colorful": true, "blargs": [{"norg": 43}]}
This also seems less than ideal since it's abusing the POST verb to query information, instead of to create or update something.
What's the correct choice to make, here? Is there any third alternative? Is there a way to rethink this design fundamentally which will obviate the need to make this choice?
Personally I'm not for adding dryRyn flags. I try to avoid boolean flags in general unless they're really required.
I've two ideas to cover this scenario:
One is to introduce state on the backend site, e.g. STARTED, FINISHED. When given resource action is submitted it has STARTED state and calculated cost which cam be viewed via GET method. Such resource may be modified with PUT and PATCH methods and is submitted when given method changes its state to FINISHED. Resources that didn't change its state for given amount of time are removed are their state is changed to other terminal value.
Second idea is to introduce a new endpoint called e.g. /calculations. If you need to calculate the cost of given action you just send the same payload (via POST) to this endpoint and in return a cost is given. Then resource send may be kept on server for some established TTL or kept forever.
In all the scenarios given (including yours) there's a need to make at least two requests.
The nicest choice here seems to be to have the endpoints return the info that need querying, and add a dryRun parameter to those endpoints. Thus:
POST /flooblinate?dryRun=true
{"intensity": 50, "colorful": true, "blargs": [{"norg": 43}]}
Returns:
{"cost": 500, /* whatever else */
And then posting with dryRun=false actually commits the action.
Say I have a table for machines, and one of the columns is called status. This can be either active, inactive, or discarded. A discarded machine is no longer useful and it only used for transaction purposes.
Assume now I want to discard a machine. Since this is an entry update, RESTfully, this would be a PUT request to /machines/:id. However, since this is a very special kind of an update, there could be other operations that would occur as well (for instance, remove any assigned users and what not).
So should this be more like a POST to /machines/:id/discard?
From a strict REST perspective, have you considered implementing a PATCH? In this manner, you can have it update just that status field and then also tie it in to updating everything else that is necessary?
References:
https://www.mnot.net/blog/2012/09/05/patch
http://jasonsirota.com/rest-partial-updates-use-post-put-or-patch
I think the most generic way would be to POST a Machine object with { status: 'discarded' } to /machines/:id/.
Personally, I'd prefer the /machines/:id/discard approach, though. It might not be exactly in accordance with the spec, but it's more clear and easier to filter. For example, some users might be allowed to update a machine but not "archive" it.
Personally I think post should be used when the resource Id is either unknown or not relevant to the update being made.
This would make put the method I would use especially since you have other status types that will also need to be updated
path
/machines/id
Message body
{"status":"discarded"}
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.
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