Curl es una gran herramienta para hacer peticiones y enviar datos usando HTTP. Desconozco todas sus funciones pero puedo asegurar que sirve perfectamente para probar las APIs que creamos en cualquier lenguaje de programación con el paradigma REST.
Es por eso que hoy veremos cómo usar CURL para probar nuestras API’s y hacer otras peticiones que nos ayudarán a depurar nuestros programas de la web. A lo largo de este tutorial te mostraré, entre otras cosas, lo siguiente:
- Enviar encabezados
- Especificar verbo HTTP
- Enviar datos o JSON
- Enviar datos como formulario
- Subir un archivo
- Enviar el contenido de un archivo
Nota: curl está disponible para Windows y me parece que viene preinstalado en Linux.
La API que vamos a probar
Como no encontré una manera fácil de reflejar los datos, hice un pequeñísimo script de PHP que nos dice la información y encabezados que le mandamos.
Es decir, nos dirá los datos que recibió, los encabezados y todo lo demás; gracias a esto sabremos si estamos haciendo lo correcto con curl.
<?php
/*
@author parzibyte
*/
echo json_encode(
[
"metodo" => $_SERVER["REQUEST_METHOD"],
"encabezados" => getallheaders(),
"datos" => file_get_contents("php://input"),
"post" => $_POST,
"cadena_consulta" => $_GET
],
JSON_PRETTY_PRINT
);
No lo uses en producción, es solamente una guía. Estoy codificando con JSON e imprimiéndolo formateado para tener una salida más bonita en la terminal.
Además, para usar curl no necesitas PHP, simplemente estoy indicando qué cosa vamos a usar para probar curl.
Petición HTTP para obtener JSON, HTML u otros
En su forma más básica, curl podría descargar el HTML de una página. Por ejemplo, descargar lo que hay en mi página personal. El comando sería:
curl https://www.parzibyte.me
Con la siguiente salida:
Eso mostraría el HTML de mi página y de cualquier otra. De hecho muestra lo que haya; tomando otro ejemplo de la api de JsonPlaceholder que usamos con Node para obtener un JSON usaríamos este comando:
curl https://jsonplaceholder.typicode.com/posts/1
Con la salida:
Así es como podemos hacer simples peticiones con curl.
Especificar salida
No siempre vamos a querer mostrar los datos en la terminal; en ocasiones se necesitará que se guarden en un archivo. Curl ofrece una opción, y los sistemas operativos otra.
Redirigir salida
Comencemos viendo la opción de redirección de salida usando el operador >
, si quisiéramos guardar la salida en un archivo sería así:
curl https://jsonplaceholder.typicode.com/posts/1 > post.json
En ese caso guardamos la salida en el archivo llamado post.json.
Opción -o de curl
Si queremos usar el método que ofrece curl especificamos la opción -o
seguida del nombre del archivo que guardará la salida. El comando quedaría así:
curl -o post.json https://jsonplaceholder.typicode.com/posts/1
En lugar de redirigir la salida indicamos el archivo en donde debería guardarse. Ahora se ve así:
Por cierto, esto no funciona únicamente para JSON, también lo hace para HTML y cualquier otra salida.
Enviar datos con POST
Aquí viene lo divertido; es hora de que usemos mi script para probar el envío de datos con el método POST.
Para enviar datos especificamos la opción --data
(su modo abreviado es -d
)y después ponemos los datos a enviar. En su caso más simple de un envío de formulario queda así:
curl --data "nombre=Luis&alias=parzibyte" localhost/probar_curl.php
Como PHP nos va a reflejar los datos y encabezados enviados, la salida es esta:
Ahí vemos muchas cosas importantes y bonitas. La primera es que el método es POST, no lo especificamos pero al enviar datos curl lo especifica por nosotros.
No hay cadena de consulta en la URL pero sí hay datos en POST. Estos datos son de tipo formulario, y podríamos recuperarlos con, p. ej. $_POST["nombre"]
en PHP.
Aparte de que están en post como datos de formulario, los datos crudos o el cuerpo está en datos
.
Especificar otro verbo HTTP
La opción -X
de curl indica el verbo que queremos usar. Si no enviamos datos entonces supone que el método es GET, y si los enviamos sin especificar, supone que es POST.
Si queremos forzar el método pasamos la opción -X
seguida del nombre del verbo. Veamos un ejemplo en donde hacemos una petición PUT:
curl -X PUT --data "nombre=Luis&alias=parzibyte" localhost/probar_curl.php
La salida es la siguiente, en donde se observa que ahora no se envió como formulario y que la única manera de obtener los datos es accediendo directamente al cuerpo:
Así podemos hacerlo para DELETE, PATCH, HEAD y otros.
Encabezados
En muchas aplicaciones se nos pide enviar encabezados adicionales con nuestras claves u otras cosas. Con curl es fácil enviar encabezados; se hace con la opción -H
.
Un ejemplo es enviar datos con JSON, especificando que el tipo de contenido es json usando Content-Type: application/json así:
curl -H "Content-Type: application/json" --data "{\"nombre\": \"Luis\"}" localhost/probar_curl.php
No le tomes importancia a data
por el momento, fíjate en el encabezado. Si quisieras enviar más encabezados especifica múltiples veces la opción:
curl -H "clave: valor" -H "otra_clave: otro_valor" localhost/probar_curl.php
Gracias al script que refleja los datos podemos ver los encabezados enviados:
Nota: recuerda que puedes sobrescribir el host, el user agent y todos los demás especificando por ti mismo los encabezados.
Enviar un JSON
Como la codificación de JSON da una cadena al final, no cuesta nada enviar un JSON con curl. Eso sí, debe ir sin estar formateado. Para hacerlo hacemos esto:
curl -H "Content-Type: application/json" --data "{\"nombre\": \"Luis\"}" localhost/probar_curl.php
Ponemos el encabezado para que el servidor sepa lo que le enviamos.
Especificamente en Windows hay que escapar las comillas así. Es decir, encerrar los datos entre comillas y luego, las comillas que están dentro escaparlas con la diagonal nvertida.
La salida es esta:
Recuerda que puedes especificar otro verbo HTTP, enviar más encabezados y todo eso.
Si quieres enviar un archivo JSON y evitar escapar los datos sigue leyendo.
Enviar datos de archivo
Si tienes muchos datos (sin importar el tipo) o quieres evitar escapar las comillas del JSON especifica el nombre del archivo en la opción --data
iniciando con un @
.
Por ejemplo, para enviar el JSON descargado anteriormente:
curl -H "Content-Type: application/json" --data @post.json localhost/probar_curl.php
En este caso no ponemos los datos, sino el nombre (después del arroba) del archivo que contiene los datos. De esta manera curl va a abrirlo y enviar su contenido.
La salida es esta:
Así podrías enviar más datos de todo tipo y sin tener que escaparlos. Eso sí, recuerda que va a enviar el contenido del archivo, no el archivo en sí.
Subir archivo con CURL
También se pueden subir archivos binarios usando curl. Para ello usamos la opción -F
especificando el nombre y la ruta usando de nuevo el @
.
Como ejemplo voy a intentar enviar el archivo post.json ahora como archivo, no solamente su contenido. Usando este método se podrían enviar imágenes, vídeos, archivos PDF o lo que sea. Veamos:
curl -F "archivo=@post.json" localhost/probar_curl.php
Si quisieras enviar más archivos haz lo mismo que con los encabezados, especifica múltiples veces la opción -F
.
He modificado el script para que mueva el archivo como vimos en el ejemplo simple de subida de archivo. Lo digo de nuevo: curl funciona sin PHP pero estoy probando con PHP para ejemplificar que las cosas funcionan.
La salida es (ahora mostrando a $_FILES
):
El nuevo código del script es el siguiente, el cual mueve el archivo binario a la misma carpeta en donde está el script:
<?php
/*
@author parzibyte
*/
move_uploaded_file($_FILES["archivo"]["tmp_name"], "post.json");
echo json_encode(
[
"metodo" => $_SERVER["REQUEST_METHOD"],
"encabezados" => getallheaders(),
"datos" => file_get_contents("php://input"),
"files" => $_FILES,
"post" => $_POST,
"cadena_consulta" => $_GET
],
JSON_PRETTY_PRINT
);
Efectivamente el archivo fue subido y procesado:
Otras opciones
Hay otras opciones de curl. Por ejemplo la opción -v
es para que sea “verboso” o sea que te muestre todo lo que se está haciendo para la petición:
curl -v localhost/probar_curl.php
En este caso muestra más detalles:
Otra opción interesante es la -i
que muestra los encabezados de la petición, así como la respuesta. Sería con:
curl -i localhost/probar_curl.php
La salida es:
Conclusión
Por cosas como la belleza de curl es que extraño usar Linux. Lo bueno es que alguien se dio a la tarea de hacer un curl para los que usamos Windows.
Recuerda que puedes combinar todas las opciones, cambiar el verbo HTTP, enviar archivos binarios o enviar su contenido, mostrar detalles con la opción -i
, cambiar encabezados y muchas cosas más.
Con curl puedes probar APIs y todos tus desarrollos que lleven HTTP. Gracias a esto se puede hacer una depuración más fácil.
Como referencia dejo un enlace al manual de curl, no sé si es oficial pero está bonito.