Comprensión de REST: Verbos, códigos de error y autenticación


Estoy buscando una manera de envolver las API alrededor de las funciones predeterminadas en mis aplicaciones web basadas en PHP, bases de datos y CMSs.

He mirado alrededor y encontrado varios marcos "esqueleto". Además de las respuestas en mi pregunta, hay Tonic, un marco de DESCANSO que me gusta porque es muy ligero.

Me gusta REST lo mejor por su simplicidad, y me gustaría crear una arquitectura API basada en él. Estoy tratando de conseguir mi cabeza alrededor de los principios básicos y tener aún no lo he entendido del todo. Por lo tanto, una serie de preguntas.

1. Estoy entendiendo bien?

Digamos que tengo un recurso "usuarios". Podría configurar un número de URI así:

/api/users     when called with GET, lists users
/api/users     when called with POST, creates user record
/api/users/1   when called with GET, shows user record
               when called with PUT, updates user record
               when called with DELETE, deletes user record

¿Es esta una representación correcta de una arquitectura tranquila hasta ahora?

2. Necesito más verbos

Crear, Actualizar y Eliminar puede ser suficiente en teoría, pero en la práctica tendré la necesidad de muchos más verbos. Me doy cuenta de que estas son cosas que podría estar incrustado en una solicitud de actualización, pero son acciones específicas que pueden tener códigos de retorno específicos y no me gustaría lanzarlos todos en una acción.

Algunos que vienen a la mente en el ejemplo de usuario son:

activate_login
deactivate_login
change_password
add_credit

¿Cómo expresaría acciones como aquellas en una arquitectura de URL RESTful?

Mi instinto sería hacer una llamada GET a una URL como

/api/users/1/activate_login 

Y esperar un código de estado de vuelta.

Que se desvía de la idea de usar verbos HTTP, aunque. ¿Qué opinas?

3. Cómo devolver mensajes de error y códigos

Una gran parte de la belleza de REST proviene de su uso de métodos HTTP estándar. En un error, emito un encabezado con un código de estado de error 3xx,4xx o 5xx. Para una descripción detallada del error, puedo usar el cuerpo (¿correcto?). Hasta ahora todo bien. Pero cuál sería la forma de transmitir un código de error propietario que es más detallado al describir lo que salió mal (por ejemplo, "no se pudo conectar a la base de datos", o "inicio de sesión de base de datos incorrecto")? Si lo pongo en el cuerpo junto con el mensaje, tengo que analizarlo después. Hay un encabezado estándar para este tipo de cosas?

4. Cómo hacer autenticación

  • ¿Cómo sería una autenticación basada en clave API siguiendo los principios REST?
  • ¿Hay puntos fuertes en contra de usar sesiones cuando se autentica un cliente REST, aparte de que es una violación flagrante del principio REST? :) (solo estoy bromeando, la autenticación basada en sesión funcionaría bien con mi infraestructura existente.)
Author: SandroMarques, 2010-01-04

10 answers

Me di cuenta de esta pregunta un par de días tarde, pero siento que puedo agregar algo de visión. Espero que esto pueda ser útil para su empresa de descanso.


Punto 1: ¿Lo estoy entendiendo bien?

Entendiste bien. Esa es una correcta representación de una arquitectura tranquila. Puede encontrar la siguiente matriz de Wikipedia muy útil para definir sus sustantivos y verbos:


Cuando se trata de una Colección URI como: http://example.com/resources/

  • GET : Lista los miembros de la colección, completa con sus URI de miembros para más navegación. Por ejemplo, enumere todos los autos a la venta.

  • PUT : Significado definido como "reemplazar toda la colección con otra colección".

  • POST : Crea una nueva entrada en la colección donde el ID es asignado automáticamente por la colección. El ID creado generalmente se incluye como parte de los datos devuelto por esta operación.

  • DELETE : Significado definido como "delete the entire collection".


Cuando se trata de un Miembro URI como: http://example.com/resources/7HOU57Y

  • GET : Recupera una representación del miembro con dirección de la colección expresada en un tipo MIME apropiado.

  • PUT : Actualice el miembro con dirección de la colección o créelo con el ID.

  • POST : Trata al miembro al que se dirige como una colección por derecho propio y crea un nuevo subordinado del mismo.

  • DELETE : Delete the addressed member of the collection.


