Las APIs REST son el lenguaje común entre aplicaciones modernas. Construir una desde cero en PHP puro —sin frameworks— te enseña exactamente cómo funciona HTTP, JSON y la arquitectura cliente-servidor. Esta guía crea una API funcional paso a paso.
¿Qué es una API REST?
REST (Representational State Transfer) es un estilo arquitectónico para construir servicios web usando HTTP. Los recursos se identifican por URLs y las operaciones se hacen con los métodos HTTP estándar:
| Método HTTP | Operación CRUD | Ejemplo |
|---|---|---|
| GET | Read | GET /api/articulos → lista todos |
| POST | Create | POST /api/articulos → crea uno nuevo |
| PUT/PATCH | Update | PUT /api/articulos/5 → actualiza el #5 |
| DELETE | Delete | DELETE /api/articulos/5 → elimina el #5 |
Estructura del proyecto
api/
├── index.php ← router principal
├── config.php ← conexión a la base de datos
├── helpers.php ← funciones utilitarias
└── .htaccess ← reescritura de URLs
# .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
El router: index.php
handle_articulos($pdo, $metodo, $id, $body),
default => responder(404, ['error' => 'Recurso no encontrado'])
};
El controlador: CRUD de artículos
prepare("SELECT * FROM articulos WHERE id = ?");
$stmt->execute([$id]);
$articulo = $stmt->fetch(PDO::FETCH_ASSOC);
$articulo ? responder(200, $articulo) : responder(404, ['error' => 'No encontrado']);
} else {
// GET /articulos
$stmt = $pdo->query("SELECT id, titulo, slug, categoria_slug, created_at FROM articulos ORDER BY created_at DESC");
responder(200, $stmt->fetchAll(PDO::FETCH_ASSOC));
}
break;
case 'POST':
// Validación básica
if (empty($body['titulo']) || empty($body['contenido'])) {
responder(422, ['error' => 'titulo y contenido son requeridos']);
return;
}
$stmt = $pdo->prepare(
"INSERT INTO articulos (titulo, slug, contenido, categoria_slug) VALUES (?, ?, ?, ?)"
);
$slug = strtolower(str_replace(' ', '-', $body['titulo']));
$stmt->execute([$body['titulo'], $slug, $body['contenido'], $body['categoria_slug'] ?? 'tecnologia']);
responder(201, ['id' => $pdo->lastInsertId(), 'slug' => $slug]);
break;
case 'DELETE':
if (!$id) { responder(400, ['error' => 'ID requerido']); return; }
$stmt = $pdo->prepare("DELETE FROM articulos WHERE id = ?");
$stmt->execute([$id]);
responder(200, ['eliminado' => $stmt->rowCount() > 0]);
break;
default:
responder(405, ['error' => 'Método no permitido']);
}
}
function responder(int $codigo, array $datos): void {
http_response_code($codigo);
echo json_encode($datos, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit();
}
Probar la API con curl
# Listar artículos
curl http://localhost/api/articulos
# Obtener uno específico
curl http://localhost/api/articulos/1
# Crear un artículo
curl -X POST http://localhost/api/articulos \
-H "Content-Type: application/json" \
-d '{"titulo":"Mi primer artículo","contenido":"Contenido aquí","categoria_slug":"redes"}'
# Eliminar
curl -X DELETE http://localhost/api/articulos/5
"Una buena API es un contrato entre sistemas. Rota ese contrato sin avisar y rompes a todos los que dependen de ti."