REST API - ¿por qué usar PUT DELETE POST GET?


Así que, estaba mirando a través de algunos artículos sobre la creación de REST API. Y algunos de ellos sugieren el uso de todo tipo de peticiones HTTP: like PUT DELETE POST GET. Crearíamos por ejemplo index.php y escriba la API de esta manera:

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

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

OK, concedido - No se mucho sobre servicios web (todavía). Pero, ¿no sería más fácil simplemente aceptar JSON objeto a través de regular POST o GET (que contendría el nombre del método y todos los parámetros) y luego responder en JSON también. Podemos serializar / deserializar fácilmente a través de PHP json_encode() y json_decode() y hacer lo que queramos con esos datos sin tener que lidiar con diferentes métodos de solicitud HTTP.

¿Me estoy perdiendo algo?

ACTUALIZAR 1:

Ok-después de explorar varias API y aprender mucho sobre XML-RPC, JSON-RPC, JABÓN, REST Llegué a la conclusión de que este tipo de API es sólido. En realidad, stack Exchange está usando esto enfoque en sus sitios y creo que estas personas saben lo que están haciendo Apilar Exchange API.

Author: Community, 2011-01-01

8 answers

La idea de REpresentational State Transfer no se trata de acceder a los datos de la manera más simple posible.

Usted sugirió usar post requests para acceder a JSON, que es una forma perfectamente válida de acceder/manipular datos.

REST es una metodología para un acceso significativo a los datos. Cuando vea una solicitud en REPOSO, debería ser inmediatamente aparente lo que está sucediendo con los datos.

Por ejemplo:

GET: /cars/make/chevrolet

Es probablemente va a devolver una lista de autos Chevy. Una buena api REST podría incluso incorporar algunas opciones de salida en la cadena de consultas como ?output=json o ?output=html que permitirían al accesor decidir en qué formato debe codificarse la información.

Después de pensar un poco sobre cómo incorporar razonablemente la tipificación de datos en una API REST, he llegado a la conclusión de que la mejor manera de especificar el tipo de datos explícitamente sería a través de la extensión de archivo ya existente, como .js, .json, .html, o .xml. Una extensión de archivo faltante sería predeterminada en cualquier formato predeterminado (como JSON); una extensión de archivo que no sea compatible podría devolver una 501 Not Implemented código de estado .

Otro ejemplo:

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

Probablemente va a crear un nuevo chevy malibu en la base de datos con los colores asociados. Digo probablemente ya que la api REST no necesita estar directamente relacionada con la estructura de la base de datos. Es solo una interfaz de enmascaramiento para que los datos verdaderos estén protegidos (piénsalo como accesores y mutadores para una estructura de base de datos).

Ahora tenemos que pasar a la cuestión de idempotencia. Normalmente REST implementa CRUD sobre HTTP. Usos HTTP GET, PUT, POST y DELETE para las solicitudes.

Una implementación muy simplista de REST podría usar la siguiente asignación de CRUD:

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

Hay un problema con esta implementación: Post se define como un método no idempotente. Esto significa que posterior las llamadas del mismo método Post resultarán en diferentes estados de servidor . Get, Put y Delete son idempotentes; lo que significa que llamarlos varias veces debería resultar en un estado de servidor idéntico.

Esto significa que una solicitud como:

Delete: /cars/oldest

Podría realmente implementarse como:

Post: /cars/oldest?action=delete

Considerando que

Delete: /cars/id/123456

Resultará en el mismo estado del servidor si lo llama una vez, o si lo llama 1000 veces.

Una mejor manera de manejar la eliminación of the oldest item would be to request:

Get: /cars/oldest

Y utilice el ID de los datos resultantes para hacer una solicitud delete:

Delete: /cars/id/[oldest id]

Un problema con este método sería si se agregara otro /cars elemento entre el momento en que se solicitó /oldest y el momento en que se emitió el delete.

 190
Author: zzzzBov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-11 18:01:05

Esta es una pregunta de seguridad y mantenibilidad.

Métodos seguros

Siempre que sea posible, debe usar métodos 'seguros' (unidireccionales) como GET y HEAD para limitar la vulnerabilidad potencial.

Métodos idempotentes

Siempre que sea posible, debe usar métodos 'idempotentes' como GET, HEAD, PUT y DELETE, que no pueden tener efectos secundarios y, por lo tanto, son menos propensos a errores/más fáciles de controlar.