Punto 2: necesito más verbos

En general, cuando crees que necesitas más verbos, en realidad puede significar que tus recursos necesitan ser reidentificados. Recuerde que en REPOSO siempre está actuando sobre un recurso, o sobre un recolección de recursos. Lo que elija como recurso es muy importante para la definición de su API.

Activar / Desactivar Inicio de sesión: Si está creando una nueva sesión, es posible que desee considerar "la sesión" como el recurso. Para crear una nueva sesión, utilice POST to http://example.com/sessions/ con las credenciales en el cuerpo. Para caducarlo use PUT o DELETE (tal vez dependiendo de si tiene la intención de mantener un historial de sesiones) a http://example.com/sessions/SESSION_ID.

Cambiar contraseña: Esta vez el recurso es "usuario". Usted necesitaría un PUT a http://example.com/users/USER_ID con las contraseñas antiguas y nuevas en el cuerpo. Está actuando sobre el recurso "usuario", y un cambio de contraseña es simplemente una solicitud de actualización. Es bastante similar a la instrucción UPDATE en una base de datos relacional.

Mi instinto sería hacer una llamada GET a una URL como /api/users/1/activate_login

Esto va en contra de un principio REST muy básico: El uso correcto de los verbos HTTP. Cualquier solicitud GET nunca debe dejar ningún efecto secundario.

Para por ejemplo, una solicitud GET nunca debe crear una sesión en la base de datos, devolver una cookie con un nuevo ID de sesión o dejar ningún residuo en el servidor. El verbo GET es como la instrucción SELECT en un motor de base de datos. Recuerde que la respuesta a cualquier solicitud con el verbo GET debe ser capaz de caché cuando se solicita con los mismos parámetros, al igual que cuando se solicita una página web estática.


Punto 3: Cómo devolver mensajes de error y códigos

Considere el HTTP 4xx o 5xx códigos de estado como categorías de error. Puedes elaborar el error en el cuerpo.

Error al conectarse a la base de datos: / Incorrect Database Login: En general, debe usar un error 500 para este tipo de errores. Este es un error del lado del servidor. El cliente no hizo nada malo. 500 errores son normalmente considerados "recuperable". es decir, el cliente puede volver a intentar la misma solicitud exacta, y esperar que tenga éxito una vez que se resuelvan los problemas del servidor. Especifique los detalles en el cuerpo, de modo que el cliente será capaz de proporcionar algún contexto a nosotros los seres humanos.

La otra categoría de errores sería la familia 4xx, que en general indican que el cliente hizo algo mal. En particular, esta categoría de errores normalmente indican al cliente que no hay necesidad de volver a intentar la solicitud tal como está, porque continuará fallando permanentemente. es decir, el cliente necesita cambiar algo antes de volver a realizar esta solicitud. Por ejemplo, "Recurso no encontrado" (HTTP 404) o " Malformado Los errores Request" (HTTP 400) caerían en esta categoría.


Punto 4: Cómo realizar la autenticación

Como se señala en el punto 1, en lugar de autenticar a un usuario, es posible que desee pensar en crear una sesión. Se le devolverá un nuevo "ID de sesión", junto con el código de estado HTTP correspondiente (200: Acceso concedido o 403: Acceso Denegado).

Entonces le preguntará a su servidor RESTful: "¿Puede conseguirme el recurso para este ID de sesión?".

Hay sin modo autenticado - REST es sin estado: se crea una sesión, se pide al servidor que le proporcione recursos utilizando este ID de sesión como parámetro y, al cerrar la sesión, se suelta o expira la sesión.

 593
Author: Daniel Vassallo,
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
2016-08-14 01:56:26

En pocas palabras, estás haciendo esto completamente hacia atrás.

No deberías acercarte a esto desde qué URL deberías usar. Las URL efectivamente vendrán "gratis" una vez que haya decidido qué recursos son necesarios para su sistema Y cómo representará esos recursos, y las interacciones entre los recursos y el estado de la aplicación.

Para citar Roy Fielding

