How to model REST URL for which there is no equivalent HTTP method? - rest

I have customers and I want to activate and cancel their plans. I am trying to be as RESTful as possible.
Should the action to perform 'active' or 'suspend' be part of URI ?
1) POST customers/{customerId}/activatePlan/{planName}
2) POST customers/{customerId}/suspendPlan/{planName}
My problem is that both activate and cancel are verbs or actions. They do not have any equivalent HTTP action ( GET, POST, PATCH etc.)
Are my URL's restful ? if not, how to make them REST ful.

Everything is a resource on the RESTful paradigm and these resources are manipulated with one of the HTTP methods (GET, POST, PUT, DELETE, etc ...).
You can create a plan with POST:
POST customers/{customerId}/{planName}
once a plan is created we have to activate or deactivate it and here we have a couple of choices:
Using the action in the URI. We use PUT in this case as the planName resource exists (so it is an update):
PUT customers/{customerId}/{planName}/activate
Set a property on the planName resource (still a PUT as it is an update on the planName resource). The activate property in the body of the HTTP PUT request (i.e.: activate=true or activate=false):
PUT customers/{customerId}/{planName}
then you can use GET to return the status of the planName resource
GET customers/{customerId}/{planName}
and DELETE if you want to remove planName from a customer:
GET customers/{customerId}/{planName}

Are my URL's restful ?
All URI are RESTful -- REST doesn't care what spelling conventions you use for your resource identifiers.
Notice, please, that both of the following URI work exactly as you would expect them to:
https://www.merriam-webster.com/dictionary/activate
https://www.merriam-webster.com/dictionary/cancel
My problem is that both activate and cancel are verbs or actions. They do not have any equivalent HTTP action ( GET, POST, PATCH etc.)
There are a couple of different answers. Perhaps the easiest is to think about how you would design a web site that allowed you to activate and cancel plans. You would probably have a web page for this customers enrollment, and on that page might be a link with some hint, like "cancel". Clicking the link would load a new web page, with a form on it, including a bunch of fields for the customer to fill in. When the customer submits the form, the browser looks at the form, and its meta data, and figures out what request to send to the server.
A "REST API" isn't about putting your domain model on the web - it's about putting your interaction model on the web. We create a collection of documents (resources) that describe the domain, and we get useful work done by moving those documents around the network. See Jim Webber 2011.
Because we are working in the language of documents, REST interfaces are usually based on one of the following ideas
Here is a document; make local edits to your copy of the document, and send it back to the server (GET, PUT, PATCH, DELETE are the primary method tokens you see in this style)
Here is a form; fill in the details and submit it (GET and POST are the method tokens you see in these cases)
If you are unhappy with the use of POST, it may help to review Fielding 2009
POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”

Related

how to design a RESTful api for redeem a coupon?

