ejemplo - buenas practicas api rest




API REST Mejores prácticas: ¿Dónde colocar los parámetros? (10)

Una API REST puede tener parámetros de al menos dos formas:

  1. Como parte de la ruta URL (es decir, /api/resource/parametervalue )
  2. Como un argumento de consulta (es decir, /api/resource?parameter=value )

¿Cuál es la mejor práctica aquí? ¿Existen pautas generales sobre cuándo usar 1 y cuándo usar 2?

Ejemplo del mundo real: Twitter utiliza parámetros de consulta para especificar intervalos. ( http://api.twitter.com/1/statuses/home_timeline.json?since_id=12345&max_id=54321 )

¿Se consideraría un mejor diseño para poner estos parámetros en la ruta de la URL?


"Empaque" y publique sus datos en el "contexto" que proporciona el localizador de recursos del universo, que significa # 1 por el bien del localizador.

Cuidado con las limitaciones con # 2. Prefiero los POST al # 1.

nota: las limitaciones se discuten para

POST en ¿Hay un tamaño máximo para el contenido del parámetro POST?

GET in ¿Hay un límite a la longitud de una solicitud GET? y tamaño máximo de los parámetros de URL en _GET

ps estos límites se basan en las capacidades del cliente (navegador) y el servidor (configuración).


Aquí está mi opinión.

Los parámetros de consulta se utilizan como metadatos para una solicitud. Actúan como filtro o modificador de una llamada de recurso existente.

Ejemplo:

/calendar/2014-08-08/events

Debe dar los eventos del calendario para ese día.

Si quieres eventos para una categoría específica.

/calendar/2014-08-08/events?category=appointments

O si necesitas eventos de más de 30 minutos.

/calendar/2014-08-08/events?duration=30

Una prueba de fuego sería para comprobar si la solicitud todavía se puede servir sin un parámetro de consulta.


De acuerdo con el estándar URI, la ruta es para parámetros jerárquicos y la consulta es para parámetros no jerárquicos. De c. Puede ser muy subjetivo lo que es jerárquico para ti.

En situaciones en las que se asignan múltiples URI al mismo recurso, me gusta colocar los parámetros (necesarios para la identificación) en la ruta y los parámetros (necesarios para construir la representación) en la consulta. (Para mí de esta manera es más fácil enrutar).

Por ejemplo:

  • /users/123 y /users/123?fields="name, age"
  • /users y /users?name="John"&age=30

Para reducir el mapa me gusta usar los siguientes enfoques:

  • /users?name="John"&age=30
  • /users/name:John/age:30

Por lo tanto, depende realmente de usted (y del enrutador del lado del servidor) cómo construye sus URI.

Nota: Solo para mencionar estos parámetros son parámetros de consulta. Entonces, lo que realmente está haciendo es definir un lenguaje de consulta simple. Por consultas complejas (que contienen operadores como y, o, mayor que, etc.) le sugiero que utilice un lenguaje de consulta ya existente. Las capacidades de las here son muy limitadas ...


Depende de un diseño. No hay reglas para los URI en REST a través de HTTP (lo principal es que son únicos). A menudo se trata de la cuestión del gusto y la intuición ...

Tomo el siguiente enfoque:

  • url ruta-elemento: el recurso y su ruta-elemento forman un recorrido transversal de directorio y un sub-recurso (por ejemplo, / items / {id}, / users / items). Cuando no esté seguro, pregúntele a sus colegas, si piensan que atravesar y piensan en "otro directorio" lo más probable es que el elemento de ruta sea la opción correcta
  • parámetro url: cuando realmente no hay recorrido (los recursos de búsqueda con múltiples parámetros de consulta son un buen ejemplo para eso)

Es una pregunta muy interesante.

Puede usar ambos, no hay ninguna regla estricta sobre este tema, pero el uso de las variables de ruta URI tiene algunas ventajas:

  • Caché : la mayoría de los servicios de caché web en Internet no almacenan en caché la solicitud GET cuando contienen parámetros de consulta. Lo hacen porque hay muchos sistemas RPC que usan solicitudes GET para cambiar los datos en el servidor (¡falla! ¡Get debe ser un método seguro)

Pero si usa variables de ruta, todos estos servicios pueden almacenar en caché sus solicitudes GET.

  • Jerarquía : las variables de ruta pueden representar jerarquía: / Ciudad / Calle / Lugar

Le da al usuario más información sobre la estructura de los datos.

Pero si sus datos no tienen ninguna relación jerárquica, aún puede usar las variables de ruta, usando coma o punto y coma:

/ Ciudad / longitud, latitud

Como regla general, use una coma cuando el orden de los parámetros es importante, use punto y coma cuando el orden no importa:

/ IconGenerator / rojo; azul; verde

Aparte de esas razones, hay algunos casos en los que es muy común utilizar variables de cadena de consulta:

  • Cuando necesite que el navegador coloque automáticamente las variables de formulario HTML en el URI
  • Cuando se trata de algoritmo. Por ejemplo, el motor de Google utiliza cadenas de consulta:

http: // www.google.com/search?q=rest

En resumen, no hay ninguna razón importante para usar uno de estos métodos, pero siempre que pueda, use las variables URI.


Generalmente tiendo hacia el # 2, como un argumento de consulta (es decir, / api / resource? Parámetro = valor).

Una tercera opción es publicar el parámetro = valor en el cuerpo.

Esto se debe a que funciona mejor para recursos de múltiples parámetros y es más extensible para uso futuro.

No importa cuál elijas, asegúrate de elegir solo uno, no mezclar y combinar. Eso lleva a una API confusa.


Respuesta tardía, pero agregaré información adicional a lo que se ha compartido, a saber, que hay varios tipos de "parámetros" en una solicitud, y debe tener esto en cuenta.

  1. Localizadores: por ejemplo, identificadores de recursos como ID o acción / vista
  2. Filtros: por ejemplo, los parámetros que proporcionan una búsqueda, ordenan o reducen el conjunto de resultados.
  3. Estado - Ej. Identificación de sesión, api keys, whatevs.
  4. Contenido - Por ejemplo, datos a almacenar.

Ahora veamos los diferentes lugares donde podrían ir estos parámetros.

  1. Solicitar encabezados y cookies
  2. Cadena de consulta de URL ("GET" vars)
  3. Rutas de URL
  4. Cuerpo consulta cadena / multiparte ("POST" vars)

En general, desea que el estado se establezca en encabezados o cookies, según el tipo de información de estado que sea. Creo que todos podemos estar de acuerdo en esto. Use encabezados http personalizados (X-My-Header) si lo necesita.

De manera similar, el Contenido solo tiene un lugar al que pertenecer, que está en el cuerpo de la solicitud, ya sea como cadenas de consulta o como contenido de multipartas http y / o JSON. Esto es consistente con lo que recibe del servidor cuando le envía contenido. Así que no deberías ser grosero y hacerlo de manera diferente.

Los localizadores como "id = 5" o "action = refresh" o "page = 2" tendrían sentido como una ruta URL, como mysite.com/article/5/page=2 donde en parte sabes qué es cada parte se supone que significa (los conceptos básicos, como el artículo y 5, obviamente, significa obtener los datos del tipo de artículo con id 5) y los parámetros adicionales se especifican como parte de la URI. Pueden estar en la forma de page=2 , o page/2 si sabe que después de cierto punto en el URI, las "carpetas" son valores-clave emparejados.

Los filtros siempre van en la cadena de consulta, porque mientras forman parte de la búsqueda de los datos correctos, solo están allí para devolver un subconjunto o modificación de lo que devuelven los Localizadores. La búsqueda en mysite.com/article/?query=Obama (subconjunto) es un filtro, y también lo es /article/5?order=backwards mysite.com/article/?query=Obama /article/5?order=backwards (modificación). ¡Piensa en lo que hace, no solo en lo que se llama!

Si "vista" determina el formato de salida, entonces es un filtro ( mysite.com/article/5?view=pdf ) porque devuelve una modificación del recurso encontrado en lugar de buscar en qué recurso queremos. Si, en cambio, decide qué parte específica del artículo veremos ( mysite.com/article/5/view=summary ), entonces es un localizador.

Recuerda, restringir un conjunto de recursos se está filtrando. Localizar algo específico dentro de un recurso es localizar ... duh. El filtrado de subconjuntos puede devolver cualquier número de resultados (incluso 0). La localización siempre encontrará esa instancia específica de algo (si existe). El filtrado de modificaciones devolverá los mismos datos que el localizador, excepto los modificados (si se permite tal modificación).

¡Espero que esto haya ayudado a dar a la gente algunos momentos de eureka si se han perdido sobre dónde poner las cosas!


Según la implementación REST,

1) Las variables de ruta se utilizan para la acción directa sobre los recursos, como un contacto o una canción, por ejemplo.
GET etc / api / resource / {songid} o
GET etc / api / resource / {contactid} devolverá los datos respectivos.

