Este artículo veremos como crear un RESTful web service utilizando un micro-framework llamado lumen, la razón para usar un framework es para reducir el tiempo de desarrollo y hacerlo más robusto.
¿Que es Lumen?
Lumen es un micro-framework, es decir una versión reducida de framework completo llamado Laravel.
La razón de utilizar Lumen en lugar de Laravel es porque los micro-framework ofrecen menos características, pero están optimizados para un rendimiento superior al eliminar características que no son esenciales.
Pero para nuestro caso tendremos todo lo que necesitamos sin sacrificar velocidad, esto lo hace perfecto para desarrollar RESTful web services.
Como instalar Lumen
Para instalar Lumen necesitas tener configurado un servidor con php en tu computadora, también vas a necesitar tener instalado composer y PHP7. Ahora abre una ventana de comandos y navega hasta tu directorio web y escribes este comando de composer:
composer create-project --prefer-dist laravel/lumen rest-api
En donde rest-api
es el nombre del directorio que va a crear el comando y en donde se va a instalar el proyecto basado en Lumen
Configurar Lumen
Ahora necesitamos configurar la base de datos en Lumen, para ello abrimos un archivo llamado .env que se encuentra en el directorio que creamos.
Ahí colocamos la dirección ip del servidor mysql, el nombre de la base de datos y el usuario y clave.
Para seguir este artículo debes crear una tabla llamada posts con esta estructura:
Crear los controladores para nuestro servicio RESTful
Vamos a crear los controladores usando un comando, pero para poder usar este comando primero tenemos que instalar un componente más, mediante composer:
NOTA: recuerda que para ejecutar cualquier comando de aquí en adelante, tienes que estar en la carpeta de trabajo, en este caso es rest-api/
composer require --dev flipbox/lumen-generator
Ahora, necesitamos registrar este componente, agregando este código en el archivo bootstrap/app.php
if ($app->environment() !== 'production') {
$app->register(Flipbox\LumenGenerator\LumenGeneratorServiceProvider::class);
}
$app->withEloquent(); //Para manejar bases de datos
La línea de código: $app->withEloquent(); sirve para activar el módulo con el que vamos a trabajar el acceso a la base de datos.
Ahora guardamos el archivo y ejecutamos este comando para generar el controlador.
php artisan make:controller PostController --resource
El comando anterior va a crear un archivo llamado PostController en la ruta app>Http>Controllers, debemos a agregar un constructor y modificar la función index, de forma que quede como en esta imagen:
En la primera modificación estamos haciendo que este controlador reciba un objeto llamado $post, este será un objeto ORM, que represente la tabla de la base de datos con la que vamos a trabajar, esto lo vamos a definir más adelante.
La segunda modificación es para que la función index regrese todos los post en nuestra base de datos, y lo haga por medio paginaciones de 2 registros por página.
Una ventaja de usar Lumen, es que va a convertir esta salida a Json, que es justo lo que necesitamos para nuestro servicio Restful
Agregar rutas en Lumen
Ahora que hemos creado el controlador, necesitamos definir rutas para apuntar a cada función (método) dentro del controlador, esto equivale a definir las direcciones URL y para hacerlo debemos agregar estas líneas de código al final del archivo routes>web.php
function resource($uri, $controller, $router)
{
//$verbs = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'];
$router->get($uri, $controller.'@index');
$router->post($uri, $controller.'@store');
$router->get($uri.'/{id}', $controller.'@show');
$router->put($uri.'/{id}', $controller.'@update');
$router->patch($uri.'/{id}', $controller.'@update');
$router->delete($uri.'/{id}', $controller.'@destroy');
}
resource('api/posts', 'PostController', $router);
Con esto hemos creado las rutas para cada operación básica del servicio RESTful.
Creando el modelo usando Eloquent
Eloquent es un ORM (Object Relational Mapping) que básicamente permite trabajar bases de datos, sus tablas y relaciones como si fueran objetos, como verán más adelante, esto simplifica mucho el trabajar con bases de datos.
En este artículo voy a tratar Eloquent de forma superficial debido a lo extenso que es, pero si quieres más información puedes leer la documentación oficial de Eloquent
Ahora vamos a correr un comando en la consola:
php artisan make:model Post
php artisan make:model Post
En el comando anterior Post es el nombre de nuestra tabla y va a crear un archivo llamado Post.php en la carpeta app, como se muestra a continuación:
Es importante saber que de forma predeterminada, esta clase va a apuntar o buscar a una tabla con el nombre de la clase más una letra S, en este caso buscará una tabla llamada posts. Si queremos evitar este comportamiento podemos agregar una línea de código dentro de la clase para definir otro nombre de tabla:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
//
protected $table = 'posts';
}
Probar el servicio Restful
Ahora ya tenemos suficiente código para probar nuestro servicio, entonces vamos a levantar un servidor desde la consola usando este comando:
php -S localhost:8000 -t public
Ahora abrimos un navegador y colocamos la ruta
localhost:8000/api/posts
Y si hemos hecho todo bien, veremos algo como esto:
NOTA: si ves alguna salida y no se ve tan ordenado como es mi imagen, es porque yo uso una extensión de Chrome llamada JSONView.
Eliminar, consultar y modificar.
Ahora vamos a agregar las demás operaciones, todo esto lo haremos en el controlador, así que editamos el archivo app>Http>Controllers>PostController.php de forma que contenga este código:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function __construct(\App\Post $post)
{
$this->post = $post;
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(\App\Post $post)
{
//
return $post->paginate(2);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$input = $request->all();
$this->post->create($input);
return [
'data' => $input
];
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
return $this->post->find($id);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$input = $request->all();
$this->post->where('id', $id)->update($input);
return $this->post->find($id);
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$post = $this->post->destroy($id);
return ['message' => 'deleted successfully', 'post_id' => $post];
}
}
Ahora podemos probar todos métodos de nuestro servicio RESTful. Si tienes dudas de como probar un servicio, puedes leer un artículo que lo explica, haciendo clic aquí.
Que más falta en nuestro servicio RESTful
A Pesar de que el servicio RESTful funciona bien cuando lo pruebas, debes saber que hace falta algunas cosas antes de usarlo en un programa “real”, primero, esto no tiene validaciones, debes validar todas las entradas antes de procesarlas (esto es lo más importante) y segundo, debes regresar los códigos de respuesta HTML que corresponden.
Ya sabes que en caso de éxito, debes regresar el código 200, esto ya lo hace Lumen, pero debes de encargarte de los casos en que la petición falle.
Veamos cómo puede quedar esto, en el caso de que desees consultar un artículo con un ID que no existe, modifica la función show en el archivo del controlador (app\Http\Controllers\PostController.php)
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$post = $this->post->find($id);
if ( !$post)
{
abort(404); //No encontrado
}
return $post;
}
Espero que hayas disfrutado este artículo y si tienes alguna duda, puedes dejarme un comentario.