Fuente

 38
Author: markus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-01 06:06:54

En resumen, REST enfatiza los sustantivos sobre los verbos. A medida que su API se vuelve más compleja, agrega más cosas, en lugar de más comandos.

 24
Author: Neil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-21 13:42:56

Usted preguntó :

¿No sería más fácil simplemente aceptar el objeto JSON a través de normal _ _POST y luego responder en JSON también

De la Wikipedia en RESTO :

Las aplicaciones RESTful maximizan el uso de la interfaz preexistente y bien definida y otras capacidades integradas proporcionadas por el protocolo de red elegido, y minimizan la adición de nuevas características específicas de la aplicación en la parte superior

De lo que (poco) he visto, creo que esto generalmente se logra maximizando el uso de los verbos HTTP existentes y diseñando un esquema de URL para su servicio que sea lo más poderoso y evidente posible.

Se desaconsejan los protocolos de datos personalizados (incluso si se construyen sobre los estándares, como SOAP o JSON), y deben minimizarse para ajustarse mejor a la ideología REST.

SOAP RPC sobre HTTP, por otro lado, alienta a cada diseñador de aplicaciones a definir una nueva y arbitraria vocabulario de sustantivos y verbos (por ejemplo getUsers (), savePurchaseOrder(...)), por lo general se superpone al verbo HTTP 'POST'. Esto no tiene en cuenta muchas de las capacidades existentes de HTTP, como la autenticación, el almacenamiento en caché y la negociación de tipos de contenido, y puede dejar al diseñador de aplicaciones reinventando muchas de estas características dentro del nuevo vocabulario.

Los objetos reales con los que está trabajando pueden estar en cualquier formato. La idea es reutilizar tanto HTTP como sea posible para exponer sus operaciones el usuario quiere realizar en esos recursos (consultas, administración de estado/mutación, eliminación).

Usted preguntó :

¿Me estoy perdiendo algo?

Hay mucho más que saber sobre REST y la sintaxis URI/verbos HTTP. Por ejemplo, algunos de los verbos son idempotentes, otros no. No vi nada sobre esto en tu pregunta, así que no me molesté en tratar de sumergirme en ella. Las otras respuestas y Wikipedia tienen un montón de buenas información.

Además, hay mucho que aprender sobre las diversas tecnologías de red construidas sobre HTTP que puede aprovechar si está utilizando una API verdaderamente restful. Empezaría con la autenticación.

 9
Author: Merlyn Morgan-Graham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-02 19:45:35

En lo que respecta al uso de extensión para definir el tipo de datos. Me di cuenta de que la API de MailChimp lo está haciendo, pero no creo que sea una buena idea.

GET /zzz/cars.json/1

GET /zzz/cars.xml/1

Mi sonido como una buena idea, pero creo que el enfoque "antiguo" es mejor - el uso de encabezados HTTP

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

También los encabezados HTTP son mucho mejores para la comunicación de tipo de datos cruzados (si alguna vez alguien lo necesitaría)

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  
 8
Author: Pawel Cioch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-15 20:09:04

¿Me estoy perdiendo algo?

Sí. ;-)

Este fenómeno existe debido a la restricción de interfaz uniforme . A REST le gusta usar estándares ya existentes en lugar de reinventar la rueda. El estándar HTTP ya ha demostrado ser altamente escalable (la web está funcionando durante un tiempo). ¿Por qué debemos arreglar algo que no está roto?!

nota: La restricción de interfaz uniforme es importante si desea desacoplar los clientes del servicio. Es similar a definir interfaces para clases con el fin de desacoplarlas entre sí. Ofc. aquí la interfaz uniforme consiste en estándares como HTTP, Tipos MIME, URI, RDF, vocabs de datos vinculados, hydra vocab , etc...

 4
Author: inf3rno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-19 21:56:59

Una buena semántica es importante en la programación.

Utilizar más métodos además de GET/POST será útil porque aumentará la legibilidad de su código y lo hará más fácil de mantener.

¿Por qué?

Porque sabes que GET recuperará datos de tu api. Sabes que POST agregará nuevos datos a tu sistema. Sabes que PUT hará actualizaciones. ELIMINAR eliminará filas etc, etc,

Normalmente estructuro mis Servicios Web RESTFUL para que tenga una función callback llamada lo mismo que el método.