Una API REST debería gastar casi todo su esfuerzo descriptivo en definición de la tipo(s) de soporte utilizado (s) para representar recursos y aplicación de conducción estado, o en la definición extendida nombres de relación y / o marcado habilitado para hipertexto para tipos de medios estándar. Cualquier esfuerzo gastado describir qué métodos usar en qué URI de interés debe ser enteramente definido en el ámbito de la reglas de procesamiento para un tipo de medio (y, en la mayoría de los casos, ya definido por tipos de medios existentes). [Fallo aquí implica que fuera de banda información está impulsando la interacción en lugar de hipertexto.]

La gente siempre comienza con los URI y piensa que esta es la solución, y luego tienden a perder un concepto clave en la arquitectura REST, notablemente, como se cita anteriormente, "El fracaso aquí implica que la información fuera de banda está impulsando la interacción en lugar de hipertexto."

Para ser honesto, muchos ven un montón de URI y algunos reciben y ponen y publican y piensan que el DESCANSO es fácil. EL descanso no es fácil. RPC sobre HTTP es fácil, moviendo blobs de datos de nuevo y forth proxied a través de cargas útiles HTTP es fácil. El DESCANSO, sin embargo, va más allá de eso. El RESTO es protocolo agnóstico. HTTP es muy popular y apto para sistemas REST.

REST vive en los tipos de medios, sus definiciones y cómo la aplicación impulsa las acciones disponibles para esos recursos a través de hipertexto (enlaces, efectivamente).

Hay diferentes vistas sobre los tipos de medios en los sistemas REST. Algunos favorecen las cargas útiles específicas de la aplicación, mientras que a otros les gusta elevar los tipos de medios existentes para roles que son apropiados para la aplicación. Por ejemplo, por un lado, tiene esquemas XML específicos diseñados para su aplicación en lugar de usar algo como XHTML como su representación, tal vez a través de microformatos y otros mecanismos.

Ambos enfoques tienen su lugar, creo que el XHTML funciona muy bien en escenarios que se superponen tanto la web impulsada por humanos como la impulsada por máquinas, mientras que los primeros tipos de datos más específicos me siento mejor facilitan máquina a máquina interacción. Encuentro que la elevación de los formatos de productos básicos puede hacer que la negociación de contenido sea potencialmente difícil. "application / xml + yourresource "es mucho más específico como tipo de medio que" application/xhtml+xml", ya que este último puede aplicarse a muchas cargas útiles que pueden o no ser algo en lo que un cliente de máquina está realmente interesado, ni puede determinar sin introspección.

Sin embargo, XHTML funciona muy bien (obviamente) en la web humana donde los navegadores web y el renderizado es muy importante.

Tu solicitud te guiará en ese tipo de decisiones.

Parte del proceso de diseño de un sistema REST es descubrir los recursos de primera clase en su sistema, junto con los recursos de soporte derivados necesarios para apoyar las operaciones en los recursos primarios. Una vez que se descubren los recursos, entonces la representación de esos recursos, así como los diagramas de estado que muestran el flujo de recursos a través de hipertexto dentro de las desafío.

Recuerde que cada representación de un recurso, en un sistema de hipertexto, combina tanto la representación de recurso real junto con las transiciones de estado disponibles para el recurso. Considere cada recurso como un nodo en un gráfico, siendo los enlaces las líneas que dejan ese nodo a otros estados. Estos enlaces informan a los clientes no solo lo que se puede hacer, sino lo que se requiere para que se hagan (ya que un buen enlace combina el URI y el tipo de medio requerido).

Por ejemplo, usted puede tienen:

<link href="http://example.com/users" rel="users" type="application/xml+usercollection"/>
<link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/>

Su documentación hablará sobre el campo rel llamado "users", y el tipo de medio de "application/xml+yourser".

Estos enlaces pueden parecer redundantes, todos están hablando con el mismo URI, más o menos. Pero no lo son.

Esto se debe a que para la relación" usuarios", ese enlace está hablando de la colección de usuarios, y puede usar la interfaz uniforme para trabajar con la colección (OBTENER para recuperar todos ellos, ELIMINAR para eliminar todos ellos, sucesivamente.)

Si publica en esta URL, tendrá que pasar un documento "application/xml+usercollection", que probablemente solo contendrá una sola instancia de usuario dentro del documento para que pueda agregar el usuario, o no, tal vez, para agregar varios a la vez. Tal vez su documentación sugiera que simplemente puede pasar un solo tipo de usuario, en lugar de la colección.

