APIs con PHP

APIs REST con PHP

Aprende a diseñar, implementar y consumir APIs REST con PHP siguiendo los principios y buenas prácticas de la arquitectura más utilizada en servicios web modernos.

Objetivos de Aprendizaje
  • Comprender los principios de las APIs REST
  • Entender los métodos HTTP y su relación con CRUD
  • Conocer el formato JSON para intercambio de datos
  • Aprender sobre los códigos de estado HTTP
  • Implementar buenas prácticas en diseño de APIs REST

¿Qué es REST?

REST (Representational State Transfer) es un estilo de arquitectura para diseñar servicios web. Fue presentado por Roy Fielding en su tesis doctoral en 2000 y se ha convertido en el estándar de facto para el diseño de APIs web modernas.

REST es un conjunto de principios arquitectónicos, no un protocolo o estándar. Las API que siguen estos principios se denominan "RESTful".

Diagrama REST

Imagen: Comunicación cliente-servidor a través de una API REST utilizando recursos, verbos HTTP y representaciones.

Principios fundamentales de REST

Interfaz uniforme

Los recursos se identifican mediante URIs y se manipulan mediante representaciones. Simplifica la arquitectura general y mejora la visibilidad de las interacciones.

Sin estado

Cada petición contiene toda la información necesaria y no depende de peticiones anteriores. El servidor no almacena contexto entre peticiones.

Sistema en capas

La arquitectura está compuesta por múltiples capas jerárquicas que pueden evolucionar de forma independiente, permitiendo escalabilidad y flexibilidad.

Recursos y URLs

En una API REST, todo es un recurso. Un recurso puede ser un objeto, un servicio, o cualquier entidad que pueda ser identificada, nombrada y manipulada a través de la web. Cada recurso es accesible a través de una URL única.

Recurso URL Descripción Ejemplo
Colección /recursos Representa todos los recursos de un tipo /usuarios
Elemento /recursos/{id} Representa un recurso específico por su ID /usuarios/123
Subrecurso /recursos/{id}/subrecursos Todos los subrecursos de un recurso específico /usuarios/123/pedidos
Filtrado /recursos?param=valor Recursos filtrados por parámetros de consulta /usuarios?activo=true

Métodos HTTP y operaciones CRUD

Los métodos HTTP definen las acciones que se pueden realizar sobre los recursos. Estos se corresponden con las operaciones CRUD (Create, Read, Update, Delete) de las bases de datos.

POST
Create

Crea un nuevo recurso en el servidor.

POST /usuarios
Crea un nuevo usuario
201 Created 400 Bad Request
GET
Read

Recupera un recurso o una colección.

GET /usuarios/123
Obtiene el usuario 123
200 OK 404 Not Found
PUT / PATCH
Update

Actualiza un recurso existente.

PUT /usuarios/123
Actualiza el usuario 123
200 OK 400 Bad Request
DELETE
Delete

Elimina un recurso existente.

DELETE /usuarios/123
Elimina el usuario 123
204 No Content 404 Not Found

Ejemplo de petición y respuesta REST

Petición
GET /api/productos/1 Cliente → Servidor

Headers:

Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJ9...

URL Parameters:

id: 1
Respuesta
200 OK Servidor → Cliente

Headers:

Content-Type: application/json
Cache-Control: max-age=3600

Body:

response.json

{
  "id": 1,
  "nombre": "Smartphone XYZ",
  "precio": 599.99,
  "categoria": "Electrónica",
  "disponible": true,
  "creado": "2025-01-15T10:30:00Z"
}
                                                    

Formato JSON

JSON (JavaScript Object Notation) es el formato estándar para intercambiar datos en APIs REST. Es ligero, fácil de leer para humanos y fácil de procesar para las máquinas.

Ligero Independiente del lenguaje Auto-descriptivo
Objeto único (Usuario) GET /usuarios/1
user.json

{
  "id": 1,
  "nombre": "Juan Pérez",
  "correo": "juan@example.com",
  "activo": true,
  "rol": "admin",
  "creado": "2025-01-15T10:30:00Z"
}
                                            
Colección (Usuarios) GET /usuarios
users_collection.json

{
  "usuarios": [
    {
      "id": 1,
      "nombre": "Juan Pérez",
      "correo": "juan@example.com"
    },
    {
      "id": 2,
      "nombre": "María López",
      "correo": "maria@example.com"
    }
  ],
  "total": 2,
  "pagina": 1,
  "porPagina": 10
}
                                            

Códigos de estado HTTP

¿Por qué son importantes?

Los códigos de estado HTTP comunican el resultado de una petición. Usar los códigos correctos mejora la usabilidad de tu API, permite un mejor manejo de errores y facilita la depuración.

2xx Éxito
  • 200 OK GET
  • 201 Created POST
  • 204 No Content DELETE
3xx Redirección
  • 301 Moved
  • 304 Not Modified
  • 307 Temp Redirect