I am designing a RESTful api for coupon redemption.
Each coupon can be redeemed only once, after redemption the coupon is on longer valid.
(POST) /coupons/{couponCode}/redeem
seems violate the RESTful guidelines since redeem is a verb.
can I just change redeem to redemption?
or can I just use
(POST) /coupons/{couponCode}?
btw I am not quite sure why use POST instead of PATCH, is it because of PATCH is idempotent and POST is not? I mean, when the coupon is redeemed for the first time, it will be marked as redeemed in database, but once it's done, the same request won't update this value anymore.
seems violate the RESTful guidelines since redeem is a verb
REST doesn't care what spelling you use for your resource identifiers.
So all of these choices are fine
POST /coupons/{couponCode}/redeem
POST /coupons/{couponCode}
POST /{couponCode}/redeem
POST /i/am/a/banana
POST /4ccd2f6f-a81e-4b70-b45c-20ce9f8732b5
Identifier spelling conventions are like variable naming conventions; they exist only to ease the burden of people, and are subject to local convention. The machines don't care.
The thing that matters is that the target uri used for your change matches the identifier of the resource in the cache that you want to invalidate.
I am not quite sure why use POST instead of PATCH, is it because of PATCH is idempotent and POST is not?
No. The difference is that PATCH promises that the payload is a patch document, which is to say a representation of a set of edits to the representation of "the" resource, whereas POST just says "this is a message to be processed by the resource".
(Both POST and PATCH are not idempotent, as it happens.)
Imagine a document store, where the documents are about one terabyte in size. You might want to change one of those documents. The natural way to do it is to GET the current representation, make your changes, and then PUT your version of the document back. But if your change is very small, then there's a lot of wasted work carrying duplicated copies of the document around.
So instead, we use PATCH, so that we can instead copy a small representation of the edit, rather than the full document.
POST is more general -- it's an unsafe message with a body, and that's pretty much all it promises. That body might be a new representation of the resource, or a patch to be applied to the current representation, or something entirely different.
why use redeem doesn't violate REST? shouldn't be verbs only HTTP methods?
Because REST is an architectural style, and it says that resource identifiers should be URL (RFC 1738) -- although these days that is generally understood to mean URI (RFC 3986) -- or URN (RFC 8141).
If you look at RFC 3986, I think you will find that the word "verb" doesn't appear anywhere in the document. You can review the ABNF rules for interpreting URI, and there is nothing about verbs in there anywhere.
REST doesn't care -- the URI is, in its primary use case, just an opaque sequence of bytes that are used by the client.
For example, try clicking on this link in your browser, does it work?
https://www.dictionary.com/browse/stop
The fact that "stop" happens to be a verb in English doesn't interfere with its function.
I also see some RESTful design guidelines suggest not to use verbs
Yup, the web is full of advice from people who don't understand the subject, or who do understand the subject and don't articulate it clearly, and so on.
REST doesn't offer enforce any particular URI design style.
In REST, the identifier is just an identifier, like a UUID, a hash signature, or a surrogate key. Within the context of an HTTP message, it doesn't mean anything, it's just a cache key. The message semantics come from the method, not the request-target.
GET /A/post HTTP/1.1
POST /B/get HTTP/1.1
DELETE /C/put HTTP/1.1
PUT /D/patch HTTP/1.1
There's no ambiguity in these request lines, the first token is the method that defines the semantics, the second token is just an arbitrary identifier. The machines will get them right every single time.
Recommended Viewing
Jim Webber, 2011
Stefan Tilkov, 2014
It would be better for you to use a url route where you expose the redeem action. This route should use the POST http request because you will modify a resource on the server, and will take as parameter your couponCode.
(POST) /coupons/redeem/{couponCode}
I don't think there is a difference between redeem and redemption. I think a verb like redeem is better to designate an action.
http PATCH or PUT request can be used too. As a convention, we use PATCH or PUT to update a resource after it has been created to change one of its attributes. If you are willing to use PATCH request to update let's say a coupon that you already created, then you can define a url route without the redeem action. The request body would contain the fields to be updated for the coupon object (for example status from "pending" to "redeemed")
(PATCH / PUT) /coupons/{couponCode}
Many use the following convention:
GET /objects (return list of objects)
GET /objects/id (return object)
PUT /objects/id (update object)
POST /objects (add object)
DELETE /objects/id (remove object)

REST creation without persisting

Right now I have a REST service which creates a report via a POST:
POST http://myhost/reports
The report however is not persisted, and cannot later on be retrieved via a GET:
GET http://myhost/reports/{id}
Instead I return the report immediately in the response to the POST. Am I violating any REST principle here, e.g. anything a POST creates should always be accessible via a GET, or is this setup OK?
The POST method isn't a synonym to the create in CRUD. The POST method is used for any operation that isn't standardized, so as long as you document what it does, you're not violating REST, no matter what you do.
There's no such REST principle saying "anything a POST creates should always be accessible via a GET". This is a common misunderstanding due to conflating REST with CRUD. Read this answer for some clarification on that.
In informal language, what a POST says to the server is "take this data and apply it to the resource identified by the given URI, following the rules you documented for the resource media type."
No, you are not violating REST. As long as your interface is uniform it is up to you to determine what actions the urls of your API perform.
As part of your documentation you simply need to state which methods are valid for certain resources and which aren't. I really like to use the Twitter API as a good example of "What to do"
Example: Twitter REST API
POST statuses/update
does not create an object available for access at
GET statuses/update/3
The action performed by the POST method might not result in a resource
that can be identified by a URI. In this case, either 200 (OK) or 204
(No Content) is the appropriate response status, depending on whether
or not the response includes an entity that describes the result.
So according to the HTTP standard this is okay.

How to edit a resource?