Puede ver lo que la aplicación requiere para realizar una búsqueda, como se define por el enlace "buscar" y su tipo de medio. La documentación para el tipo de medios de búsqueda le dirá cómo se comporta y qué esperar como resultados.

La conclusión aquí, sin embargo, es que los URI en sí mismos son básicamente sin importancia. La aplicación tiene el control de los URI, no de los clientes. Más allá de unos pocos "puntos de entrada", sus clientes deben confiar en los URI proporcionados por la aplicación para su trabajo.

El cliente necesita saber cómo manipular e interpretar los tipos de medios, pero no necesita preocuparse por dónde ir.

Estos dos enlaces son semánticamente idénticos a los ojos de un cliente:

<link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/>
<link href="http://example.com/AW163FH87SGV" rel="search" type="application/xml+usersearchcriteria"/>

Entonces, concéntrate en tus recursos. Enfóquese en sus transiciones de estado en la aplicación y cómo se logra mejor.

 76
Author: Will Hartung,
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-03-18 01:48:54

Re 1: Esto se ve bien hasta ahora. Recuerde devolver el URI del usuario recién creado en un encabezado " Location: "como parte de la respuesta a POST, junto con un código de estado" 201 Created".

Re 2: La activación vía GET es una mala idea, e incluir el verbo en el URI es un olor a diseño. Es posible que desee considerar devolver un formulario en un GET. En una aplicación web, esto sería un formulario HTML con un botón de envío; en el caso de uso de la API, es posible que desee devolver una representación que contiene un URI para poner a activar la cuenta. Por supuesto, también puedes incluir este URI en la respuesta en POST to / users. El uso de PUT asegurará que su solicitud sea idempotente, es decir, se puede enviar de nuevo de forma segura si el cliente no está seguro del éxito. En general, piensa en qué recursos puedes convertir tus verbos (una especie de "nounificación de verbos"). Pregúntese con qué método su acción específica está más estrechamente alineada. Por ejemplo, change_password - > PUT; deactivate - > probably DELETE; add_credit - >posiblemente POST o PUT. Señale al cliente a los URI apropiados incluyéndolos en sus representaciones.

Re 3. No inventes nuevos códigos de estado, a menos que creas que son tan genéricos que merecen ser estandarizados a nivel mundial. Intente utilizar el código de estado más apropiado disponible (lea sobre todos ellos en RFC 2616). Incluya información adicional en el cuerpo de respuesta. Si realmente, realmente está seguro de que desea inventar un nuevo código de estado, piense de nuevo; si todavía cree por lo tanto, asegúrese de elegir al menos la categoría correcta (1xx -> OK, 2xx -> informativo, 3xx -> redirección; 4xx-> error del cliente, 5xx -> error del servidor). ¿Mencioné que inventar nuevos códigos de estado es una mala idea?

Pregunta 4. Si es posible, utilice el marco de autenticación integrado en HTTP. Echa un vistazo a la forma en que Google hace la autenticación en GData. En general, no pongas claves API en tus URI. Trate de evitar las sesiones para mejorar la escalabilidad y apoyar el almacenamiento en caché-si la respuesta a un la solicitud difiere debido a algo que ha sucedido antes, generalmente se ha vinculado a una instancia de proceso de servidor específica. Es mucho mejor convertir el estado de la sesión en estado cliente (por ejemplo, hacerlo parte de las solicitudes posteriores) o hacerlo explícito convirtiéndolo en estado de recurso (servidor), es decir, darle su propio URI.

 29
Author: Stefan Tilkov,
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-03-23 15:53:18

1. Tienes la idea correcta sobre cómo diseñar tus recursos, en mi humilde opinión. Yo no cambiaría nada.

2. En lugar de tratar de extender HTTP con más verbos, considere lo que sus verbos propuestos se pueden reducir en términos de los métodos y recursos básicos de HTTP. Por ejemplo, en lugar de un verbo activate_login, puedes configurar recursos como: /api/users/1/login/active que es un booleano simple. Para activar un login, basta con PUT un documento que diga 'true' o 1 o lo que sea. A desactivar, PUT un documento que está vacío o dice 0 o false.

Del mismo modo, para cambiar o establecer contraseñas, simplemente haga PUT s a /api/users/1/password.