2) Los permisos / argumentos de consulta se utilizan para los recursos directos como los metadatos de una canción, por ejemplo, GET / api / resource / {songid}? Metadata = géneros que devolverán los datos de géneros para esa canción en particular.


Una "dimensión" de este tema se ha omitido, pero es muy importante: hay veces en que las "mejores prácticas" tienen que ponerse de acuerdo con la plataforma que estamos implementando o aumentando con las capacidades REST.

Ejemplo práctico:

Muchas aplicaciones web actualmente implementan la arquitectura MVC (Modelo, Vista, Controlador). Asumen que se proporciona una determinada ruta estándar, incluso más cuando esas aplicaciones web vienen con la opción "Habilitar URL de SEO".

Solo por mencionar una aplicación web bastante famosa: una tienda de comercio electrónico OpenCart. Cuando el administrador habilita las "URL de SEO", espera que dichas URL vengan en un formato MVC bastante estándar como:

http://www.domain.tld/special-offers/list-all?limit=25

Dónde

  • special-offers es el controlador MVC que procesará la URL (mostrando la página de ofertas especiales)

  • list-all es la acción del controlador o el nombre de la función a llamar. (*)

  • limit = 25 es una opción, que indica que se mostrarán 25 elementos por página.

(*) list-all es un nombre de función ficticio que utilicé para mayor claridad. En realidad, OpenCart y la mayoría de los marcos MVC tienen una función de index predeterminada, implícita (y generalmente omitida en la URL) que se llama cuando el usuario desea que se realice una acción predeterminada. Así que la URL del mundo real sería:

