Is it wrong to use POST for everything in REST? I know POST is for updating and creating but what if I use it for SELECTS and DELETS as well? What I basically need is a web service that can do CRUD operations to a database. Im using PHP. Also, what if I use query strings to do the POST request instead of using JSON or XML?
If you're using POST for all operations, you can't really call it REST anymore.
So it's not wrong, but it's not REST either :)
Yes, it's wrong. If you are using POST for anything other than updating you aren't actually following the REST convention.
You can eat soup with fork but why? Anyway you can use any method, just don't call it REST protocol.
Is it wrong to use POST for everything in REST?
You can't use POST for everything in REST (e.g. only for requests, not responses), so the question about wrong or right is not a valid question.
I know POST is for updating and creating but what if I use it for SELECTS and DELETS as well?
It normally just works.
What I basically need is a web service that can do CRUD operations to a database.
That's fine.
Im using PHP.
That's fine, too. PHP hast support for the HEAD, GET and POST method. For the PUT and DELETE methods you need to do a little bit more coding.
Also, what if I use query strings to do the POST request instead of using JSON or XML?
You use query strings instead of JSON/XML request bodies. REST does not specify the protocol, so you can do whatever pleases you. Using "query strings" might be a good idea with PHP as PHP supports those out of the box. But it depends what you use for a handler or what you want to support.
As your questions are very broad, you might want to read some basic description of REST first before so you can more specifically ask: A Brief Introduction to REST.
It's wrong to use POST for calls that are meant to be repeatable.
POST calls are never cached but your select calls should be cache-able (and repeatable) so you shouldn't be using POST for them.
But there's no technical reason why you can't force everything through POST, (particularly as DELETE isn't supported across all browsers), but it does mean that caching won't work for any of your calls, and also that your users may not be able to refresh a web page without being asked to confirm page reload if POST calls have been made to create it.
At this REST tutorial here the 4th article in the series says:
For creation, updating, and deleting data, use POST requests. (POST can also be used for read-only queries, as noted above, when complex parameters are required.)
Of course GET is usually used for read-only queries, so putting it all together, if complexity is the default assumption, which is kind of a handy assumption when no threshold between complexity and simplicity is stated, then this guy who is enough an authority to write a whole series on REST is saying that it's okay to POST everything. May be caches make some assumptions about responses to various HTTP verbs that might be beneficial but if your application does not benefit from caching (indeed, might be harmed by it, so disable it or do something so your application does not suffer from it) then I don't know if there's any problem at all.
Related
I have researched APIs and I generally understand how they work and how to use them (HTTP request to API, get data and parse it, etc.), however, for my project I need to use data that I collected myself so I can't just use another database for example. I'm quite new to this so I don't understand a few things. I'll try to explain my plan as clearly as possible. Please let me know if any additional explanation is required.
I have an HTML form which can be filled out and saved. This form is not supposed to be local, but rather on a server
I read a lot about XML-files and API's and I also saw many similar questions on here but I'm not sure what applies to my instance.
I wanted to store the information from the form in an XML-file. Some people said, that this could be done with JavaScript, some people said this would require some server-side script. What applies in this case? I would guess that I need a server-side script but as I said, I'm kinda at loss here.
I thought I could simply use JavaScript to store whatever is entered into the form and use python or php to create an XML-file in which I store this information. This XML-file would then be used by the API. This is were I have trouble understanding.
The edited form is supposed to be saved (on the server I guess, so several people can access it), so you can go back to it later and edit it again. How exactly would I implement an API here? Can I just "make" my own XML-file, which the API uses as database? Is there any better way to do this?
I know this probably seems like a stupid question but I really want to understand this so bear with me. I'm very much overwhelmed by this task so I appreciate any help.
I need some advice on website design.
Lets take example of twitter for my question. Lets say I am making twitter. Now on the home_page.php ,I need both, Data about tweets (Tweet id , who tweeted , tweet time etc. etc) and Data about the user( userId , username , user profile pic).
Now to display all this, I have two option in mind..
1) Making separate php files like tweets.php and userDetails.php. By using AJAX queries, I can get the data on the home_page.php.
2) Adding all the php code (connecting to db, fetching data ) in the home_page.php itself.
In option one, I need to make many HTTP requests, which (i think) will be load to the network. So it might slow down the website.
But option two, I will have a defined REST API. Which will be good of adding more features in the future.
Please give me some advice on picking the best. Also I am still a learner, so if there are more options of implementing this, please share.
In number 1 you're reliant on java-script which doesn't follow progressive enhancement or graceful degradation; if a user doesn't have JS they will see zero content which is obviously bad.
Split your code into manageable php files to make it easier to read and require them all in one main php file; this wont take any extra http requests because all the includes are done server side and 1 page is sent back.
You can add additional javascript to grab more "tweets" like twitter does, but dont make the main functionality rely on javascript.
Don't think of PHP applications as a collection of PHP files that map to different URLs. A single PHP file should handle all your requests and include functionality as needed.
In network programming, it's usually good to minimize the number of network requests, because each request introduces an overhead beyond the time it takes for the raw data to be transmitted (due to protocol-specific information being transmitted and the time it takes to establish a connection for example).
Don't rely on JavaScript. JavaScript can be used for usability enhancements, but must not be used to provide essential functionality of your application.
Adding to Kiee's answer:
It can also depend on the size of your content. If your tweets and user info is very large, the response the single PHP file will take considerable time to prepare and deliver. Then you should go for a "minimal viable response" (i.e. last 10 tweets + 10 most popular users, or similar).
But what you definitely will have to do: create an API to bring your page to life. No matter which approach you will use...
So, I was looking through some articles on creating REST API's.
And some of them suggest using all types of HTTP requests: like PUT DELETE POST GET.
We would create for example index.php and write API this way:
$method = $_SERVER['REQUEST_METHOD'];
$request = split("/", substr(#$_SERVER['PATH_INFO'], 1));
switch ($method) {
case 'PUT':
....some put action....
break;
case 'POST':
....some post action....
break;
case 'GET':
....some get action....
break;
case 'DELETE':
....some delete action....
break;
}
OK, granted - I don't know much about web services (yet).
But, wouldn't it be easier to just accept JSON object through regular POST or GET (that would contain method name and all parameters) and then respond in JSON as well. We can easily serialize/deserialize via PHP's json_encode() and json_decode() and do whatever we want with that data without having to deal with different HTTP request methods.
Am I missing something?
UPDATE 1:
Ok - after digging through various API's and learning a lot about XML-RPC, JSON-RPC, SOAP, REST I came to a conclusion that this type of API is sound. Actually stack exchange is pretty much using this approach on their sites and I do think that these people know what they are doing Stack Exchange API.
The idea of REpresentational State Transfer is not about accessing data in the simplest way possible.
You suggested using post requests to access JSON, which is a perfectly valid way to access/manipulate data.
REST is a methodology for meaningful access of data. When you see a request in REST, it should immediately be apparant what is happening with the data.
For example:
GET: /cars/make/chevrolet
is likely going to return a list of chevy cars. A good REST api might even incorporate some output options in the querystring like ?output=json or ?output=html which would allow the accessor to decide what format the information should be encoded in.
After a bit of thinking about how to reasonably incorporate data typing into a REST API, I've concluded that the best way to specify the type of data explicitly would be via the already existing file extension such as .js, .json, .html, or .xml. A missing file extension would default to whatever format is default (such as JSON); a file extension that's not supported could return a 501 Not Implemented status code.
Another example:
POST: /cars/
{ make:chevrolet, model:malibu, colors:[red, green, blue, grey] }
is likely going to create a new chevy malibu in the db with the associated colors. I say likely as the REST api does not need to be directly related to the database structure. It is just a masking interface so that the true data is protected (think of it like accessors and mutators for a database structure).
Now we need to move onto the issue of idempotence. Usually REST implements CRUD over HTTP. HTTP uses GET, PUT, POST and DELETE for the requests.
A very simplistic implementation of REST could use the following CRUD mapping:
Create -> Post
Read -> Get
Update -> Put
Delete -> Delete
There is an issue with this implementation: Post is defined as a non-idempotent method. This means that subsequent calls of the same Post method will result in different server states. Get, Put, and Delete, are idempotent; which means that calling them multiple times should result in an identical server state.
This means that a request such as:
Delete: /cars/oldest
could actually be implemented as:
Post: /cars/oldest?action=delete
Whereas
Delete: /cars/id/123456
will result in the same server state if you call it once, or if you call it 1000 times.
A better way of handling the removal of the oldest item would be to request:
Get: /cars/oldest
and use the ID from the resulting data to make a delete request:
Delete: /cars/id/[oldest id]
An issue with this method would be if another /cars item was added between when /oldest was requested and when the delete was issued.
This is a security and maintainability question.
safe methods
Whenever possible, you should use 'safe' (unidirectional) methods such as GET and HEAD in order to limit potential vulnerability.
idempotent methods
Whenever possible, you should use 'idempotent' methods such as GET, HEAD, PUT and DELETE, which can't have side effects and are therefore less error prone/easier to control.
Source
In short, REST emphasizes nouns over verbs. As your API becomes more complex, you add more things, rather than more commands.
You asked:
wouldn't it be easier to just accept JSON object through normal $_POST and then respond in JSON as well
From the Wikipedia on REST:
RESTful applications maximize the use of the pre-existing, well-defined interface and other built-in capabilities provided by the chosen network protocol, and minimize the addition of new application-specific features on top of it
From what (little) I've seen, I believe this is usually accomplished by maximizing the use of existing HTTP verbs, and designing a URL scheme for your service that is as powerful and self-evident as possible.
Custom data protocols (even if they are built on top of standard ones, such as SOAP or JSON) are discouraged, and should be minimized to best conform to the REST ideology.
SOAP RPC over HTTP, on the other hand, encourages each application designer to define a new and arbitrary vocabulary of nouns and verbs (for example getUsers(), savePurchaseOrder(...)), usually overlaid onto the HTTP 'POST' verb. This disregards many of HTTP's existing capabilities such as authentication, caching and content type negotiation, and may leave the application designer re-inventing many of these features within the new vocabulary.
The actual objects you are working with can be in any format. The idea is to reuse as much of HTTP as possible to expose your operations the user wants to perform on those resource (queries, state management/mutation, deletion).
You asked:
Am I missing something?
There is a lot more to know about REST and the URI syntax/HTTP verbs themselves. For example, some of the verbs are idempotent, others aren't. I didn't see anything about this in your question, so I didn't bother trying to dive into it. The other answers and Wikipedia both have a lot of good information.
Also, there is a lot to learn about the various network technologies built on top of HTTP that you can take advantage of if you're using a truly restful API. I'd start with authentication.
In regards to using extension to define data type.
I noticed that MailChimp API is doing it, but I don't think this is a good idea.
GET /zzz/cars.json/1
GET /zzz/cars.xml/1
My sound like a good idea, but I think "older" approach is better - using HTTP headers
GET /xxx/cars/1
Accept: application/json
Also HTTP headers are much better for cross data type communication (if ever someone would need it)
POST /zzz/cars
Content-Type: application/xml <--- indicates we sent XML to server
Accept: application/json <--- indicates we want get data back in JSON format
Am I missing something?
Yes. ;-)
This phenomenon exists because of the uniform interface constraint. REST likes using already existing standards instead of reinventing the wheel. The HTTP standard has already proven to be highly scalable (the web is working for a while). Why should we fix something which is not broken?!
note: The uniform interface constraint is important if you want to decouple the clients from the service. It is similar to defining interfaces for classes in order to decouple them from each other. Ofc. in here the uniform interface consists of standards like HTTP, MIME types, URI, RDF, linked data vocabs, hydra vocab, etc...
Good Semantics is important in programming.
Utilizing more methods besides GET/POST will be helpful because it will increase the readability of your code and make it easier to maintain.
Why?
Because you know GET will retrieve data from your api. You know POST will add new data to your system. You know PUT will make updates. DELETE will delete rows etc, etc,
I normally structure my RESTFUL Web Services so that I have a function callback named the same thing as the method.
I use PHP, so I use function_exists (I think its called). If the function doesn't exist, I throw a 405 (METHOD NOT ALLOWED).
Bill Venners: In your blog post entitled "Why REST Failed," you said that we need all four HTTP verbs—GET, POST, PUT, and DELETE— and lamented that browser vendors only GET and POST." Why do we need all four verbs? Why aren't GET and POST enough?
Elliotte Rusty Harold: There are four basic methods in HTTP: GET, POST, PUT, and DELETE. GET is used most of the time. It is used for anything that's safe, that doesn't cause any side effects. GET is able to be bookmarked, cached, linked to, passed through a proxy server. It is a very powerful operation, a very useful operation.
POST by contrast is perhaps the most powerful operation. It can do anything. There are no limits as to what can happen, and as a result, you have to be very careful with it. You don't bookmark it. You don't cache it. You don't pre-fetch it. You don't do anything with a POST without asking the user. Do you want to do this? If the user presses the button, you can POST some content. But you're not going to look at all the buttons on a page, and start randomly pressing them. By contrast browsers might look at all the links on the page and pre-fetch them, or pre-fetch the ones they think are most likely to be followed next. And in fact some browsers and Firefox extensions and various other tools have tried to do that at one point or another.
PUT and DELETE are in the middle between GET and POST. The difference between PUT or DELETE and POST is that PUT and DELETE are *idempotent, whereas POST is not. PUT and DELETE can be repeated if necessary. Let's say you're trying to upload a new page to a site. Say you want to create a new page at http://www.example.com/foo.html, so you type your content and you PUT it at that URL. The server creates that page at that URL that you supply. Now, let's suppose for some reason your network connection goes down. You aren't sure, did the request get through or not? Maybe the network is slow. Maybe there was a proxy server problem. So it's perfectly OK to try it again, or again—as many times as you like. Because PUTTING the same document to the same URL ten times won't be any different than putting it once. The same is true for DELETE. You can DELETE something ten times, and that's the same as deleting it once.
By contrast, POST, may cause something different to happen each time. Imagine you are checking out of an online store by pressing the buy button. If you send that POST request again, you could end up buying everything in your cart a second time. If you send it again, you've bought it a third time. That's why browsers have to be very careful about repeating POST operations without explicit user consent, because POST may cause two things to happen if you do it twice, three things if you do it three times. With PUT and DELETE, there's a big difference between zero requests and one, but there's no difference between one request and ten.
Please visit the url for more details. http://www.artima.com/lejava/articles/why_put_and_delete.html
Update:
Idempotent methods
An idempotent HTTP method is a HTTP method that can be called many times without different outcomes. It would not matter if the method is called only once, or ten times over. The result should be the same. Again, this only applies to the result, not the resource itself. This still can be manipulated (like an update-timestamp, provided this information is not shared in the (current) resource representation.
Consider the following examples:
a = 4;
a++;
The first example is idempotent: no matter how many times we execute this statement, a will always be 4. The second example is not idempotent. Executing this 10 times will result in a different outcome as when running 5 times. Since both examples are changing the value of a, both are non-safe methods.
Basically REST is (wiki):
Client–server architecture
Statelessness
Cacheability
Layered system
Code on demand (optional)
Uniform interface
REST is not protocol, it is principles.
Different uris and methods - somebody so called best practices.
I need to generate HTML snippets using jQuery. The creation of those snippets depends on some data. The data is stored server-side, in session (where PHP is used).
At the moment I achieved this
- retrieving the data from the server via AJAX in form of JSON
- and building the snippets via specific javascript functions that read those data
The problem is that the complexity of the data is getting bigger and hence the serialization into JSON is getting even more difficult since I can't do it automatically.
I can't do it automatically because some information are sensible so I generate a "stripped" version to send to the client.
I know it is difficult to understand without any code to read, but I am hoping this is a common scenario and would be glad for any tip, suggestion or even design-pattern you can give me.
Should I store both a complete and a stripped data on the server and then use some library to automatically generate the JSON from the stripped data? But this also means I have to get the two data synchronized.
Or maybe I could move the logic server-side, this way avoiding sending the data. But this means sending javascript code (since I rely on jQuery). Maybe not a good idea.
Feel free to ask me more details if this is not clear.
Thank you for any help
There are several Javascript/jQuery templating solutions available. John Resig is working on one that's likely to become a popular jQuery add-on, if not part of the core distribution. Kyle Simpson is also doing one.
I googled for a reference to it, but really I'd suggest doing your own searching because there's lots of good information out there.
edit well here's a pretty good link: http://www.west-wind.com/Weblog/posts/509108.aspx
You can use PHP's json_encode and json_decode methods to convert native PHP objects into JSON data representation.
So...
I've been reading about REST a little bit, and the idea behind it sounds nice, but the question is, can it be easily integrated into the standard flow of a webpage?
For example, a user creates some sort of item, a blog post or what have you, and now he wants to delete it, so he clicks a 'delete' link on the page. Now what? How do we issue a DELETE request to, say, http://mysite.com/posts/5? And how do we handle that request? I have no experience with cURL or anything, but from the looks of it, I would have to curl_init('http://mysite.com/posts/5') and then work some magic. But where would I even put that script? That would have to be on another page, which would break the whole idea of REST. Then I would just be GETing another page, which would in turn DELETE the page I originally intended?
Is this why people rarely use REST or is there actually a nice way to do this?
Looks like I need to clarify. People are suggesting I include words like "DELETE" and "POST" in the URL. I believe REST dictates that we have a unique URL for each resource but not for each action on that resource. I assume this also means that we only have one and only one URL for each resource. i.e. I want to be able to DELETE or VIEW the contents of a particular post from one URL (by sending either DELETE, PUT, POST, or GET), not different URLs with additional params
With a restful server, the same url (say /books/1) can respond to many different verbs. Those verbs, GET, POST, PUT, and DELETE, together with the path, indicate what you want to do to the data on the server. The response tells you the answer to your request.
REST is about accessing data in a predictable and sensible way.
If you come from a strong PHP background, where every url has to map to a particular file, you're right, it doesn't really make sense. The two most visible RESTful development environments, ASP.NET MVC and Rails, each have special servers (or server logic) which read the verbs and do that special routing for you. That's what lets the "normal flow" of the application go through as you'd expect. For PHP, there are frameworks that help with this, such as WSO2's WSF.
How REST works with Web Browsers
Take, for instance, your example. We have posts, and we want to delete one.
We start by visiting a url like /posts/4. As we would expect, this shows post 4, its attributes, and some actions you could take on it. The request to render this url would look like GET /posts/4. The response contains HTML that describes the item.
The user clicks the "Delete Item 4" link, part of the HTML. This sends a request like DELETE /posts/4 to the server. Notice, this has re-used the /posts/4 url, but the logic must be different.
Of HTML forms and web browsers, many of them will change a link with method="delete" into a method="post" link by default. You will need to use Javascript (something like this) to change the verb. Ruby on Rails uses a hidden input field (_method) to indicate which method is to be used on a form, as an alternative.
On the server side, the "delete an item" logic is executed. It knows to execute this because of the verb in the request (DELETE), which matches the action being performed. That's a key point of REST, that the HTTP verbs become meaningful.
After deleting the item, you could respond with a page like "yep, done," or "no, sorry, you can't do that," but for a browser it makes more sense to put you somewhere else. The item being deleted, responding with a redirect to GET /posts makes good sense.
If you look at the server log, it will be very clear what everybody did to the server, but that's not as important as...
How REST works with Arbitrary Data
Another key point of REST is that it works well with multiple data formats. Suppose you were writing a program that wanted to read and interact with the blog programmatically. You might want all the posts given in XML, rather than having to scrape the HTML for information.
GET /posts/4.xml is intuitive: "Server, please give me xml describing post #4." The response will be that xml. A RESTful server makes it obvious how to get the information you want.
When you made the DELETE /posts/4.xml request, you're asking, "Server, please delete item #4." A response like, "Okay, sure," is usually sufficient to express what's happened. The program can then decide what else it wants and make another request.
Well one way is to make an AJAX call using the DELETE method.
Facebook's REST server is a pseudo one, you can do it like them, asking for the post method: POST, GET, etc. the action and the other values you need for that request.
Why I say facebook is a pseudo REST server? : well, one of the Principles of REST says
Every resource is uniquely addressable using a universal syntax for use in hypermedia links
in facebook you only have /server.php and there is where you make the request, even for (POST, GET, PUT, DELETE...)
the other way is using mod_rewrite and parse the url the client is requesting
EDIT: just found this, looks interesting. Have fun!
I don't think REST is rarely used. You're using it right now, on StackOverflow. As far as your specific example goes, you can send DELETE requests though XMLHttpRequest in browsers that support it. When JS is off, or for non-compliant browsers, you can do something like:
POST http://foo.com/delete?post=5
Not ideal, but still more restful than many sites.
EDIT: Changed to POST
Depending on what framework you use, there are models that determine how actions are handled for each resource.
Basically using another parameter, you want to send the resource what action to perform. That parameter may be sent through AJAX/JS for example.
If you want to do it without javascript/ajax (in case it's disabled), then a form POST method would work as well, sending the resource the extra ACTION parameter.
Of course, in both cases, you have to consider security, and make sure that they're not sending the resource an action they shouldn't be. Make sure to do your checking on the backend, and send an appropriate response or error message.
Client side scripting, whether through JS/Ajax or form POST or other methods require the extra security precaution.
Edited after clarification from poster.
Don't overthink it. You're not going to be able to do this with straight HTML forms and a browser. They do not support DELETE method. Ajax can do it.
I want to be able to DELETE to VIEW
the contents of a particular post from
one URL (by sending either DELETE,
PUT, POST, or GET), not different URLs
with additional params
Delete to view? I'm not sure I understand it, but your delete should be done through the headers, not through the URL. The delete method should not return a view. REST is a service, not all requests are meant for visual consumption.
If you really have no choice about using the DELETE verb then I would suggest something like the following:
POST http://mysite.com/Trashcan?resourceUrl=/Customer/75
What url you use really does not matter to REST, however, it is easier to understand the REST way of interacting if your urls avoid verbs completely.
I have seen so many questions from both Rails and ASP.NET MVC users who need to go beyond the standard "actions" and it is so tempting to just add a new action on the controller. The problem with doing this is that you just threw away the uniform interface constraint of REST.
The trashcan metaphor is not the only way of doing deletes restfully but I would argue that it is just as clear to read as putting a "delete" in the url.
Here are some more "noun-based" ways of replacing verbs.
POST http://mysite.com/Printer/75/PrintQueue?url=http://mysite.com/Document/xyz
POST http://mysite.com/CurrentLogins?user=bob
POST http://mysite.com/QueryProcessor?query=FindMyInformation
POST http://mysite.com/SearchEngine?searchTerms=cat,blue,furry
POST http://mysite.com/OrderProcessor?cart=http://mysite.com/user/2323/cart
Sometimes you have to think out of the box a little to come up with a noun based url, and may seem pedantic to try and do this, but for me the benefit comes from the ability to manage my variables. I am going to have a variable number of resources in my interface, no matter what I do, if I can fix the number of verbs that can operate on those resources then I reduce one of my variables.
Another way of doing it, assuming a webbased/webapplication-based request, is have 2 submitbuttons. Since PUT and DELETE use the same uri/url. You could add a specific delete form and attach a specific name to this delete-button, so when this is sent via a post, you can use this button-name to turn the action into a DELETE