Siempre que necesite agregar algo (como un crédito) piense en términos de POST s. Por ejemplo, podría hacer un POST a un recurso como /api/users/1/credits con un cuerpo que contenga el número de créditos a agregar. Un PUT en el mismo recurso podría usarse para sobrescribir el valor en lugar de agregar. Un POST con un número negativo en el cuerpo restaría, y así en.

3. Recomiendo encarecidamente no extender los códigos de estado HTTP básicos. Si no puede encontrar uno que coincida exactamente con su situación, elija el más cercano y coloque los detalles del error en el cuerpo de respuesta. Además, recuerde que los encabezados HTTP son extensibles; su aplicación puede definir todos los encabezados personalizados que desee. Una aplicación en la que trabajé, por ejemplo, podría devolver un 404 Not Found bajo múltiples circunstancias. En lugar de hacer que el cliente analice el cuerpo de respuesta para la razón, acabamos de agregar un nuevo encabezado, X-Status-Extended, que contenía nuestras extensiones de código de estado propietarias. Así que usted podría ver una respuesta como:

HTTP/1.1 404 Not Found    
X-Status-Extended: 404.3 More Specific Error Here

De esa manera un cliente HTTP como un navegador web todavía sabrá qué hacer con el código 404 normal, y un cliente HTTP más sofisticado puede elegir mirar el encabezado X-Status-Extended para obtener información más específica.

4. Para la autenticación, recomiendo usar la autenticación HTTP si puede. Pero en mi humilde opinión no hay nada malo con usar la autenticación basada en cookies si es más fácil para usted.

 21
Author: friedo,
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
2010-01-04 21:28:32

Conceptos básicos de DESCANSO

REST tiene una restricción de interfaz uniforme, que establece que el cliente REST debe confiar en estándares en lugar de detalles específicos de la aplicación del servicio REST real, por lo que el cliente REST no se romperá por cambios menores, y probablemente será reutilizable.

Así que hay un contrato entre el cliente REST y el servicio REST. Si utiliza HTTP como protocolo subyacente, los siguientes estándares forman parte del contrato:

  • HTTP 1.1
    • definiciones del método
    • definiciones del código de estado
    • encabezados de control de caché
    • encabezados accept y content-type
    • encabezados de autenticación
  • IRI (utf8 URI)
  • cuerpo (elige uno)
    • tipo MIME específico de la aplicación registrada, por ejemplo maze + xml
    • tipo MIME específico del proveedor, por ejemplo, vnd.github + json
    • tipo MIME genérico con
      • vocabulario RDF específico de la aplicación, p. ej. ld+json & hydra, schema.org
      • perfil específico de la aplicación, por ejemplo hal + json & perfil link param (supongo)
  • hipervínculos
    • lo que debe contener (elija uno)
      • enviando encabezados de enlace
      • enviando una respuesta hipermedia, por ejemplo, html, atom + xml, hal + json, ld + json & hydra, etc...
    • semántica
      • utilice las relaciones de enlace de IANA y probablemente personalizado relaciones de enlace
      • use un vocabulario RDF específico de la aplicación

REST tiene una restricción sin estado, que declara que la comunicación entre el servicio REST y el cliente debe ser sin estado. Esto significa que el servicio REST no puede mantener los estados del cliente, por lo que no puede tener un almacenamiento de sesiones del lado del servidor. Tienes que autenticar cada solicitud. Por ejemplo, HTTP basic auth (parte del estándar HTTP) está bien, porque envía el nombre de usuario y contraseña con cada solicitud.

