Idempotencia en verbos http

Idempotencia en verbos http

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 HTTPEs idempotente
GETSI
POSTNO
PUTSI
PATCHNO
DELETESI

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 :

  1. 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.

  2. 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.