¿Qué es cURL?
¿Has oído hablar de cURL? Es una famosa herramienta de línea de comandos para enviar/recibir datos utilizando la sintaxis URL, dice wikipedia aquí. Empecemos con un ejemplo relacionado con Couchbase. El servicio de consulta N1QL está disponible a través de una API REST. Si quieres ejecutar una consulta N1QL con cURL, y suponiendo que tu servicio de consulta está habilitado en localhost, se verá así:
curl http://localhost:8093/query/service -d 'statement=SELECT * FROM default LIMIT 1'
o si desea ejecutar una consulta de texto completo, haga algo como lo siguiente
curl -XPOST -H "Content-Type: application/json" http://localhost:8094/api/index/beer/query -d '{"explain": true, "fields": ["*"], "highlight": {}, "query": {"query": "pale ale"}}'
En este momento no hay nada específico sobre N1QLes sólo un ejemplo de llamada REST API con cURL. ¿Por qué este título? Pues porque puedes llamar a cURL desde una consulta N1QL.
cURL() en N1QL
curl() es una nueva función N1QL que permite acceder a datos JSON externos a través de un endpoint remoto (normalmente HTTP(s)). Al igual que otras funciones N1QL, esta función puede utilizarse en varias expresiones N1QL y varias cláusulas de las consultas SELECT/DML (proyección, where, from, etc.). Cuando se utiliza en la cláusula from, la invocación a curl() debe dar como resultado un conjunto/colección de documentos JSON.
Ya se ha tratado ampliamente en DZoneLe invito encarecidamente a leerlo, así como muchos otros artículos de DZone puestos sobre N1QL y escrito por el equipo de N1QL.
Podemos empezar como haría cualquiera al probar un nuevo idioma con un SELECT muy sencillo:
SELECT CURL("GET", "https://maps.googleapis.com/maps/api/geocode/json", {"data": "address=santa+cruz&components=country:ES&key=YOUR_API_KEY"});
Esto le dará el siguiente resultado JSON:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
[ { "resultados": [ { "dirección_componentes": [ { "nombre_largo": "Santa Cruz de Tenerife", "nombre_corto": "Santa Cruz de Tenerife", "tipos": [ "localidad", "político" ] }, { "nombre_largo": "Santa Cruz de Tenerife", "nombre_corto": "TF", "tipos": [ "zona_administrativa_nivel_2", "político" ] }, { "nombre_largo": "Islas Canarias", "nombre_corto": "CN", "tipos": [ "zona_administrativa_nivel_1", "político" ] }, { "nombre_largo": "España, "nombre_corto": "ES", "tipos": [ "país", "político" ] } ], "dirección_formateada": "Santa Cruz de Tenerife, España", "geometría": { "límites": { "noreste": { "lat": 28.487616, "lng": -16.2356646 }, "suroeste": { "lat": 28.4280248, "lng": -16.3370045 } }, "localización": { "lat": 28.4636296, "lng": -16.2518467 }, "tipo_ubicación": "APROXIMADO", "viewport": { "noreste": { "lat": 28.487616, "lng": -16.2356646 }, "suroeste": { "lat": 28.4280248, "lng": -16.3370045 } } }, "place_id": "ChIJcUElzOzMQQwRLuV30nMUEUM", "tipos": [ "localidad", "político" ] } ] } ] |
Aquí hay mucha información y quizá sólo le interese obtener las coordenadas de la dirección identificada. Es fácil hacerlo. Sólo tienes que tratar el resultado de la función cURL como cualquier otro objeto JSON:
SELECT CURL("GET", "https://maps.googleapis.com/maps/api/geocode/json", {"data": "address=santa+cruz&components=country:ES&key=YOUR_API_KEY"}).results[0].geometry ;
Y esto te devolverá justo lo que querías:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
[ { "geometría": { "límites": { "noreste": { "lat": 28.487616, "lng": -16.2356646 }, "suroeste": { "lat": 28.4280248, "lng": -16.3370045 } }, "localización": { "lat": 28.4636296, "lng": -16.2518467 }, "tipo_ubicación": "APROXIMADO", "viewport": { "noreste": { "lat": 28.487616, "lng": -16.2356646 }, "suroeste": { "lat": 28.4280248, "lng": -16.3370045 } } } } ] |
Aunque esto está muy bien, actualmente no existe ningún vínculo con sus datos. Supongamos que tiene un documento con una dirección pero sin coordenadas geográficas. Ahora puede añadir esas coordenadas con la siguiente consulta N1QL:
ACTUALIZACIÓNviaje-muestraUSE KEYS "myDocumentWithoutCoordinates" SET geo = CURL("GET", "https://maps.googleapis.com/maps/api/geocode/json", {"data": "address=santa+cruz&components=country:ES&key=YOUR_API_KEY"}).results[0].geometry returning *
Y ahora acaba de modificar un documento existente basado en un servicio externo con una consulta N1QL :)
He aquí otro ejemplo. La misma consulta FTS que antes, pero como cláusula FROM de una consulta N1QL:
SELECT result.total_hits, array_length(result.hits) FROM curl("POST", "http://localhost:8094/api/index/beer/query",{"header": "Content-Type: application/json", "data":{"explain":true, "fields": ["*"], "highlight": {}, "query": {"query": "pale ale"}} }) resultado;
Y esto te dará:
[ { "$1": 10, "total_hits": 3815 } ]
Ahora usted sabe que puede ejecutar una búsqueda de texto completo (o cualquier llamada a cualquier URL que devuelve JSON) y utilizar toda la bondad que es N1QL para obtener una buena proyección de los datos JSON. En cierto modo esto nos permite integrar FTS con N1QL. Ya que puedes usar cURL en una cláusula FROM puedes por ejemplo JOIN el resultado a un bucket.
He aquí otro ejemplo con ese espíritu, utilizando nuestra tradicional muestra de cerveza que contiene cervezas y un documento de cervecería. Primero transformamos la consulta anterior para obtener la lista de ID de los documentos que contienen "pale ale":
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
SELECCIONE hit.id DESDE rizo("POST","http://localhost:8094/api/index/beer/query", {"cabecera":"Content-Type: application/json", "datos":{"explicar":verdadero,"campos": ["*"],"destacar": {},"consulta": {"consulta": "pale ale"}} }) resultado UNNEST resultado.hits AS hit [ { "id": "piedra_cervecera_co-piedra_pale_ale" }, { "id": "sierra_nevada_cervecera_co-sierra_nevada_pale_ale" }, { "id": "yards_brewing-yards_philadelphia_pale_ale" }, { "id": "cooper_s_cave_ale_company-cooper_s_cave_pale_ale" }, { "id": "tommyknocker_brewery_and_pub-pick_axe_pale_ale" }, { "id": "bell_s_brewery_inc-pale_ale" }, { "id": "flying_dog_brewery-classic_pale_ale" }, { "id": "appalachian_brewing_company-hoppy_trails_india_pale_ale" }, { "id": "mogollon_brewing_company-superstition_pale_ale" }, { "id": "the_church_brew_works-pipe_organ_pale_ale" } ] |
Para obtener más información sobre esta consulta FTS y lo que puede hacer generalmente con la API REST de FTS, consulte la página documentación actual.
Ahora tenemos una lista de ID de documentos de FTS a la que podemos unirnos fácilmente:
SELECT beers.* FROM curl("POST", "http://localhost:8094/api/index/beer/query", {"header": "Content-Type: application/json", "data":{"explain":true, "fields": ["*"], "highlight": {}, "query": {"query": "pale ale"}} }) result UNNEST result.hits AS hit JOIN beer-sample beers ON KEYS hit.id
¿No es genial? Pero luego no tienes que limitarte a consultar Couchbase, puedes usar fuentes externas. Aquí tienes otro ejemplo. Encontrarás muchos conjuntos de datos JSON interesantes en catálogo.datos.gouv. Por ejemplo, puede consultar el Nombres de bebé más populares por sexo y grupo étnico de la madre en Nueva York. Es un archivo JSON grande, muchas filas, 13962 filas como se puede aprender corriendo:
SELECT count(row) FROM CURL("GET", "https://data.cityofnewyork.us/api/views/25th-nujf/rows.json?accessType=DOWNLOAD") result UNNEST result.data AS row
Y si desea un top 10 del nombre dado, puede ejecutar la siguiente consulta:
SELECT row FROM CURL("GET", "https://data.cityofnewyork.us/api/views/25th-nujf/rows.json?accessType=DOWNLOAD") result UNNEST result.data AS row ORDER BY TONUMBER(row[13]) ASC, TONUMBER(row[12]) DESC LIMIT 10
Parece que Jayden e Isabella son nombres muy populares en Nueva York estos días :)
A partir de estos ejemplos se puede ver que el lenguaje de consulta N1QL es una forma innovadora de averiguar lo que hay dentro de un gran archivo JSON. Básicamente puedes mapear un endpoint JSON a una Base de Datos :) Y por supuesto hay otras posibilidades que aún no hemos tocado como el uso de JOINs a través de un bucket Couchbase y un endpoint JSON.
Documentación
Ahora no soportamos todas las características de cURL. Sin embargo, debería cubrir lo básico y ser utilizable ahora mismo. Aquí está la lista de opciones que soportamos hasta ahora. La función curl toma hasta tres parámetros:
1 - El primer parámetro es el verbo HTTP utilizado. Hasta ahora soportamos "GET" y "POST".
2 - El segundo parámetro es la URL del punto final
3 - El tercer parámetro representa diferentes opciones de cURL.
Opciones de seguridad
Opción |
Descripción |
valor |
usuario |
Usuario y contraseña del servidor |
NOMBRE DE USUARIO[:CONTRASEÑA] |
básico |
Utilizar autenticación básica HTTP |
— |
inseguro |
Permitir conexiones a sitios SSL sin certificados (H) |
— |
anyauth |
curl para averiguar el método de autenticación por sí mismo, y utilizar el más seguro (En nuestro caso esto será sólo básico por ahora. Eventualmente soportaremos digest) |
— |
Otras opciones relacionadas con las transferencias
Opción |
Descripción |
valor |
tiempo de espera de conexión |
Tiempo máximo de conexión |
SEGUNDOS |
max-time |
Tiempo máximo permitido para la transferencia |
SEGUNDOS |
datos |
Datos HTTP POST (H) |
DATOS |
cabecera |
Pasar LÍNEA de cabecera personalizada al servidor (H) |
LÍNEA |
show-error |
Mostrar errores. Con -s, haga que CURL() muestre los errores cuando se produzcan. |
|
silencioso |
Modo silencioso (no emite nada) |
— |
max-redirs |
Número máximo de redireccionamientos permitidos (H) |
NUM |
keepalive-time |
Espere SEGUNDOS entre sondas keepalive |
SEGUNDOS |
Nos encantaría conocer tu opinión sobre esta función. ¿Cómo la utilizarías? ¿Echa algo en falta? Esperamos sus comentarios a continuación.