Para responder a sus preguntas

  1. Sí, puede ser.

    Solo por mencionar, los clientes no se preocupan por la estructura IRI, se preocupan por la semántica, porque siguen enlaces que tienen relaciones de enlace o atributos de datos vinculados (RDF).

    Lo único importante sobre el IRIS, que un único IRI debe identificar solo un único recurso. Se le permite a un solo recurso, como un usuario, tener muchos IRIS diferentes.

    It es bastante simple por qué usamos IRIs agradable como /users/123/password; es mucho más fácil escribir la lógica de enrutamiento en el servidor cuando entiendes el IRI simplemente leyéndolo.

  2. Tienes más verbos, como PUT, PATCH, OPTIONS e incluso más, pero no necesitas más de ellos... En lugar de agregar verbos nuevos, tienes que aprender a agregar nuevos recursos.

    activate_login -> PUT /login/active true deactivate_login -> PUT /login/active false change_password -> PUT /user/xy/password "newpass" add_credit -> POST /credit/raise {details: {}}

    (El login no tiene sentido desde la perspectiva REST, debido a la restricción sin estado.)

  3. Su a los usuarios no les importa por qué existe el problema. Solo quieren saber si hay éxito o error, y probablemente un mensaje de error que puedan entender, por ejemplo: "Lo siento, pero no pudimos guardar tu publicación.", sucesivamente...

    Las cabeceras de estado HTTP son las cabeceras estándar. Todo lo demás debería estar en el cuerpo, creo. Un solo encabezado no es suficiente para describir, por ejemplo, mensajes de error multilingües detallados.

  4. La restricción sin estado (junto con la caché y restricciones del sistema en capas) asegura que el servicio se escale bien. Seguramente no quiere mantener millones de sesiones en el servidor, cuando puede hacer lo mismo en los clientes...

    El cliente de tercera parte obtiene un token de acceso si el usuario le otorga acceso usando el cliente principal. Después de eso, el cliente de tercera parte envía el token de acceso con cada solicitud. Hay soluciones más complicadas, por ejemplo, puede firmar cada solicitud, etc. Para más detalles consulte el OAuth manual.

Literatura relacionada

 12
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-17 22:49:28

Para los ejemplos que usted indicó usaría lo siguiente:

Activate_login

POST /users/1/activation

Deactivate_login

DELETE /users/1/activation

Change_password

PUT /passwords (esto supone que el usuario está autenticado)

Add_credit

POST /credits (esto supone que el usuario está autenticado)

Para los errores, devolverías el error en el cuerpo en el formato en el que recibiste la solicitud, por lo que si recibes:

DELETE /users/1.xml

Enviarías la respuesta de vuelta en XML, el lo mismo sería cierto para JSON, etc...

Para la autenticación debe usar la autenticación http.

 11
Author: jonnii,
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
2010-01-04 21:35:42
  1. Use post cuando no sepa cómo se vería el nuevo URI de recursos (cree un nuevo usuario, la aplicación asignará al nuevo usuario su id), PUT para actualizar o crear recursos que sepa cómo se representarán (ejemplo: PUT /myfiles/thisismynewfile.txt)
  2. devuelve la descripción del error en el cuerpo del mensaje
  3. Puede usar la autenticación HTTP (si es suficiente) Los servicios web deben ser stateles
 6
Author: Arjan,
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
2010-01-04 20:06:15

Sugeriría (como primera pasada) que PUT solo se use para actualizar entidades existentes. POST debe usarse para crear nuevos. es decir,

/api/users     when called with PUT, creates user record

No me parece bien. El resto de su primera sección (re. uso del verbo) parece lógico, sin embargo.

 5
Author: Brian Agnew,
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
2010-01-04 20:03:06

Detallado, pero copiado de la especificación del método HTTP 1.1 en http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

9.3 GET

El método GET significa recuperar cualquier información (en forma de entidad) identificada por el URI de solicitud. Si el URI de solicitud se refiere a un proceso de producción de datos, son los datos producidos los que se devolverán como la entidad en la respuesta y no el texto fuente del proceso, a menos que ese texto resulte ser la salida del proceso.

La semántica del método GET cambia a "GET condicional" si el mensaje de solicitud incluye un campo de encabezado If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match o If-Range. Un método GET condicional solicita que la entidad se transfiera solo bajo las circunstancias descritas por los campos de encabezado condicional. El método GET condicional está diseñado para reducir el uso innecesario de la red al permitir que las entidades almacenadas en caché se actualicen sin requerir múltiples solicitudes o transferencia de datos ya en poder del cliente.

La semántica del método GET cambia a un "GET parcial" si el mensaje de solicitud incluye un campo de encabezado de rango. Un GET parcial solicita que solo se transfiera una parte de la entidad, como se describe en la sección 14.35. El método partial GET está diseñado para reducir el uso innecesario de la red al permitir que las entidades recuperadas parcialmente se completen sin transferir datos que ya posee el cliente.

La respuesta a un GET la solicitud se puede almacenar en caché si y solo si cumple con los requisitos para el almacenamiento en caché HTTP descritos en la sección 13.

Ver sección 15.1.3 para consideraciones de seguridad cuando se utiliza para formularios.

9.5 POST

