views:

203

answers:

5

I read a lot of Restful tutorials for PHP.

(I don't want to go in depth into why I am not using RoR. It is due to the team being more familiar with PHP)

Because we are planning for future expansion into having APIs i read that it is important to implement Restful web services.

I have looked at tutorials such as

http://www.gen-x-design.com/archives/create-a-rest-api-with-php/

Apparently restful is meant for webservices.

What about for webpages? can they be RESTFUL as well?

if the answer is NO, please do not go beyond this line AND just tell me. Thank you.

i know to make the urls look like RESTFUL urls is to simply use mod_rewrite. However, i am quite sure, restful architecture goes beyond just making the urls look nice.

For eg, i have a list of items on a webpage called list.php . Each item has a delete link next to it. E.g., list.php?id=1&deleteitem

What happens is that when someone clicks on the list.php?id=1&deleteitem link, of course i go back to the same list.php file and check for the param deleteitem in $_GET.

If detected, i will then delete from database based on the param id in $_GET.

After which i will redirect back to list.php WITHOUT any params.

I am wondering, how do i make this whole flow RESTFUL?

I am asking because in REST, to make delete something you need to use HTTP request method (DELETE).

Clearly in my links they are all just simply <a href="list.php?id=1&deleteitem">Delete</a>

Please enlighten me.

My programming is not that strong and it would be good if the advice given can be as layman as possible.

Thank you.

EDIT

I have 2 follow up questions.

question 1) Since this is a list of items with paging, how would the URL look like if i want to make it RESTful?

question 2) Since i am putting DELETE links next to every one of the items in the list, I understand now, i should use

<form method="POST">
<input type=hidden name="_method" value="delete">
<input type="submit" >
</form>

instead.

however the form should be posted to where? the item url? /items/{item-id}

But i want to go back to this listing page displaying a success message AFTER successfully deleting the row in database.

I also want to avoid a popup message when i refresh this listing page with success message.

If i post back to this list.php url, then it is not RESTful yes? because i am told by the answers below that each item is a resource which needs its own url.

Please enlighten me. Thank you.

+1  A: 

Restful approach can surely be used in web pages as well. Putting commands in an URL is not a good idea, due to the side effects you are mentioning. When you change the database (or do whatever that changes the model), use POST commands.

Of course, you don't have PUT and DELTE in major web browsers, but you can always send a simple POST with some specific parameter like method = "PUT", method="DELETE" etc.

naivists
I'd call the parameter method=PUT or method=DELETE :D
aefxx
aefxx: good idea, of course "method" makes more sense than "job"
naivists
I have a question. For forms using POST, i do not want my user to see the popup window when they use the back and refresh buttons on their browser. So how do i overcome this while still be RESTful?
keisimone
You can avoid duplicate form submissions with http://en.wikipedia.org/wiki/Post/Redirect/Get
vsr
+2  A: 

Long answer short: yes. REST is for both. That's because even if you have the simplest of all websites one would still have to GET your page and maybe POST ones personal data to add an entry to the guestbook. In that we all adhere to REST somehow.

In your case poor browser implementation makes it hard to implement a PURE RESTful way. DELETE isn't supported without Javascript and therefore you would have to use GET or POST (which both do have a totally different meaning from DELETE in REST) anyway.

aefxx
+2  A: 

RESTful is commonly used when referring to web services, but it can very well apply to web pages. In a nutshell, being RESTful is about dealing with resources. A resource can be a person, a book, a movie, a theatre, a ticket, or whatever you fancy.

There are four basic operations you could perform on a resource.

  • create (POST)
  • read (GET)
  • update (PUT)
  • delete (DELETE)

Most web browsers do not support the PUT and DELETE actions, so you can only use POST actions for sending data. Rails fakes PUT and DELETE by passing in a hidden parameter named _method that the framework picks up and routes it depending on that value.

Also, you should never use GET for any destructive action. Any action that changes the state of your resource(s), should be called with either POST, PUT, or DELETE depending on the change (fake PUT/DELETE with POST if need be).

I would suggest you checkout the way RESTful routing is handled in Rails just to get an idea, if nothing else. Althought the four actions above are sufficient to modify a resource in any way possible, Rails also introduces three other types of actions that sound useful.

  • index (listing view of all items)
  • new (usually a form view to add a new resource)
  • edit (usually a form view to update an existing resource)

Pretty URL's is definitely on the table when designing RESTful sites, but probably the biggest win is that the quality of code improves automatically. When you're only dealing with resources, and there are only four potential actions that can be applied to a resource, then things start to clean up by themselves.

Edit 1: Self-descriptive URL's are preferred and will make your life easier, but there's nothing stopping from creating cryptic URLs that uniquely identify a resource and manage it using the HTTP verbs. URLs such as the ones below (using md5) to uniquely identify resources are perfectly RESTful.

