Este post es una breve descripción sobre la famosa idempotencia y su importancia en el los verbos http.
Según wikipedia el significado de idempotencia es la propiedad de realizar una acción determinada varias veces, y aún así, conseguir el mismo resultado que se obtendría si se realizara una sola vez.
En el caso de HTTP, específicamente en los verbos HTTP, la idempotencia nos dice que:
La ejecución repetida de una petición, con los mismos parámetros, sobre un mismo recurso; tendrá el mismo efecto en el estado de nuestro recurso, si se ejecuta 1 o N veces. Es decir siempre tendremos el mismo resultado sin importar el numéro de ejecuciones.
Verbos HTTP Idempotentes Vs No Idempotentes
Debemos tener en cuenta, que tambien existen verbos HTTP idempotentes y no idempotentes.
En la siguiente tabla vemos los verbos que son y no son idempotentes:
Verbo HTTP | Es idempotente |
GET | SI |
POST | NO |
PUT | SI |
PATCH | NO |
DELETE | SI |
Verbos no idempotentes
Debemos tener en cuenta, que existen verbos HTTP no idempotentes. Pero es buena práctica, respetar el principio de idempotencia para evitar efectos secundarios o no deseados al ejecutar nuestros recursos http.
La ejecución repetida, usando un verbo no idempotente, con los mismos datos sobre un recurso no tendrá el mismo efecto.
Ejemplo verbo No idempotente
Tenemos un API la cual, tiene un endpoint que tiene como recurso una entidad USUARIO parte de una base de datos de un blog.
Si hacemos uso de una petición POST
http para crear un artículo, como POST
es un verbo no idempotente.
Si ejecutamos la siguiente petición POST /api/v1/usuario
la primera vez, con los siguientes datos, obtendremos como resultado la creacion del recuso usuario Jhon Doe
.
POST /api/v1/usuario
{
"nombre" : "Jhon Doe",
"email": "jdoe@doe.com"
}
¿Que pasa si ejecutamos una segunda vez esta petición POST /api/v1/usuario
con la misma información en el cuerpo de la petición? -- dependiendo de la lógica dentro de nuestra API podemos tener los siguientes resultados :
Si no estamos validando que el email se repita, el resultado en cada ejecución, será crear cada vez un nuevo recurso _usuario_ en la base de datos.
Si validamos el
email
obtendremos un error porque ya existe un usuario con el mismo email en la base de datos.
Ejemplo verbo Idempotente
En este caso vamos a usar el verbo http PUT
; realizaremos una peticion de creación/actualización sobre un recurso USUARIO
especifico de la base de datos con datos usados en el cuerpo del ejemplo anterior.
Si ejecutamos la siguiente petición PUT /api/v1/usuario/1
creara un nuevo USUARIO
en caso de no existir, o lo modificara en caso de haya cambiado algo en el existente.
PUT /api/v1/usuario/1
{
"nombre" : "Jhon Doe",
"email": "jdoe@doe.com"
}
Si ejecutamos esta petición por primera vez, creara el nuevo recurso usuario/1
en caso de no existir.
Pero si repetimos y ejecutamos la misma petición N veces, con el verbo idempotente PUT
, incluso enviando los mismo parámetros al mismo recurso /1
, este se actualizara y se mantendrá igual, es decir tendremos el mismo estado o resultado.
Pero que pasa si ejecutamos la petición cambiando algo de información, por ejemplo el recurso /2
, el efecto que tendrá sera crear un nuevo recurso.
PUT /api/v1/usuario/2
{
"nombre" : "Jhon Doe ",
"email": "jdoe@doe.com"
}
Conclusiones
Es importante tener en cuenta que este comportamiento de idempotencia no solo se produce simplemente por usar uno de los verbos idempotentes, sino que es necesario implementar y respetar este principio al momento de diseñar la lógica de nuestra API.