Skip to main content

REST: Is DELETE Idempotent?

·894 words·5 mins
Hari KT
Author
Hari KT
Freelancer | Founder of Tripti and Tanvish | Maintainer of Aura for PHP, created by Paul M Jones

This post is a thrive to learn, and not to show anyone is incorrect. Feel free to share your thoughts.

Lukas Kahwe Smith was having a nice post RESTing with Symfony2

Quoting a few words from the post on REST

DELETE and 404
#

I started my talk on RESTing with Symfony2 with an introduction to REST itself. On slide 7 of my talk I explained the concept of “safe” and “idempotent” HTTP methods. Many people were surprised when I explained that DELETE should be idempotent, meaning that sending a DELETE request to a resource that has been removed should infact not return a 404.

I am not a REST guru, but in fact I got curious on the same, and was looking at http status 410 Gone

@harikt 1st Q that must be answered is if DELETE is idempotent. if it is then the status code shouldn't change on subsequent delete requests — Lukas Kahwe Smith (@lsmith) October 29, 2013

What is idempotent?
#

Quoting from Wikipedia

Idempotence is the property of certain operations in mathematics and computer science, that can be applied multiple times without changing the result beyond the initial application. The concept of idempotence arises in a number of places in abstract algebra (in particular, in the theory of projectors and closure operators) and functional programming (in which it is connected to the property of referential transparency).

There are several meanings of idempotence, depending on what the concept is applied to:

  • A unary operation (or function) is idempotent if, whenever it is applied twice to any value, it gives the same result as if it were applied once; i.e., ƒ(ƒ(x)) ≡ ƒ(x). For example, the absolute value: abs(abs(x)) ≡ abs(x).
  • A binary operation is idempotent if, whenever it is applied to two equal values, it gives that value as the result. For example, the operation giving the maximum value of two values is idempotent: max (x, x) ≡ x.
  • Given a binary operation, an idempotent element (or simply an idempotent) for the operation is a value for which the operation, when given that value for both of its operands, gives the value as the result. For example, the number 1 is an idempotent of multiplication: 1 × 1 = 1.

Christophe Coevoet also feel the same

@lsmith then 410 is probably the best status code here, and 404 otherwise /cc @harikt @_m6w6 — Christophe Coevoet (@Stof70) October 29, 2013

Why?

@lsmith The definition says "without changing the result". the HTTP spec says that the result is the state of the app @_m6w6 @harikt — Christophe Coevoet (@Stof70) October 29, 2013

 Status code of DELETE

The above screenshot is limited, you can check all the messages passed from https://twitter.com/harikt/status/395154834426314752

Woke up early morning and I noticed a subsequent post Is a HTTP DELETE request idempotent? by Lee Davis. Interesting to read his thoughts on the same. There was a nice discussion by Jason Lotito, do consider reading it.

I felt Jason Lotito is correct.

Wikipedia has something to say aboout Idempotent methods
#

Hypertext Transfer Protocol Idempotent methods

Methods PUT and DELETE are defined to be idempotent, meaning that multiple identical requests should have the same effect as a single request (Note that idempotence refers to the state of the system after the request has completed, so while the action the server takes (e.g. deleting a record) or the response code it returns may be different on subsequent requests, the system state will be the same every time).

So what does that mean?

Let us look into a real world example deleting http://example.com/post/121

We send a DELETE method via REST. What is going to happen?

I am quoting from http://www.restapitutorial.com/lessons/httpmethods.html

On successful deletion, return HTTP status 200 (OK) along with a response body, perhaps the representation of the deleted item (often demands too much bandwidth), or a wrapped response (see Return Values below). Either that or return HTTP status 204 (NO CONTENT) with no response body

so far, so good.

What is going to happen on your subsequent request?

2nd time we are sending a DELETE method via REST, what do you expect to get?

204 No Content. What does that mean?

The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation.

No Content is a good status, which means the server has exectuted your delete operation successfully is a wrong information.

iirc I have learned in Software Engineering, the wrong information is too bad than sending an error. Eg : 5+2 returning 9. I read some where at http://www.joelonsoftware.com/ the bug they want to deal with when he was at microsoft. ( If anyone have the link please comment it)

So if you know that a request for http://example.com/post/121 is already deleted, then 410 Gone will be the right status.

If you don’t know 404 Not Found is the best status. Say it is not created, do we send 204?.

So here http://example.com/post/121 is already deleted. (That means your subsequent response should be same, note that not response status code)

It is upto your application how to deal with making it truely RESTful. Else passing false information as response always is a wrong way.

I have also tried to get RSDL (RESTful Service Description Language) Maintainer to know the real information.

Probably I am wrong, but I am still learning REST.

Thank you.

Related

Magento and the REST API

·712 words·4 mins
Magento provides both REST and SOAP api. In this post I would like to concentrate on REST api to connect and get the products from magento shop. First we want to register an Oauth consumer to get the consumer key and secret key. Login to the admin of the magento shop and from the menu System->Web Services->REST - Oauth Consumers and add a new Ouath consumer.

Connecting to Magento via SOAP

·663 words·4 mins
In my earlier post I have shown how you can connect to Magento with REST api. In this post let us connect via SOAP. The below class acts like a proxy to call the magento soap api. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 <?php /** * * @author Hari K T * */ class My_Soap_Magento { /** * * Host name to connect * * @var string * */ protected $hostname; /** * * User name * * @var string * */ protected $username; /** * * API Key * * @var string * */ protected $apikey; /** * * Zend_Soap_Client * * @var Zend_Soap_Client * */ protected $client; protected $session; /** * * Constructor * * @param string $hostname The host name * * @param string $username The user name of the host * * @param string $apikey The apikey of the host * */ public function __construct($hostname, $username, $apikey) { $this->hostname = $hostname; $this->username = $username; $this->apikey = $apikey; } /** * * Magic method, the methods are named on the basis of Magento SOAP api * You don't need to pass the session as the first argument, for convience. * * @link http://www.magentocommerce.com/api/soap/introduction.html * * @param string $function * * @param mixed $args * * @return string | null * */ public function __call($function, $args) { $session = $this->getSession(); $params = array_merge(array($this->getSession()), $args); $result = call_user_func_array(array($this->getClient(), $function), $params); if ($result) { // I need to get as json return Zend_Json_Encoder::encode($result); } return null; } /** * * Get the session from logging in to the Magento server * * @return string * */ public function getSession() { if (! $this->session) { try { $this->session = $this->getClient()->login($this->username, $this->apikey); } catch (Exception $e) { } } return $this->session; } /** * * If we already have a session, we can set the session so it don't * need to login again and get the session. This helps to reduce the * call for login . * * @see getSession() * * @param string $session * * @return IM_Soap_Magento * */ public function setSession($session) { $this->session = $session; return $this; } /** * * Get the Zend_Soap_Client object * * @return Zend_Soap_Client * */ public function getClient() { if (! $this->client) { $endpoint = trim($this->hostname, '/') . '/api/v2_soap/?wsdl'; $this->client = new Zend_Soap_Client( $endpoint ); } return $this->client; } } In order to connect you want to create an object of the above class My_Soap_Magento. You need to get the username and api key from the magento host.

Aura.Http Request and Response

·856 words·5 mins
The Aura.Http package provide you the tool to build and send request and response. Instantiation: # The easiest way is 1 2 3 <?php $http = require 'path/to/Aura.Http/scripts/instance.php'; What it gives you is an object of Aura\Http\Manager. If you want to create manually you can look into the instance.php Building your Response # Probably you may not have bothered too much on building the http response either the framework does it for you, or until you need to send the correct response.