// represents a person "John Doe"
http://example.com/4c2a904bafba06591225113ad17b5cec

// represents the movie "Lord of the Rings: The Two Towers"
http://example.com/1d9198260dec7bda3fb21e232d60fec3

// represents the "Formula One" sport
http://example.com/fs340as?id=23xa12&amp;type=SP012Ts

That's REpresentational State Transfer right there. The MD5 hash is like the mailing address of the resource that remains constant. The representation could be the movie's details (in html/xml/json/etc.), or maybe the video of the movie itself depending on the capabilities of the client).

Edit 2: Let's say you have a resource which is a collection - countries of the world. It could be represented by a URI and HTTP verb such as:

GET /countries

Since paging is a property of the application rather than the resource itself, you could supply querystring parameters to control it.

GET /countries?page=1

A country is also a resource that is a part of the countries resource. You could identify a country with a URL such as:

/countries/<id>

And operations on this country could be performed with these verbs:

GET    /countries/<id>
POST   /countries  -- the new country has no existing representation
PUT    /countries/<id>
DELETE /countries/<id>
Anurag
I have a question. For forms using POST, i do not want my user to see the popup window when they use the back and refresh buttons on their browser. So how do i overcome this while still be RESTful?
keisimone
checkout this question for ideas on how to fix that: http://stackoverflow.com/questions/660329/prevent-back-button-from-showing-post-confirmation-alert
Anurag
I have a question about the listing view of all items. I am not that familiar with Rails, so i have to ask you instead. For paging of lists, how would a RESTful framework handle it?
keisimone
so what you are saying is whenever you have a property of the application rather than the resource itself, it is still RESTful that i indicate it using a url param like ?page=1
keisimone
that's a minor detail.. the most important thing is to remember what constitutes a resource. if you paginate 10 countries per page, does each page of countries constitute a resource for your purposes? if so, make it a part of the URI itself. otherwise put it in the querystring params.
Anurag
suppose i have /countries?page=1 that lists 10 countries, and each country has a DELETE link next to it. the link is a input submit within a form tag that will also have a hidden input _method valueDELETE as suggested by other answers here to make it RESTful. The problem is this form tag, what is the value of the action? is it a RESTful URI like /countries/<id> ? if so i must have a .php file that will handle all the PUTs, DELETEs, GETs, POSTs that are sent to the countries/<id> and then read the referral link and redirect back to be able to use the POSTRedirectGet?
keisimone
yep. since you're deleting a resource like `/countries/43`, that will also be the URL (form action). the method will be `DELETE` like you mentioned. the redirect to `/countries` after delete is done can be implicit knowledge on the server side or could be requested by the client as a referral parameter like you said.
Anurag
implicit knowledge on the server side meaning something like _SERVER['HTTP_REFERER'];requested by the client as a referral parameter you mean like making the form action = "/countries/43?referrer=countries?page=1"sorry if i have to ask in such details.
keisimone
Oh and which do you think is better? the server side or the client side way? provided my understanding is correct based on my last comment
keisimone
I prefer keeping it all in the server side itself. For ex., on the server side a delete may work like, `function deleteCountry() { ... ; header("Location:/countries"); }` .. after something is deleted, it has no representation, so ideally i'd let the server decide where to go next. but it's upto you and your use cases, which may vary
Anurag
so i am on the right track to say that the $_SERVER['HTTP_REFERER'] should be used to determine where the request comes from and redirect accordingly?
keisimone
yes, that works too
Anurag
i also have read somewhere that it is not ideal to use $_SESSION for authentication in a restful website. What does that mean?
keisimone
lol, this is not a forum.. that's a different question
Anurag
okie i will post that as a separate question. thanks anurag
keisimone
+1  A: 

I wrote a tiny framework on top of Zend Framework to make implementing RESTful interfaces easier:

http://github.com/mikekelly/Resauce

You can use that for web services and websites. Essentially, a website is just a web service driven by HTML.

Mike
Due to certain reasons, we are not using Zend Framework. Can i still use Resauce to help me in my situation as described above? Thank you.
keisimone
Resauce is built from ZF's MVC components - so no. There are other projects like glue (http://gluephp.com/about), Limonade, etc.
Mike
+1  A: 

RESTful means not "beautiful URIs". Despite the fact that URIs identify a resource the only thing REST says about URIs is, that they shouldn't contain an action paramater like "delete".

In your case you would call

DELETE /items/6793

The Answer would be typically status code 200 OK with the modified list as message body. See: http://restpatterns.org/HTTP_Methods/DELETE

Since HTML 4 doesn't support other form actions than GET and POST you have to workaround with a hidden paramater and override the HTTP method on the server side.

deamon
even if i use form POST to delete the item, how would i redirect back to the listing page? I have edited my question to include this query
keisimone