CONSUL
Search…
GraphQL

Características

    API de sólo lectura
    Acceso público, sin autenticación
    Usa GraphQL por debajo
      El tamaño máximo (y por defecto) de página está establecido a 25
      La profundiad máxima de las consultas es de 8 niveles
      Como máximo se pueden solicitar 2 colecciones en una misma consulta
      Soporte para peticiones GET (consulta dentro del query string) y POST (consulta dentro del body, como application/json o application/graphql).

GraphQL

La API de CONSUL utiliza GraphQL http://graphql.org, en concreto la implementación en Ruby. Si no estás familiarizado con este tipo de APIs, es recomendable investigar un poco sobre GraphQL previamente.
Una de las caracteríticas que diferencian una API REST de una GraphQL es que con esta última es posible construir consultas personalizadas, de forma que el servidor nos devuelva únicamente la información en la que estamos interesados.
Las consultas en GraphQL están escritas siguiendo un estándar que presenta ciertas similitudes con el formato JSON, por ejemplo:
1
{
2
proposal(id: 1) {
3
id,
4
title,
5
public_author {
6
id,
7
username
8
}
9
}
10
}
Copied!
Las respuestas son en formato JSON:
1
{
2
"data": {
3
"proposal": {
4
"id": 1,
5
"title": "Hacer las calles del centro de Madrid peatonales",
6
"public_author": {
7
"id": 2,
8
"username": "electrocronopio"
9
}
10
}
11
}
12
}
Copied!

Haciendo peticiones a la API

Siguiendo las directrices oficiales, la API de CONSUL soporta los siguientes tipos de peticiones:
    Peticiones GET, con la consulta dentro del query string.
    Peticiones POST
      Con la consulta dentro del body, con Content-Type: application/json
      Con la consulta dentro del body, con Content-Type: application/graphql

Clientes soportados

Al ser una API que funciona a través de HTTP, cualquier herramienta capaz de realizar este tipo de peticiones resulta válida.
Esta sección contiene unos pequeños ejemplos sobre cómo hacer las peticiones a través de:
    GraphiQL
    Extensiones de Chrome como Postman
    Cualquier librería HTTP

GraphiQL

GraphiQL es una interfaz de navegador para realizar consultas a una API GraphQL, así como una fuente adicional de documentación. Está desplegada en la ruta /graphiql y es la mejor forma de familiarizarse una API basada en GraphQL.
GraphiQL
Tiene tres paneles principales:
    En el panel de la izquierda se escribe la consulta a realizar.
    El panel central muestra el resultado de la petición.
    El panel derecho (ocultable) contiene una documentación autogenerada a partir de la información expuesta en la API.

Postman

Ejemplo de petición GET, con la consulta como parte del query string:
Postman GET
Ejemplo de petición POST, con la consulta como parte del body y codificada como application/json:
Postman POST
La consulta debe estar ubicada en un documento JSON válido, como valor de la clave "query":
Postman POST

Librerías HTTP

Por supuesto es posible utilizar cualquier librería HTTP de lenguajes de programación.
IMPORTANTE: Debido a los protocolos de seguridad de los servidores del Ayuntamiento de Madrid, es necesario incluir un User Agent perteneciente a un navegador para que la petición no sea descartada. Por ejemplo:
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36

Información disponible

El fichero config/api.yml contiene una lista completa de los modelos (y sus campos) que están expuestos actualmente en la API.
La lista de modelos es la siguiente:
Modelo
Descripción
User
Usuarios
Debate
Debates
Proposal
Propuestas
Comment
Comentarios en debates, propuestas y otros comentarios
Geozone
Geozonas (distritos)
ProposalNotification
Notificaciones asociadas a propuestas
Tag
Tags en debates y propuestas
Vote
Información sobre votos

Ejemplos de consultas

Recuperar un único elemento de una colección

``` { proposal(id: 2) { id, title, comments_count } } ``` Respuesta: ```json { "data": { "proposal": { "id": 2, "title": "Crear una zona cercada para perros en Las Tablas", "comments_count": 10 } } } ```

Recuperar una colección completa

1
{
2
proposals {
3
edges {
4
node {
5
title
6
}
7
}
8
}
9
}
Copied!
Respuesta:
1
{
2
"data": {
3
"proposals": {
4
"edges": [
5
{
6
"node": {
7
"title": "ELIMINACION DE ZONA APARCAMIENTO EXCLUSIVO FUNCIONARIOS EN MADRID"
8
}
9
},
10
{
11
"node": {
12
"title": "iluminación de zonas deportivas"
13
}
14
}
15
]
16
}
17
}
18
}
Copied!