Pardon the simple question, but it seems most searches try to tell me which methods are designed for what actions. Eg, create & edit is PUT, create from plural (articles) is POST, and so on. (If you disagree with this, i was just using it as an example. :)
With that said, how do you initiate a resource edit? To create a resource, with a known url you preform a GET on an non-existing URL. Eg, GET:mysite/resource_one. This then returns a form, and the form submits a PUT to the same address and bam, the resource is created.
Now how do you edit that same resource? With 4 Methods, designed for CRUD, i am having issues because i can only seem to think of one way. To go to a new resource. Eg, GET:mysite/resource_one/edit. This then presents a form with existing data, you edit it, and then the data is submitted to GET:mysite/resource_one. This seems odd to me in a system that seems to be designed to allow full CRUD to be preformed on a resource, without leaving said resource.
So.. what is the proper method? I mean, if GET:mysite/resource_one/edit is right, then why not GET:mysite/resource_one/delete, GET:mysite/resource_two/create, and so on..
Replies much appreciated!
The URL always represents the resource, not the action. Thus, while mysite/resource_one/edit might be a proper URL to a page that initiates editing a resource, it's not a part of the REST API itself, it's part of the web app that uses that REST API to manipulate that resource. Moreover, in that example mysite/resource_one would be a confusing representation of the resource.
To create a new resource, you use POST on the parent resource, with the body of the request containing the data for the new resource. The response contains the URL for the newly created resource.
To update an existing resource, you use PUT on the resource URL, with the body of the request containing either full or partial update of the resource data.

REST Web Services API Design

Just wanted to get feedback on how I am planning to architect my API. Dummy methods below. Here's the structure:
GET http://api.domain.com/1/users/ <-- returns a list of users
POST http://api.domain.com/1/users/add.xml <-- adds user
POST http://api.domain.com/1/users/update.xml <-- updates user
DELETE (or POST?) http://api.domain.com/1/users/delete.xml <-- deletes user
Questions:
Is it OK to use just GET and POST?
Is it a good idea that I plan to rely on the filename to indicate what operation to do (e.g. add.xml to add)? Would it be better to do something like this: POST http://api.domain.com/1/users/add/data.xml?
What's a good way to keep these resources versioned? In my example, I use a /1/ after domain name to indicate version 1. Alternatives would be: http://api1.domain.com... or http://api-1.domain.com... or http://apiv1.domain.com... or http://api-v1.domain.com... or http://api.domain.com/v1/... or
What's the best way to authenticate?
Before you dig into REST, here are some terms you really need to grasp:
Resource - The things/data you want to make available in your API (in your case a "User")
URI - A universally unique ID for a resource. Should mention nothing about the method being performed (e.g. shouldn't contain "add" or "delete"). The structure of your URI however doesn't make your app any more or less RESTful - this is a common misconception.
Uniform Interface - A fixed set of operations you can perform on your resources, in most cases this is HTTP. There are clear definitions for the purpose of each of these HTTP methods.
The most unrestful thing about your URIs as they are right now is that they have information about the operation being performed right in them. URIs are IDs and nothing more!
Let's take a real world example. My name is Nathan. "Nathan" could be considered my ID (or in restful terms URI – for the purpose of this example assume I'm the only "Nathan"). My name/ID doesn't changed based on how you would like to interact with me, e.g. My name wouldn't change to "NathanSayHello" when you wanted to greet me.
It's the same for REST. Your user identified by http://api.domain.com/users/1 doesn't change to http://api.domain.com/users/1/update.xml when you want to update that user. The fact that you want to update that user is implied by the method you're using (e.g. PUT).
Here is my suggestion for your URIs
# Retrieve info about a user
GET http://api.domain.com/user/<id>
# Retrieve set all users
GET http://api.domain.com/users
# Update the user IDed by api.domain.com/user/<id>
PUT http://api.domain.com/user/<id>
# Create a new user. The details (even <id>) are based as the body of the request
POST http://api.domain.com/users
# Delete the user ID'd by api.domain.com/user/<id>
DELETE http://api.domain.com/user/<id>
As for your questions:
Use PUT and DELETE when appropriate and avoid overloading POST to handle these functions as it breaks HTTP's definition of POST. HTTP is your uniform interface. It is your contract with the API user about how they can expect to interact with your service. If you break HTTP, you break this contract.
Remove "add" altogether. Use HTTP's Content-Type header for specifying the mime-type of posted data.
Are you referring to the version of your API or the version of the resource? ETag and other response headers can be used to version the resources.
Many options here. Basic HTTP Auth (easy but insecure), Digest Auth, custom auth like AWS. OAuth is also a possibility. If security is of main importance, I use client side SSL certs.
1) On your design probably not. POST is not idempotent! So you should not use for the update or the delete, instead use PUT and DELETE from Rest
2) A better choice is to use the header Content-Type on the WS call, like: application/xml
3) Also on the header Content-Type u can use it: application-v1.0/xml
4) Not sure if it is the best, but probably the easiest way is to use HTTP's built-in authentication mechanisms in RFC 2617. An example: AWS Authentication
In REST, the HTTP "verb" is used to denote the operation type: you won't be able to express all the CRUD operations with only "GET" and "POST"
no: the URL of the resource is usually where the "document identifier" should appear
The version of the "document" can be transmitted in an HTTP response header upon creation/modification of the said resource. It should be the duty of the server to uniquely identify the resources - trying to do this on the client side will prove a daunting challenge i.e. keeping consistency.
Of course, there are many variations on the topic...
I did authentication based on headers. Something like
X-Username:happy-hamster
X-Password:notmyactualpassword
If you're concerned about security - do it through SSL.
Other implementations exist, of course. For instance, Amazon with their S3:
http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTAuthentication.html
If you don't have ability to make PUT and DELETE requests, it's considered a good practice to tunnel them through POST. In this case the action is specified in URL. If I recall correctly, RoR does exactly this:
POST http://example.com/foos/2.xml/delete
or
POST http://example.com/foos/3.xml/put
...
<foo>
<bar>newbar</bar>
</foo>
It's a bit offtop, but in regards to versioning and REST overall you might want to take a look at CouchDB. Here is a good book available on-line
Using post for create and delete functionality is not a good rest api design strategy. Use Put to create, post to update and delete to delete the resources.
For more information on designing rest apis follow the link - best practices to design rest apis

