Coder Perfect



So, I was reading some papers about building REST APIs. Some even recommend employing all forms of HTTP requests, such as PUT DELETE POST GET. We would create for example index.php and write API this way:

$request = split("/", substr(@$_SERVER['PATH_INFO'], 1));

switch ($method) {
  case 'PUT':
    ....some put action.... 
  case 'POST':
    ....some post action.... 
  case 'GET':
    ....some get action.... 
  case 'DELETE':
    ....some delete action.... 

Granted, I’m not an expert on web services (yet). But wouldn’t it be simpler to simply take a JSON object via standard POST or GET (which would include the method name and all parameters) and then answer in JSON? Using PHP’s json encode() and json decode() functions, we can quickly serialise and deserialize data and do anything we want with it without having to deal with multiple HTTP request types.

Is there something I’m overlooking?


Ok, after poring through many APIs and learning a lot about XML-RPC, JSON-RPC, SOAP, and REST, I’ve decided that this type of API is sound. Actually, Stack Exchange uses this strategy on their website, and I believe that these guys are knowledgeable about the Stack Exchange API.

Asked by Stann

Solution #1

The goal of REpresentational State Transfer isn’t to make data access as simple as feasible.

To retrieve JSON, you advised using post requests, which is a perfectly legitimate method of doing so.

REST is a protocol for accessing data in a meaningful way. When you see a request with REST, you should be able to see what’s going on with the data right away.

For example:

GET: /cars/make/chevrolet

is likely to return a list of Chevrolet vehicles. A decent REST api might even include output options in the querystring, such as?output=json or?output=html, allowing the accessor to choose which format the data should be encoded in.

After some consideration of how to reasonably add data types into a REST API, I’ve come to the conclusion that the simplest approach to explicitly declare the type of data is to use an existing file extension such as.js,.json,.html, or.xml. A file extension that isn’t supported will default to the default format (such as JSON); a file extension that isn’t supported will return a 501 Not Implemented status code.

Another example:

POST: /cars/
{ make:chevrolet, model:malibu, colors:[red, green, blue, grey] }

hues of ted I say likely because the REST api does not have to be linked to the database schema directly. It’s only a masking interface to keep the real data safe (think of it like accessors and mutators for a database structure).

We must now turn our attention to the topic of idempotence. CRUD is usually implemented via HTTP in REST. The requests in HTTP are GET, PUT, POST, and DELETE.

The following CRUD mapping could be used in a very basic REST implementation:

Create -> Post
Read   -> Get
Update -> Put
Delete -> Delete

This implementation has a flaw: Post is declared as a non-idempotent method. This means that calling the Post method again will result in a different server state. Idempotent means that if you call Get, Put, or Delete several times, the server state should remain the same.

This means that if you make a request like this, you’ll be able to get

Delete: /cars/oldest

could be implemented as follows:

Post: /cars/oldest?action=delete


Delete: /cars/id/123456

Whether you call it once or 1000 times, the server state will remain the same.

Requesting the following would be a better method to handle the removal of the oldest item:

Get: /cars/oldest

and make a delete request using the ID from the generated data:

Delete: /cars/id/[oldest id]

If another /cars item was added between when /oldest was requested and when the delete was performed, this procedure would fail.

Answered by zzzzBov

Solution #2

This is a concern of security and upkeep.

To limit potential vulnerability, you should use’safe’ (unidirectional) methods like GET and HEAD whenever possible.

Use ‘idempotent’ methods like GET, HEAD, PUT, and DELETE wherever possible, as they can’t have side effects and are hence less mistake prone/easier to control.


Answered by markus

Solution #3

In a nutshell, REST prioritizes nouns over verbs. Instead of adding more commands, you add more items as your API becomes more complicated.

Answered by Neil

Solution #4

You asked:

RESTful web services, according to Wikipedia:

I believe this is usually accomplished by maximizing the usage of existing HTTP verbs and building a URL scheme for your service that is as powerful and self-evident as feasible, based on what (little) I’ve seen.

Custom data protocols (even if built on top of established ones like SOAP or JSON) are discouraged and should be avoided as much as possible to adhere to the REST philosophy.

The things you’re working with can be of any shape or size. The goal is to use as much HTTP as feasible to expose the actions that the user wishes to do on those resources (queries, state management/mutation, and deletion).

You asked:

There’s still a lot to learn about REST and the URI syntax/HTTP verbs. Some verbs, for example, are idempotent, whereas others are not. I didn’t notice anything in your query concerning this, so I didn’t bother to look into it. Both the other replies and Wikipedia have a wealth of useful information.

Also, if you’re utilizing a really restful API, there’s a lot to understand about the many network technologies built on top of HTTP that you may use. I’d begin with the authentication process.

Answered by Merlyn Morgan-Graham

Solution #5

Concerning the use of extensions to define data types. I saw that the MailChimp API does this, but I don’t think it’s a smart idea.

GET /zzz/cars.json/1

GET /zzz/cars.xml/1

My suggestion sounds fine, however I believe the “older” way of using HTTP headers is preferable.

GET /xxx/cars/1
Accept: application/json

Additionally, HTTP headers are far superior 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  

Answered by Pawel Cioch

Post is based on