Paginación

Actualmente el número máximo (y por defecto) de elementos que se devuelven en cada página está establecido a 25. Para poder navegar por las distintas páginas es necesario solicitar además información relativa al endCursor:
1
{
2
proposals(first: 25) {
3
pageInfo {
4
hasNextPage
5
endCursor
6
}
7
edges {
8
node {
9
title
10
}
11
}
12
}
13
}
Copied!
La respuesta:
1
{
2
"data": {
3
"proposals": {
4
"pageInfo": {
5
"hasNextPage": true,
6
"endCursor": "NQ=="
7
},
8
"edges": [
9
# ...
10
]
11
}
12
}
13
}
Copied!
Para recuperar la siguiente página, hay que pasar como parámetro el cursor recibido en la petición anterior, y así sucesivamente:
1
{
2
proposals(first: 25, after: "NQ==") {
3
pageInfo {
4
hasNextPage
5
endCursor
6
}
7
edges {
8
node {
9
title
10
}
11
}
12
}
13
}
Copied!

Acceder a varios recursos en una única petición

Esta consulta solicita información relativa a varios modelos distintos en una única petición: Proposal, User, Geozone y Comment:
1
{
2
proposal(id: 15262) {
3
id,
4
title,
5
public_author {
6
username
7
},
8
geozone {
9
name
10
},
11
comments(first: 2) {
12
edges {
13
node {
14
body
15
}
16
}
17
}
18
}
19
}
Copied!

Limitaciones de seguridad

Permitir que un cliente personalice las consultas supone un factor de riesgo importante. Si se permitiesen consultas demasiado complejas, sería posible realizar un ataque DoS contra el servidor.
Existen tres mecanismos principales para evitar este tipo de abusos:
    Paginación de resultados
    Limitar la profundidad máxima de las consultas
    Limitar la cantidad de información que es posible solicitar en una consulta

Ejemplo de consulta demasiado profunda

La profundidad máxima de las consultas está actualmente establecida en 8. Consultas más profundas (como la siguiente), serán rechazadas:
1
{
2
user(id: 1) {
3
public_proposals {
4
edges {
5
node {
6
id,
7
title,
8
comments {
9
edges {
10
node {
11
body,
12
public_author {
13
username
14
}
15
}
16
}
17
}
18
}
19
}
20
}
21
}
22
}
Copied!
La respuesta obtenida tendrá el siguiente aspecto:
1
{
2
"errors": [
3
{
4
"message": "Query has depth of 9, which exceeds max depth of 8"
5
}
6
]
7
}
Copied!

Ejemplo de consulta demasiado compleja

El principal factor de riesgo se da cuando se solicitan varias colecciones de recursos en una misma consulta. El máximo número de colecciones que pueden aparecer en una misma consulta está limitado a 2. La siguiente consulta solicita información de las colecciónes users, debates y proposals, así que será rechazada:
1
{
2
users {
3
edges {
4
node {
5
public_debates {
6
edges {
7
node {
8
title
9
}
10
}
11
},
12
public_proposals {
13
edges {
14
node {
15
title
16
}
17
}
18
}
19
}
20
}
21
}
22
}
Copied!
La respuesta obtenida tendrá el siguiente aspecto:
1
{
2
"errors": [
3
{
4
"message": "Query has complexity of 3008, which exceeds max complexity of 2500"
5
},
6
{
7
"message": "Query has complexity of 3008, which exceeds max complexity of 2500"
8
},
9
{
10
"message": "Query has complexity of 3008, which exceeds max complexity of 2500"
11
}
12
]
13
}
Copied!
No obstante sí que es posible solicitar información perteneciente a más de dos modelos en una única consulta, siempre y cuando no se intente acceder a la colección completa. Por ejemplo, la siguiente consulta que accede a los modelos User, Proposal y Geozone es válida:
1
{
2
user(id: 468501) {
3
id
4
public_proposals {
5
edges {
6
node {
7
title
8
geozone {
9
name
10
}
11
}
12
}
13
}
14
}
15
}
Copied!
La respuesta:
1
{
2
"data": {
3
"user": {
4
"id": 468501,
5
"public_proposals": {
6
"edges": [
7
{
8
"node": {
9
"title": "Empadronamiento necesario para la admisión en GoFit Vallehermoso",
10
"geozone": {
11
"name": "Chamberí"
12
}
13
}
14
}
15
]
16
}
17
}
18
}
19
}
Copied!

Ejemplos de código

El directorio doc/api/examples contiene ejemplos de código para acceder a la API.
Last modified 6mo ago