4xx Error Cliente
  • 400 Bad Request
  • 401 Unauthorized
  • 404 Not Found
5xx Error Servidor
  • 500 Server Error
  • 502 Bad Gateway
  • 503 Unavailable

Buenas prácticas para diseñar APIs REST


Mejores Prácticas

Seguir estas recomendaciones te ayudará a crear APIs más intuitivas, mantenibles y fáciles de usar.

Usa sustantivos, no verbos

/usuarios en lugar de /getUsuarios

Versiona tu API

/api/v1/usuarios

Usa correctamente los códigos HTTP

Comunica claramente el resultado

Implementa paginación

Para colecciones grandes

Permite filtrado y ordenación

Mediante parámetros de consulta

Documenta tu API

Usa herramientas como Swagger/OpenAPI

Valida los datos

Tanto en cliente como en servidor

Asegura tu API

Usa HTTPS y autenticación apropiada

Flujo de comunicación REST

Cliente

Aplicación o navegador

API REST

GET POST PUT DELETE

Recursos

Base de datos, archivos, etc.

Casos de Uso de REST en PHP

Consumir APIs
  • Usar file_get_contents() para peticiones sencillas
  • Implementar la librería cURL para peticiones avanzadas
  • Utilizar Guzzle HTTP como cliente moderno
  • Gestionar autenticación y tokens
Crear APIs
  • Crear endpoints con PHP puro
  • Implementar usando frameworks como Laravel o Symfony
  • Gestionar autorización y permisos
  • Documentar con Swagger/OpenAPI
Seguridad
  • Autenticación con JWT (JSON Web Tokens)
  • Validación de datos de entrada
  • Protección contra ataques CSRF y XSS
  • Implementación de HTTPS
En resumen

Las APIs REST siguen principios de diseño que las hacen escalables, mantenibles y fáciles de usar. Utilizan URLs para identificar recursos, métodos HTTP para manipularlos, y códigos de estado para comunicar resultados. En las próximas lecciones, veremos cómo implementar y consumir APIs REST con PHP.

Ejemplo de PHP con REST API

simple_request.php

<?php
// Consumir una API REST con file_get_contents
$url = 'https://fakestoreapi.com/products/1';

// Configurar el contexto para la solicitud
$options = [
    'http' => [
        'method' => 'GET',
        'header' => 'Accept: application/json'
    ]
];
$context = stream_context_create($options);

// Realizar la petición
$response = file_get_contents($url, false, $context);

// Verificar si hubo errores
if ($response === false) {
    echo "Error al obtener datos de la API";
    exit;
}

// Decodificar la respuesta JSON
$data = json_decode($response, true);

// Mostrar los datos
echo "<h3>{$data['title']}</h3>";
echo "<p>Precio: \${$data['price']}</p>";
echo "<p>Categoría: {$data['category']}</p>";
echo "<p>{$data['description']}</p>";
?>
                                                
curl_request.php

<?php
// Consumir una API REST con cURL
$url = 'https://fakestoreapi.com/products?limit=5';

// Inicializar cURL
$ch = curl_init();

// Configurar opciones de cURL
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Accept: application/json',
    'Content-Type: application/json'
]);

// Ejecutar la petición
$response = curl_exec($ch);

// Verificar si hubo errores
if(curl_errno($ch)) {
    echo 'Error cURL: ' . curl_error($ch);
    exit;
}

// Obtener código de estado HTTP
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo "Código de estado: $httpCode<br>";

// Cerrar sesión cURL
curl_close($ch);

// Decodificar la respuesta JSON
$productos = json_decode($response, true);

// Mostrar resultados
echo "<ul>";
foreach ($productos as $producto) {
    echo "<li>{$producto['title']} - \${$producto['price']}</li>";
}
echo "</ul>";
?>
                                                
post_request.php

<?php
// Enviar datos JSON a una API con POST
$url = 'https://fakestoreapi.com/products';

// Datos a enviar en formato JSON
$data = [
    'title' => 'Nuevo Producto',
    'price' => 99.99,
    'description' => 'Una descripción del nuevo producto',
    'image' => 'https://example.com/image.jpg',
    'category' => 'electronics'
];

// Convertir array a JSON
$jsonData = json_encode($data);

// Inicializar cURL
$ch = curl_init();

// Configurar opciones de cURL para POST
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($jsonData)
]);

// Ejecutar la petición
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// Cerrar sesión cURL
curl_close($ch);

// Verificar respuesta
if ($httpCode == 201) { // 201 Created
    $productoCreado = json_decode($response, true);
    echo "Producto creado correctamente con ID: {$productoCreado['id']}<br>";
    echo "<pre>";
    print_r($productoCreado);
    echo "</pre>";
} else {
    echo "Error al crear el producto. Código: $httpCode<br>";
    echo "Respuesta: $response";
}
?>