http://www.domain.tld/special-offers?limit=25

Con una estructura de aplicación o frameworkd ahora bastante estándar similar a la anterior, a menudo obtendrá un servidor web que está optimizado para ella, que vuelve a escribir las URL (la verdadera "URL sin SEO" sería: http://www.domain.tld/index.php?route=special-offers/list-all&limit=25 ).

Por lo tanto, usted, como desarrollador, se enfrenta a lidiar con la infraestructura existente y adapta sus "mejores prácticas", a menos que sea el administrador del sistema, sepa exactamente cómo modificar una configuración de reescritura de Apache / NGinx (¡esta última puede ser desagradable!) Y así en.

Por lo tanto, su API REST a menudo sería mucho mejor siguiendo los estándares de la aplicación web de referencia, tanto por su consistencia como por su facilidad / velocidad (y por lo tanto, el ahorro de presupuesto).

Para volver al ejemplo práctico anterior, una API REST coherente sería algo con URL como:

http://www.domain.tld/api/special-offers-list?from=15&limit=25

o (URLs no SEO)

http://www.domain.tld/index.php?route=api/special-offers-list?from=15&limit=25

con una mezcla de argumentos de "caminos formados" y argumentos de "consulta formada".


Veo muchas API REST que no manejan bien los parámetros. Un ejemplo que aparece a menudo es cuando el URI incluye información de identificación personal.

http://software.danielwatrous.com/design-principles-for-rest-apis/

Creo que una pregunta de corolario es cuándo un parámetro no debería ser un parámetro, sino que debería moverse al HEADER o BODY de la solicitud.







design