El método POST se utiliza para solicitar que el servidor de origen acepte la entidad incluida en la solicitud como un nuevo subordinado del recurso identificado por el URI de la Solicitud en la Línea de solicitud. POST está diseñado para permitir un método uniforme para cubrir lo siguiente funciones:

  - Annotation of existing resources;
  - Posting a message to a bulletin board, newsgroup, mailing list,
    or similar group of articles;
  - Providing a block of data, such as the result of submitting a
    form, to a data-handling process;
  - Extending a database through an append operation.

La función real realizada por el método POST es determinada por el servidor y generalmente depende del URI de la solicitud. La entidad publicada está subordinada a ese URI de la misma manera que un archivo está subordinado a un directorio que lo contiene, un artículo de noticias está subordinado a un grupo de noticias al que se publica, o un registro está subordinado a una base de datos.

La acción realizada por el método POST podría no resultar en un recurso que pueda ser identificado por un URI. En este caso, 200 (OK) o 204 (Sin contenido) es el estado de respuesta apropiado, dependiendo de si la respuesta incluye o no una entidad que describe el resultado.

Si se ha creado un recurso en el servidor de origen, la respuesta DEBE ser 201 (Creado) y contener una entidad que describa el estado de la solicitud y se refiera al nuevo recurso, y un encabezado de ubicación (consulte la sección 14.30).

Las respuestas a este método no se pueden almacenar en caché, a menos que la respuesta incluya campos de encabezado de control de caché o Caduca apropiados. Sin embargo, la respuesta 303 (Ver Otro) se puede usar para dirigir al agente de usuario a recuperar un recurso cacheable.

Las solicitudes POST DEBEN cumplir los requisitos de transmisión de mensajes establecidos en la sección 8.2.

Véase la sección 15.1.3 para las consideraciones de seguridad.

9.6 PUT

El método PUT solicita que la entidad incluida se almacene bajo el URI de solicitud suministrado. Si el URI de solicitud se refiere a un recurso ya existente, la entidad incluida debe considerarse como una versión modificada de la que reside en el servidor de origen. Si el URI de solicitud no apunta a un recurso existente y el agente de usuario solicitante puede definir ese URI como un recurso nuevo, el servidor de origen puede crear el recurso con ese URI. Si se crea un nuevo recurso, el servidor de origen DEBE informar al agente de usuario a través de la respuesta 201 (Creada). Si se modifica un recurso existente, el 200 (OK) o el 204 (Sin contenido) los códigos de respuesta deben enviarse para indicar que la solicitud se ha completado con éxito. Si el recurso no se pudo crear o modificar con el URI de solicitud, se debe dar una respuesta de error adecuada que refleje la naturaleza del problema. El destinatario de la entidad NO DEBE ignorar ningún encabezado Content-* (por ejemplo, Content-Range) que no comprenda o implemente y DEBE devolver una respuesta 501 (No Implementada) en tales casos.

Si la solicitud pasa a través de una caché y la Solicitud-URI identifica una o más entidades actualmente almacenadas en caché, esas entradas DEBEN tratarse como obsoletas. Las respuestas a este método no se pueden almacenar en caché.

La diferencia fundamental entre las solicitudes POST y PUT se refleja en el significado diferente del URI de solicitud. El URI en una solicitud POST identifica el recurso que manejará la entidad incluida. Ese recurso puede ser un proceso de aceptación de datos, una puerta de enlace a algún otro protocolo o una entidad separada que acepte anotaciones. En contraste, el URI en una solicitud PUT identifica la entidad incluida con la solicitud the el agente de usuario sabe qué URI se pretende y el servidor NO DEBE intentar aplicar la solicitud a otro recurso. Si el servidor desea que la solicitud se aplique a un URI diferente,

DEBE enviar una respuesta 301 (Movida Permanentemente); el agente de usuario PUEDE entonces tomar su propia decisión con respecto a si redirigir o no la solicitud.

Un único recurso PUEDE ser identificado por muchos URI diferentes. Para por ejemplo, un artículo puede tener un URI para identificar "la versión actual" que es independiente del URI que identifica cada versión en particular. En este caso, una solicitud PUT en un URI general puede resultar en que el servidor de origen defina varios otros URI.

HTTP/1.1 no define cómo un método PUT afecta el estado de un servidor de origen.