How do you implement resource "edit" forms in a RESTful way?

We are trying to implement a REST API for an application we have now. We want to expose read/write capabilities for various resources using the REST API. How do we implement the "form" part of this? I get how to expose "read" of our data by creating RESTful URLs that essentially function as method calls and return the data:
GET /restapi/myobject?param=object-id-maybe
...and an XML document representing some data structure is returned. Fine.
But, normally, in a web application, an "edit" would involve two requests: one to load the current version of the resources and populate the form with that data, and one to post the modified data back.
But I don't get how you would do the same thing with HTTP methods that REST is sort of mapped to. It's a PUT, right? Can someone explain this?
(Additional consideration: The UI would be primarily done with AJAX)
--
Update: That definitely helps. But, I am still a bit confused about the server side? Obviously, I am not simply dealing with files here. On the server, the code that answers the requests should be filtering the request method to determine what to do with it? Is that the "switch" between reads and writes?
There are many different alternatives you can use. A good solution is provided at the microformats wiki and has also been referenced by the RESTful JSON crew. As close as you can get to a standard, really.
Operate on a Record
GET /people/1
return the first record
DELETE /people/1
destroy the first record
POST /people/1?_method=DELETE
alias for DELETE, to compensate for browser limitations
GET /people/1/edit
return a form to edit the first record
PUT /people/1
submit fields for updating the first record
POST /people/1?_method=PUT
alias for PUT, to compensate for browser limitations
I think you need to separate data services from web UI. When providing data services, a RESTful system is entirely appropriate, including the use of verbs that browsers can't support (like PUT and DELETE).
When describing a UI, I think most people confuse "RESTful" with "nice, predictable URLs". I wouldn't be all that worried about a purely RESTful URL syntax when you're describing web UI.
If you're submitting the data via plain HTML, you're restricted to doing a POST based form. The URI that the POST request is sent to should not be the URI for the resource being modified. You should either POST to a collection resource that ADDs a newly created resource each time (with the URI for the new resource in the Location header and a 202 status code) or POST to an updater resource that updates a resource with a supplied URI in the request's content (or custom header).
If you're using an XmlHttpRequest object, you can set the method to PUT and submit the data to the resource's URI. This can also work with empty forms if the server supplies a valid URI for the yet-nonexistent resource. The first PUT would create the resource (returning 202). Subsequent PUTs will either do nothing if it's the same data or modify the existing resource (in either case a 200 is returned unless an error occurs).
The load should just be a normal GET request, and the saving of new data should be a POST to the URL which currently has the data...
For example, load the current data from http://www.example.com/record/matt-s-example and then, change the data, and POST back to the same URL with the new data.
A PUT request could be used when creating a new record (i.e. PUT the data at a URL which doesn't currently exist), but in practice just POSTing is probably a better approach to get started with.