Uso PHP, así que uso function_exists (creo que se llama). Si la función no existe, tiro un 405 (MÉTODO NO PERMITIDO).

 1
Author: HumbleWebDev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-21 20:37:09

Bill Venners: En su entrada de blog titulada "Por qué el DESCANSO falló", dijo que necesitamos los cuatro verbos HTTP-GET, POST, PUT y DELETE - y lamentó que los proveedores de navegadores solo OBTIENEN y PUBLICAN."¿Por qué necesitamos los cuatro verbos? ¿Por qué no son suficientes GET and POST?

Elliotte Rusty Harold: Hay cuatro métodos básicos en HTTP: GET, POST, PUT y DELETE. GET se usa la mayor parte del tiempo. Se usa para cualquier cosa que sea segura, que no cause efectos secundarios. OBTENER es capaz de ser marcado, almacenado en caché, vinculado, pasado a través de un servidor proxy. Es una operación muy poderosa, una operación muy útil.

POST por el contrario es quizás la operación más poderosa. Puede hacer cualquier cosa. No hay límites en cuanto a lo que puede suceder, y como resultado, hay que tener mucho cuidado con él. No lo marcas. No lo escondes. No lo traes antes. No haces nada con un POST sin preguntar al usuario. ¿Quieres hacer esto? Si el usuario presiona el botón, puede PUBLICAR algo de contenido. Pero no vas a mirar todos los botones de una página y empezar a presionarlos aleatoriamente. Por el contrario, los navegadores pueden mirar todos los enlaces en la página y pre-buscarlos, o pre-buscar los que creen que son más propensos a ser seguidos a continuación. Y, de hecho, algunos navegadores y extensiones de Firefox y varias otras herramientas han tratado de hacer eso en un momento u otro.

PUT y DELETE están en el medio entre GET y POST. La diferencia entre PUT o DELETE y POST es que PUT y DELETE son * idempotentes, mientras que POST no lo es. PONER y ELIMINAR se puede repetir si es necesario. Digamos que estás intentando subir una nueva página a un sitio. Supongamos que desea crear una nueva página en http://www.example.com/foo.html , por lo que escribe su contenido y lo PONE en esa URL. El servidor crea esa página en la URL que usted proporciona. Ahora, supongamos que por alguna razón su conexión de red se interrumpe. No está seguro, ¿la solicitud llegó o no? Tal vez la red es lento. Tal vez hubo un problema con el servidor proxy. Por lo tanto, está perfectamente bien intentarlo de nuevo, o de nuevo, tantas veces como desee. Porque PONER el mismo documento en la misma URL diez veces no será diferente a ponerlo una vez. Lo mismo es cierto para ELIMINAR. Puedes BORRAR algo diez veces, y eso es lo mismo que borrarlo una vez.

Por el contrario, POST, puede causar que algo diferente suceda cada vez. Imagine que está saliendo de una tienda en línea presionando el botón comprar. Si envíe esa solicitud de CORREO nuevamente, podría terminar comprando todo en su carrito por segunda vez. Si lo envías de nuevo, lo has comprado por tercera vez. Es por eso que los navegadores tienen que tener mucho cuidado al repetir operaciones POST sin el consentimiento explícito del usuario, porque POST puede causar dos cosas que suceden si lo haces dos veces, tres cosas si lo haces tres veces. Con PUT y DELETE, hay una gran diferencia entre cero solicitudes y una, pero no hay diferencia entre una solicitud y diez.

Por favor visite la url para más detalles. http://www.artima.com/lejava/articles/why_put_and_delete.html

Actualización:

Métodos idempotentes Un método HTTP idempotente es un método HTTP que se puede llamar muchas veces sin resultados diferentes. No importaría si el método se llama solo una vez, o diez veces más. El resultado debe ser el mismo. Una vez más, esto solo se aplica al resultado, no al recurso en sí. Esto todavía puede ser manipulado (como una marca de tiempo de actualización, siempre que esta información no se comparta en la representación de recursos (actual).

Considere los siguientes ejemplos:

A = 4;

A++;

El primer ejemplo es idempotente: no importa cuántas veces ejecutemos esta instrucción, a siempre será 4. El segundo ejemplo no es idempotente. Ejecutar esto 10 veces dará como resultado un resultado diferente al de ejecutar 5 veces. Dado que ambos ejemplos están cambiando la valor de a, ambos son métodos no seguros.

 1
Author: Bimal Das,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-04 09:48:40