LAS solicitudes PUT DEBEN cumplir los requisitos de transmisión de mensajes establecidos en la sección 8.2.

A menos que se especifique otra cosa para una entity-header particular, los entity-headers en la solicitud PUT deben aplicarse al recurso creado o modificado por el PUT.

9.7 SUPRIMIR

El método DELETE solicita que el servidor de origen elimine el recurso identificado por el URI de solicitud. Este método PUEDE ser anulado por intervención humana (u otros medios) en el servidor de origen. El cliente no puede garantizar que la operación se ha llevado a cabo, incluso si el código de estado devuelto desde el servidor de origen indica que la acción se ha completado con éxito. Sin embargo, el servidor NO DEBE indicar éxito a menos que, en el momento en que se da la respuesta, tenga la intención de eliminar el recurso o moverlo a una ubicación inaccesible.

Una respuesta exitosa DEBE ser 200 (OK) si la respuesta incluye una entidad que describe el estado, 202 (Aceptada) si la acción aún no se ha promulgado, o 204 (Sin contenido) si la acción se ha promulgado pero la respuesta no incluye una entidad.

Si la solicitud pasa a través de una caché y el URI de solicitud identifica una o más entidades actualmente almacenadas en caché, esas entradas DEBEN tratarse como obsoletas. Las respuestas a este método no se pueden almacenar en caché.

 5
Author: gahooa,
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
2010-01-04 20:10:14

Acerca de los códigos de retorno REST: es incorrecto mezclar códigos de protocolo HTTP y resultados REST.

Sin embargo, vi muchas implementaciones mezclándolas, y muchos desarrolladores pueden no estar de acuerdo conmigo.

Los códigos de retorno HTTP están relacionados con el propio HTTP Request. Una llamada REST se realiza utilizando una solicitud de Protocolo de transferencia de Hipertexto y funciona a un nivel más bajo que el método REST invocado en sí. REST es un concepto / enfoque, y su salida es un resultado empresarial / lógico , mientras que el código de resultado HTTP es un transporte uno.

Por ejemplo, devolver "404 Not found" cuando llamas a / users / es confuso, porque puede significar:

  • URI es incorrecto (HTTP)
  • No se encuentran usuarios (REST)

"403 Prohibido / Acceso Denegado" puede significar:

  • Se necesita un permiso especial. Los navegadores pueden manejarlo preguntando al usuario / contraseña. (HTTP)
  • Permisos de acceso incorrectos configurados en el servidor. (HTTP)
  • Necesita ser autenticado (RESTO)

Y la lista puede continuar con 'Error de servidor 500" (un error HTTP lanzado de Apache/Nginx o un error de restricción de negocio en REST) u otros errores HTTP, etc...

A partir del código, es difícil entender cuál fue la razón del fallo, un fallo HTTP (transporte) o un fallo REST (lógico).

Si la solicitud HTTP físicamente se realizó con éxito, siempre devolverá 200 código, independientemente de que se encuentren o no los registros. Porque el recurso URI es {[8] encontrado} y fue manejado por el servidor http. Sí, puede devolver un conjunto vacío. Es posible recibir una página web vacía con 200 como resultado http, ¿verdad?

En lugar de esto, puede devolver 200 código HTTP y simplemente un JSON con un array/objeto vacío, o usar un indicador bool result/success para informar sobre el estado de la operación realizada.

Además, algunos proveedores de Internet pueden interceptar sus solicitudes y devolverle un código http 404. Esto no significa que sus datos no se encuentren, pero algo está mal a nivel de transporte.

De Wiki:

En julio de 2004, el proveedor de telecomunicaciones británico BT Group implementó el Cleanfeed sistema de bloqueo de contenido, que devuelve un error 404 a cualquier solicitud de contenido identificado como potencialmente ilegal por Internet Watch Fundación. Otros ISP devuelven un error HTTP 403 "prohibido" en el mismo circunstancia. La práctica de emplear falsos errores 404 como un medio para también se ha informado de censura oculta en Tailandia y Túnez. En Túnez, donde la censura era severa antes de la revolución de 2011, la gente se dio cuenta de la naturaleza de los falsos errores 404 y creó un personaje imaginario llamado "Ammar 404" que representa " lo invisible censura".

 2
Author: Marcodor,
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-09-23 12:08:47