LARAVEL Framework - Tutorial 01 - Creación de API RESTful
LARAVEL Framework - Tutorial 01 - Creación de API RESTful
LARAVEL Framework - Tutorial 01 - Creación de API RESTful
Laravel es uno de los frameworks más populares de código abierto para PHP que nos permitirá desarrollar
aplicaciones y servicios web con PHP 5.
Fue creado en el año 2011 y su filosofía es la de desarrollar código PHP de forma elegante y simple para crear
código de forma sencilla y permitiendo múltiples funcionalidades.
Vamos a realizar la instalación para un entorno Windows, y en este caso instalaremos un sistema WAMP que
incluye Apache, MySQL y PHP.
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 2
Para nuestra instalación de Laravel vamos a crear un dominio.local. La idea es que cuando tecleemos el nombre de
ese dominio.local nos conecte con la ruta dónde está instalada la aplicación que realizaremos con Laravel.
• Si queremos añadir más dominios a la misma dirección IP los pondremos en la misma línea separadas por un
espacio.
Una vez configuradas las IP's de los dominios virtuales tendremos que editar el fichero de configuración de XAMPP:
Si queremos configurar nuestro servidor virtual en XAMPP para que siga la misma estructura de clases al estilo
www.dominio.local, lo primero que tendremos que hacer es configurar la resolución del nombre www.dominio.local
para que cuando el navegador quiera conectarse a ese dominio lo haga a nuestro servidor web local en 127.0.0.1
Para ello en Windows 8.1 tendremos que editar el fichero hosts.
1. Accederemos a la carpeta: C:\Windows\System32\drivers\etc
2. Copiaremos el fichero hosts al escritorio y lo editaremos.
3. Añadiremos la siguiente entrada al final del fichero: 127.0.0.1 www.dominio.local
4. Grabamos el fichero y lo pegaremos de nuevo en la carpeta: C:\Windows\System32\drivers\etc
sobreescribiendo el actual.
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 3
A partir de este momento cuando queramos acceder al www.dominio.local nuestro equipo se conectará a nuestro
servidor localhost.
NameVirtualHost *:80
<VirtualHost *:80>
DocumentRoot "C:\xampp\htdocs"
ServerName localhost
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "C:\xampp\htdocs\dominios\dominio.local"
ServerName www.dominio.local
ServerAlias dominio.local
<Directory "C:\xampp\htdocs\dominios\dominio.local">
AllowOverride All
Order Allow,deny
Allow from all
Require all granted
</Directory>
</VirtualHost>
Instalación de Composer
Composer es una herramienta para gestionar dependencias en aplicaciones PHP, algo así como un instalador
de paquetes/librerías referentes a desarrollo web.
Con Composer podemos crear un archivo de configuración (en formato JSON) en el cuál indicamos las
dependencias (de otras librerías) que tiene nuestro proyecto y Composer es capaz de descargar e instalar
automáticamente dichas librerías en la versión que le indiquemos en el archivo de configuración.
Composer se basa en otro proyecto denominado https:/ / packagist. org/ el cuál es el principal repositorio utilizado
por Composer para descargar los paquetes.
El uso de Composer es muy recomendable por que a la hora de crear un proyecto en Laravel, le podemos indicar que
se descargue Laravel automáticamente, sin tener que ir nosotros a la página y descargarlo manualmente, así como
cualquier otro tipo de librería adicional que necesitemos en cualquier momento.
Para instalar Composer tendremos que hacer lo siguiente:
• Ir a su página oficial: https://getcomposer.org/
• Pulsar en Download: https://getcomposer.org/download/
• Elegir el método adecuado a nuestra versión de sistema operativo.
Una vez instalado Composer para poder ejecutarlo tendremos que ir a la línea de comandos del sistema con
Windows+R teclear cmd y escribir Composer seguido de la instrucción correspondiente.
Ejemplo de fichero de configuración .json para Composer:
{
"require": {
"monolog/monolog": "1.0.*"
}
}
Para usar GitHub: Para poder usar GitHub correctamente tendremos que registrarnos en su web https:/ / github.
com/join
De esta manera podremos crear gratuitamente nuestros repositorios públicos. Si queremos que nuestros
repositorios sean privados tendríamos que pagar una cuota por dicho servicio.
Para instalar Git (opcional):
Para disponer de comandos Git en cualquier ventana de comandos del sistema operativo, tendremos que instalar
Git. Para este proyecto no lo necesitaremos ya que ejecutaremos los comandos de Git desde el GitShell de GitHub.
• Página oficial de Git: http://git-scm.com/
• Página de descarga de Git: http://git-scm.com/downloads
Postman es otra extensión para Google Chrome que nos permite ejecutar peticiones a una API REST, muy similar a
la extensión Advanced Rest Client con la que trabajamos anteriormente..
• Para instalar Postman en Chrome, visitar Postman - REST Client [2]
• Para instalar Advanced REST Client visitar Advanced REST Client [3].
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 7
applications'''
Para solucionar ese error iremos a GitHub.com y en Edit Profile veremos en el menú izquierdo Applications
dónde podremos generar el Token personalizado.
Pasos a seguir:
• Loguearse en https://github.com/'''
• Acceder a https://github.com/settings/applications''' o ir a Settings'Texto en negrita.
• Entrar en el menú izquierdo en Personal access tokens
• Generate New Token (opciones por defecto)
• Copiar el Token generado. Por ejemplo: f547bdf6c1c4f4f5154b2fdb4479a80234983279a
• Ir a la línea de comandos y ejecutar el siguiente comando:
# Ejemplo de uso:
composer config -g github-oauth.github.com
f547bdf6c1c4f4f5154b2fdb4479a80234983279a
composer clearcache
Estructura de LARAVEL 5
Laravel sigue la metodología MVC. Veamos una pequeña introducción a las rutas principales de este framework.
Cuando abrimos la estructura de Laravel veremos algo similar a la imagen siguiente:
Creación de modelos
• A la hora de crear el modelo tendremos que crear un modelo para cada tabla y lo haremos dentro de la carpeta
app.
• La forma rápida de crear una plantilla para cada modelo es utilizando PHP Artisan (utilidad incluída en el
framework Laravel). Artisan es el nombre de una interfaz en línea de comandos incluída con Laravel.
• Artisan proporciona un número de comandos muy útiles a la hora de desarrollar aplicaciones. Por ejemplo nos
permitirá generar plantillas para los modelos, generar las tablas MySQL en el servidor, hacer rollbacks, rellenar
datos en las tablas de forma automática, etc.
• DOCUMENTACIÓN SOBRE ARTISAN [8]
Pasos a seguir para crear cada modelo:
• Abrimos una ventana de comandos en la carpeta principal de Laravel.
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Model;
// Generalmente cada vez que creamos una clase tenemos que indicar el
espacio de nombres
// dónde la estamos creando y suele coincidir con el nombre del
directorio.
// El nombre del namespace debe comenzar por UNA LETRA MAYÚSCULA.
// Eloquent asume que cada tabla tiene una clave primaria con una
columna llamada id.
// Si éste no fuera el caso entonces hay que indicar cuál es
nuestra clave primaria en la tabla:
protected $primaryKey = 'serie';
use Illuminate\Database\Eloquent\Model;
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 13
// Generalmente cada vez que creamos una clase tenemos que indicar el
espacio de nombres
// dónde la estamos creando y suele coincidir con el nombre del
directorio.
// El nombre del namespace debe comenzar por UNA LETRA MAYÚSCULA.
Migrations
• Las Migrations (desplazamientos o migraciones) son un tipo de control de versiones pero para bases de datos.
• Nos permiten modificar el esquema de la base de datos y estar actualizados correctamente del estado del mismo.
Es decir con las migrations podremos crear el esquema de tablas, cubrir datos en la tablas, hacer rollback para
volver a estados iniciales, etc...
• Las migrations en Laravel se encuentran en la carpeta database/migrations.
• Para cada tabla de la base de datos tendremos 1 archivo de migrations.
• A la hora de ejecutar las migrations Laravel ejecuta los archivos de migration que están en la carpeta
database/migrations.
Pasos a seguir para crear las plantillas de Migrations para cada tabla
• Primero tenemos que crear una base de datos, usuario y contraseña con PHPMyAdmin, ya que PHP Artisan
no puede hacer esa tarea por nosotros.
• Configuraremos los parámetros de conexión a nuestra base de datos en el fichero .env que se encuentra en la
ruta raíz de Laravel.
DB_HOST=localhost
DB_DATABASE=c2base2
DB_USERNAME=c2base2
DB_PASSWORD=xxxxxxxxx
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
• Una vez configurada la conexión a la base de datos procederemos a crear una plantilla de Migration para cada
tabla.
• ATENCIÓN: si hemos creado las plantillas de Modelo sin usar PHP Artisan, entonces borrarremos todas las
migrations que aparecen por defecto en la carpeta database/migrations. En otro caso borraremos solamente las
migrations que no tengan que ver con nuestras tablas.
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 15
• Si necesitamos crear las plantillas de Migrations para nuestras tablas por que hemos borrado todos los ficheros
podemos ejecutar el siguiente comando para cada una de las tablas:
=> FABRICANTES
* #Id (auto incremental)
* Nombre string
* Direccion string
* Telefono integer
=> AVIONES
* #Serie (auto incremental)
* Modelo string
* Longitud float
* Capacidad integer
* Velocidad integer
* Alcance integer
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('fabricantes', function(Blueprint $table)
{
$table->increments('id');
$table->string('nombre');
$table->string('direccion');
$table->integer('telefono');
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 16
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('fabricantes');
}
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('aviones', function(Blueprint $table)
{
$table->increments('serie');
$table->string('modelo');
$table->float('longitud');
$table->integer('capacidad');
$table->integer('velocidad');
$table->integer('alcance');
array('modelo','longitud','capacidad','velocidad','alcance','fabricante_id');
$table->integer('fabricante_id')->unsigned();
$table->foreign('fabricante_id')->references('id')->on('fabricantes');
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('aviones');
}
• ATENCIÓN:: En XAMPP para que funcione correctamente PDO MySQL que es el sistema de acceso a base de
datos que viene por defecto en XAMPP, hay que habilitar dicha extensión editando el fichero
C:\xampp\php\php.ini y sacando el ; inicial en la línea extension=php_pdo_mysql.dll. Si no lo hacemos al
intentar ejecutar las migraciones obtendremos un error del estilo: [PDOException] could not find driver en
Laravel. Acordarse de Reiniciar Apache en XAMPP una vez hecho el cambio.
• PHP Artisan lleva el control de las Migrations a través de una tabla llamada migrations que tendríamos que tener
en el MySQL. Para instalar esa tabla de forma automática antes de poder ejecutar las Migrations tenemos que
ejecutar el siguiente comando (1 vez solamente por proyecto):
• Ejecutar el siguiente comando desde la shell en Laravel:
• Ejecutamos a continuación todas las migrations para que cree las tablas en el MySQL:
#Migrated: 2015_04_09_105558_fabricantes_migration
#Migrated: 2015_04_09_105827_aviones_migration
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 18
Población automática de las tablas de la base de datos con Laravel y PHP Artisan
• Con PHP Artisan podremos llenar de forma masiva las tablas con datos de ejemplo, utilizando lo que se
conoce como Seeders.
• Los Seeders son una serie de instruciones en las cuales indicamos cómo queremos que se llenen las tablas con
datos.
• Los Seeders se encuentran en la carpeta database/seeds
Pasos a seguir para configurar los seeders:
• Abrir el fichero database/seeds/DatabaseSeeder.php
• En ese fichero haremos las llamadas a los seeders que queremos que ejecute:
Código de ejemplo del fichero database/seeds/DatabaseSeeder.php:
<?php
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Model::unguard();
$this->call('FabricanteSeeder');
$this->call('AvionSeeder');
// $this->call('UserTableSeeder');
}
• Creamos un fichero de Seeder para cada tabla FabricanteSeeder.php y AvionSeeder.php copiando el código de
ejemplo anterior cambiando el nombre de la clase.
• Para poder configurar con qué información rellenamos las tablas necesitamos un proyecto adicional que no viene
con Laravel que se llama Faker, el cuál nos permitirá generar letras, números y textos aleatorios.
• Podemos buscar ese proyecto con Composer:
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 19
• Pasamos a configurar cada fichero de Seeder empleando las instrucciones de Faker. Documentación de Faker en:
https://github.com/fzaninotto/Faker
• Contenido del fichero database/seeds/FabricanteSeeder.php:
<?php
use Illuminate\Database\Seeder;
/**
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 20
<?php
use Illuminate\Database\Seeder;
/**
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 21
'fabricante_id'=>$faker->numberBetween(1,$cuantos)
]
);
}
• Ahora nos queda ejecutar el comando que insertará registros en las tablas:
• Si nos da algún tipo de error de Clase no Encontrada (suele ocurrir al hacer los seeds, ejecutaremos este comando:
composer dumpautoload
• Si queremos volver a poner la base de datos en su estado inicial y ejecutar el primer seed podemos hacerlo con:
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 22
Generación de las plantillas de Controladores para Fabricante y FabricanteAvion y Avion con PHP Artisan y
modificaciones básicas
php artisan make:controller FabricanteController
# Controller created successfully.
En cada Controlador programaremos las tareas a realizar para cada una de las peticiones de la API RESTful.
• Contenido del fichero app/Http/Controllers/FabricanteController.php:
use App\Http\Requests;
use App\Http\Controllers\Controller;
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 23
use Illuminate\Http\Request;
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
// Devolverá todos los fabricantes.
return "Mostrando todos los fabricantes de la base de
datos.";
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
//
return "Se muestra formulario para crear un fabricante.";
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 24
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
//
return "Se muestra formulario para editar Fabricante con
id: $id";
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
//
}
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 25
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index($idFabricante)
{
// Devolverá todos los aviones.
return "Mostrando los aviones del fabricante con Id
$idFabricante";
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create($idFabricante)
{
//
return "Se muestra formulario para crear un avión del
fabricante $idFabricante.";
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($idFabricante,$idAvion)
{
//
return "Se muestra avión $idAvion del fabricante
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 26
$idFabricante";
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($idFabricante,$idAvion)
{
//
return "Se muestra formulario para editar el avión $idAvion
del fabricante $idFabricante";
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($idFabricante,$idAvion)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($idFabricante,$idAvion)
{
//
}
}
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 27
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 28
* @return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
//
}
Route::get('/', function()
{
return 'Hola Mundo.';
});
• Para verificar las rutas disponibles en el proyecto podemos hacerlo empleando PHP Artisan:
# Ayuda sobre php artisan
+--------+--------------------------------+-------------------------------------------------------+------+------------------------------------------------------------+------------+
| Name | Action
| Middleware |
+--------+--------------------------------+-------------------------------------------------------+------+------------------------------------------------------------+------------+
| | GET|HEAD | /
| |
App\Http\Controllers\WelcomeController@index | guest
| | GET|HEAD | home
| |
App\Http\Controllers\HomeController@index | auth
| | GET|HEAD |
auth/register/{one?}/{two?}/{three?}/{four?}/{five?} | |
App\Http\Controllers\Auth\AuthController@getRegister | guest
| | POST |
auth/register/{one?}/{two?}/{three?}/{four?}/{five?} | |
App\Http\Controllers\Auth\AuthController@postRegister | guest
| | GET|HEAD |
auth/login/{one?}/{two?}/{three?}/{four?}/{five?} | |
App\Http\Controllers\Auth\AuthController@getLogin | guest
| | POST |
auth/login/{one?}/{two?}/{three?}/{four?}/{five?} | |
App\Http\Controllers\Auth\AuthController@postLogin | guest
| | GET|HEAD |
auth/logout/{one?}/{two?}/{three?}/{four?}/{five?} | |
App\Http\Controllers\Auth\AuthController@getLogout |
| | GET|HEAD|POST|PUT|PATCH|DELETE | auth/{_missing}
| |
App\Http\Controllers\Auth\AuthController@missingMethod | guest
| | GET|HEAD |
password/email/{one?}/{two?}/{three?}/{four?}/{five?} | |
App\Http\Controllers\Auth\PasswordController@getEmail | guest
| | POST |
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 30
password/email/{one?}/{two?}/{three?}/{four?}/{five?} | |
App\Http\Controllers\Auth\PasswordController@postEmail | guest
| | GET|HEAD |
password/reset/{one?}/{two?}/{three?}/{four?}/{five?} | |
App\Http\Controllers\Auth\PasswordController@getReset | guest
| | POST |
password/reset/{one?}/{two?}/{three?}/{four?}/{five?} | |
App\Http\Controllers\Auth\PasswordController@postReset | guest
| | GET|HEAD|POST|PUT|PATCH|DELETE | password/{_missing}
| |
App\Http\Controllers\Auth\PasswordController@missingMethod | guest
+--------+--------------------------------+-------------------------------------------------------+------+------------------------------------------------------------+------------+
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
| Here is where you can register all of the routes for an application.
*/
Route::resource('fabricantes','FabricanteController');
si no le indicamos el fabricante,
Route::resource('fabricantes.aviones','FabricanteAvionController');
/*
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 31
+--------+----------+--------------------------------------------------+-----------------------------+--------------------------------------------------------+------------+
| Name | Action
| Middleware |
+--------+----------+--------------------------------------------------+-----------------------------+--------------------------------------------------------+------------+
| | GET|HEAD | fabricantes
| fabricantes.index |
App\Http\Controllers\FabricanteController@index | |
| | GET|HEAD | fabricantes/create
| fabricantes.create |
App\Http\Controllers\FabricanteController@create | |
| | POST | fabricantes
| fabricantes.store |
App\Http\Controllers\FabricanteController@store | |
| | GET|HEAD | fabricantes/{fabricantes}
| fabricantes.show |
App\Http\Controllers\FabricanteController@show | |
| | GET|HEAD | fabricantes/{fabricantes}/edit
| fabricantes.edit |
App\Http\Controllers\FabricanteController@edit | |
| | PUT | fabricantes/{fabricantes}
| fabricantes.update |
App\Http\Controllers\FabricanteController@update | |
| | PATCH | fabricantes/{fabricantes}
| |
App\Http\Controllers\FabricanteController@update | |
| | DELETE | fabricantes/{fabricantes}
| fabricantes.destroy |
App\Http\Controllers\FabricanteController@destroy | |
| | GET|HEAD | fabricantes/{fabricantes}/aviones
| fabricantes.aviones.index |
App\Http\Controllers\FabricanteAvionController@index | |
| | GET|HEAD | fabricantes/{fabricantes}/aviones/create
| fabricantes.aviones.create |
App\Http\Controllers\FabricanteAvionController@create | |
| | POST | fabricantes/{fabricantes}/aviones
| fabricantes.aviones.store |
App\Http\Controllers\FabricanteAvionController@store | |
| | GET|HEAD | fabricantes/{fabricantes}/aviones/{aviones}
| fabricantes.aviones.show |
App\Http\Controllers\FabricanteAvionController@show | |
| | GET|HEAD | fabricantes/{fabricantes}/aviones/{aviones}/edit
| fabricantes.aviones.edit |
App\Http\Controllers\FabricanteAvionController@edit | |
| | PUT | fabricantes/{fabricantes}/aviones/{aviones}
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 32
| fabricantes.aviones.update |
App\Http\Controllers\FabricanteAvionController@update | |
| | PATCH | fabricantes/{fabricantes}/aviones/{aviones}
| |
App\Http\Controllers\FabricanteAvionController@update | |
| | DELETE | fabricantes/{fabricantes}/aviones/{aviones}
| fabricantes.aviones.destroy |
App\Http\Controllers\FabricanteAvionController@destroy | |
+--------+----------+--------------------------------------------------+-----------------------------+--------------------------------------------------------+------------+
*/
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
| Here is where you can register all of the routes for an application.
*/
Route::resource('fabricantes','FabricanteController');
si no le indicamos el fabricante,
Route::resource('fabricantes.aviones','FabricanteAvionController');
show.
Route::resource('aviones','AvionController',[ 'only'=>['index','show']
]);
/*
+--------+----------+--------------------------------------------------+-----------------------------+--------------------------------------------------------+------------+
| Name | Action
| Middleware |
+--------+----------+--------------------------------------------------+-----------------------------+--------------------------------------------------------+------------+
| | GET|HEAD | fabricantes
| fabricantes.index |
App\Http\Controllers\FabricanteController@index | |
| | GET|HEAD | fabricantes/create
| fabricantes.create |
App\Http\Controllers\FabricanteController@create | |
| | POST | fabricantes
| fabricantes.store |
App\Http\Controllers\FabricanteController@store | |
| | GET|HEAD | fabricantes/{fabricantes}
| fabricantes.show |
App\Http\Controllers\FabricanteController@show | |
| | GET|HEAD | fabricantes/{fabricantes}/edit
| fabricantes.edit |
App\Http\Controllers\FabricanteController@edit | |
| | PUT | fabricantes/{fabricantes}
| fabricantes.update |
App\Http\Controllers\FabricanteController@update | |
| | PATCH | fabricantes/{fabricantes}
| |
App\Http\Controllers\FabricanteController@update | |
| | DELETE | fabricantes/{fabricantes}
| fabricantes.destroy |
App\Http\Controllers\FabricanteController@destroy | |
| | GET|HEAD | fabricantes/{fabricantes}/aviones
| fabricantes.aviones.index |
App\Http\Controllers\FabricanteAvionController@index | |
| | GET|HEAD | fabricantes/{fabricantes}/aviones/create
| fabricantes.aviones.create |
App\Http\Controllers\FabricanteAvionController@create | |
| | POST | fabricantes/{fabricantes}/aviones
| fabricantes.aviones.store |
App\Http\Controllers\FabricanteAvionController@store | |
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 34
| | GET|HEAD | fabricantes/{fabricantes}/aviones/{aviones}
| fabricantes.aviones.show |
App\Http\Controllers\FabricanteAvionController@show | |
| | GET|HEAD | fabricantes/{fabricantes}/aviones/{aviones}/edit
| fabricantes.aviones.edit |
App\Http\Controllers\FabricanteAvionController@edit | |
| | PUT | fabricantes/{fabricantes}/aviones/{aviones}
| fabricantes.aviones.update |
App\Http\Controllers\FabricanteAvionController@update | |
| | PATCH | fabricantes/{fabricantes}/aviones/{aviones}
| |
App\Http\Controllers\FabricanteAvionController@update | |
| | DELETE | fabricantes/{fabricantes}/aviones/{aviones}
| fabricantes.aviones.destroy |
App\Http\Controllers\FabricanteAvionController@destroy | |
| | GET|HEAD | aviones
| aviones.index |
App\Http\Controllers\AvionController@index | |
| | GET|HEAD | aviones/{aviones}
| aviones.show |
App\Http\Controllers\AvionController@show | |
+--------+----------+--------------------------------------------------+-----------------------------+--------------------------------------------------------+------------+
*/
• Un último detalle consistiría en eliminar el método show de fabricantes.aviones.show ya que ese método se usa
para mostrar un avión y ya tenemos un aviones.show que hace esa tarea:
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
| Here is where you can register all of the routes for an application.
*/
Route::resource('fabricantes','FabricanteController',['except'=>['edit','create']
de edición.
show.
Route::resource('aviones','AvionController',[ 'only'=>['index','show']
si no le indicamos el fabricante,
Route::resource('fabricantes.aviones','FabricanteAvionController',[
'except'=>['show','edit','create'] ]);
/*
+--------+----------+---------------------------------------------+-----------------------------+--------------------------------------------------------+------------+
Name | Action
| Middleware |
+--------+----------+---------------------------------------------+-----------------------------+--------------------------------------------------------+------------+
| | GET|HEAD | fabricantes |
fabricantes.index |
App\Http\Controllers\FabricanteController@index | |
| | POST | fabricantes |
fabricantes.store |
App\Http\Controllers\FabricanteController@store | auth.basic |
| | GET|HEAD | fabricantes/{fabricantes} |
fabricantes.show |
App\Http\Controllers\FabricanteController@show | |
| | PUT | fabricantes/{fabricantes} |
fabricantes.update |
App\Http\Controllers\FabricanteController@update | auth.basic |
| | PATCH | fabricantes/{fabricantes} |
App\Http\Controllers\FabricanteController@update | auth.basic |
| | DELETE | fabricantes/{fabricantes} |
fabricantes.destroy |
App\Http\Controllers\FabricanteController@destroy | auth.basic |
| | GET|HEAD | aviones |
aviones.index |
App\Http\Controllers\AvionController@index | |
| | GET|HEAD | aviones/{aviones} |
aviones.show | App\Http\Controllers\AvionController@show
| |
| | GET|HEAD | fabricantes/{fabricantes}/aviones |
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 36
fabricantes.aviones.index |
App\Http\Controllers\FabricanteAvionController@index | |
| | POST | fabricantes/{fabricantes}/aviones |
fabricantes.aviones.store |
App\Http\Controllers\FabricanteAvionController@store | auth.basic |
| | PUT | fabricantes/{fabricantes}/aviones/{aviones} |
fabricantes.aviones.update |
App\Http\Controllers\FabricanteAvionController@update | auth.basic |
| | PATCH | fabricantes/{fabricantes}/aviones/{aviones} |
App\Http\Controllers\FabricanteAvionController@update | auth.basic |
| | DELETE | fabricantes/{fabricantes}/aviones/{aviones} |
fabricantes.aviones.destroy |
App\Http\Controllers\FabricanteAvionController@destroy | auth.basic |
+--------+----------+---------------------------------------------+-----------------------------+--------------------------------------------------------+------------+
*/
• 401 Unauthorized – [Desautorizada] Cuando los detalles de autenticación son inválidos o no son otorgados.
También útil para disparar un popup de autorización si la API es usada desde un navegador.
• 403 Forbidden – [Prohibida] Cuando la autenticación es exitosa pero el usuario no tiene permiso al recurso en
cuestión.
• 404 Not Found – [No encontrada] Cuando un recurso se solicita un recurso no existente.
---
• 405 Method Not Allowed – [Método no permitido] Cuando un método HTTP que está siendo pedido no está
permitido para el usuario autenticado.
• 409 Conflict - [Conflicto] Cuando hay algún conflicto al procesar una petición, por ejemplo en PATCH, POST o
DELETE.
• 410 Gone – [Retirado] Indica que el recurso en ese endpoint ya no está disponible. Útil como una respuesta en
blanco para viejas versiones de la API
• 415 Unsupported Media Type – [Tipo de contenido no soportado] Si el tipo de contenido que solicita la petición
es incorrecto
• 422 Unprocessable Entity – [Entidad improcesable] Utilizada para errores de validación, o cuando por ejemplo
faltan campos en una petición.
• 429 Too Many Requests – [Demasiadas peticiones] Cuando una petición es rechazada debido a la tasa límite .
---
• 500 – Internal Server Error – [Error Interno del servidor] Los desarrolladores de API NO deberían usar este
código. En su lugar se debería loguear el fallo y no devolver respuesta.
--- Más información en: http://jsonapi.org/format/'''
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 38
return
response()->json(['status'=>'ok','data'=>Fabricante::all()], 200);
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
//
return "Se muestra formulario para crear un fabricante.";
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 39
{
//
// return "Se muestra Fabricante con id: $id";
// Buscamos un fabricante por el id.
$fabricante=Fabricante::find($id);
return
response()->json(['status'=>'ok','data'=>$fabricante],200);
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
//
return "Se muestra formulario para editar Fabricante con
id: $id";
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
//
}
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 40
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
//
}
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index($idFabricante)
{
// Devolverá todos los aviones.
//return "Mostrando los aviones del fabricante con Id
$idFabricante";
$fabricante=Fabricante::find($idFabricante);
if (! $fabricante)
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 404.
// En code podríamos indicar un código de error
personalizado de nuestra aplicación si lo deseamos.
return
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 41
response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra
un fabricante con ese código.'])],404);
}
return
response()->json(['status'=>'ok','data'=>$fabricante->aviones()->get()],200);
//return
response()->json(['status'=>'ok','data'=>$fabricante->aviones],200);
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create($idFabricante)
{
//
return "Se muestra formulario para crear un avión del
fabricante $idFabricante.";
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($idFabricante,$idAvion)
{
//
return "Se muestra avión $idAvion del fabricante
$idFabricante";
}
/**
* Show the form for editing the specified resource.
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 42
*
* @param int $id
* @return Response
*/
public function edit($idFabricante,$idAvion)
{
//
return "Se muestra formulario para editar el avión $idAvion
del fabricante $idFabricante";
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($idFabricante,$idAvion)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($idFabricante,$idAvion)
{
//
}
En el fichero app/Http/Kernel.php se definen los middlewares que se cargarán al inicio de nuestra aplicación.
/**
* The application's global HTTP middleware stack.
*
* @var array
*/
// Aquí se programa el Middleware que se cargará siempre y
globalmente en la aplicación.
protected $middleware = [
'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
'Illuminate\Cookie\Middleware\EncryptCookies',
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
'Illuminate\Session\Middleware\StartSession',
'Illuminate\View\Middleware\ShareErrorsFromSession',
'App\Http\Middleware\VerifyCsrfToken',
];
/**
* The application's route middleware.
*
* @var array
*/
}
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 44
TokenMismatchException
Teóricamente se debería estar ejecutando el método store() de nuestro controlador de fabricantes, pero se supone
que previamente se tendría que haber mostrado un formulario para cubrir esos datos y haber enviado junto con los
datos el token CSRF, pero no se ha enviado dicho token por que ni siquiera tenemos formulario.
Para evitar este tipo de error en nuestra API RESTful podríamos comentar en app/Http/Kernel.php en el array
$middleware la siguiente línea:
//'App\Http\Middleware\VerifyCsrfToken',
ATENCIÓN: Ésto no implicará ningún tipo de agujero de seguridad en nuestra API ya que más adelante veremos
como evitar CSRF a través de autenticación de usuarios.
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as
AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as
CanResetPasswordContract;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['name', 'email', 'password'];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = ['password', 'remember_token'];
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as
AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as
CanResetPasswordContract;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 46
/**
* The attributes that are mass assignable.
*
* @var array
*/
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('email')->unique();
$table->string('password');
$table->timestamps();
});
}
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 47
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('users');
}
• Ejecutamos la migración:
<?php
use Illuminate\Database\Seeder;
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
User::create(
[
'email'=>'[email protected]',
'password'=> Hash::make('abc123') //Cifrado
de la contraseña abc123
]);
}
}
• Edición de database/seeds/DatabaseSeeder.php:
<?php
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 48
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Model::unguard();
$this->call('FabricanteSeeder');
$this->call('AvionSeeder');
• Ejecutamos el seeder:
Configuración de la autenticación
La autenticación de usuarios solamente la vamos a utilizar para el caso de crear, actualizar o eliminar datos a
través de la API REST.
• Para poder usar la autenticación usaremos el middleware AuthenticateWithBasicAuth de Laravel.
• Editaremos los controladores para indicarles que hagan uso de ese Middleware pero solamente para unos métodos
específicos y además borraremos los métodos de /create y /edit ya que no usamos formularios.
• Editaremos el fichero del controlador app/Http/Controllers/FabricanteController.php:
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
$this->middleware('auth.basic',['only'=>['store','update','destroy']]);
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
// Devolverá todos los fabricantes.
// return "Mostrando todos los fabricantes de la base de
datos.";
// return Fabricante::all(); No es lo más correcto por que
se devolverían todos los registros. Se recomienda usar Filtros.
// Se debería devolver un objeto con una propiedad como
mínimo data y el array de resultados en esa propiedad.
// A su vez también es necesario devolver el código HTTP de
la respuesta.
//php
http://elbauldelprogramador.com/buenas-practicas-para-el-diseno-de-una-api-RESTful-pragmatica/
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 50
//
https://cloud.google.com/storage/docs/json_api/v1/status-codes
return
response()->json(['status'=>'ok','data'=>Fabricante::all()], 200);
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
//
return "petición post recibida.";
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
// return "Se muestra Fabricante con id: $id";
// Buscamos un fabricante por el id.
$fabricante=Fabricante::find($id);
return
response()->json(['status'=>'ok','data'=>$fabricante],200);
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 51
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
//
}
• Si ahora intentamos acceder a aviones por alguno de los métodos de POST, PUT o DELETE de Fabricante nos
pedirá la autenticación:
• El controlador para app/Http/Controllers/AvionController.php no es necesario modificarlo por que no tenemos
ninguno de esos métodos:
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
*/
return response()->json(['status'=>'ok','data'=>Avion::all()],
200);
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
// return "Se muestra Fabricante con id: $id";
// Buscamos un fabricante por el id.
$avion=Avion::find($id);
if (!$avion)
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 404.
// En code podríamos indicar un código de error
personalizado de nuestra aplicación si lo deseamos.
return
response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra
un avión con ese código.'])],404);
}
return response()->json(['status'=>'ok','data'=>$avion],200);
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
//
}
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Fabricante;
use App\Avion;
$this->middleware('auth.basic',['only'=>['store','update','destroy']]);
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index($idFabricante)
{
// Devolverá todos los aviones.
//return "Mostrando los aviones del fabricante con Id
$idFabricante";
$fabricante=Fabricante::find($idFabricante);
if (! $fabricante)
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 404.
// En code podríamos indicar un código de error
personalizado de nuestra aplicación si lo deseamos.
return
response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra
un fabricante con ese código.'])],404);
}
return
response()->json(['status'=>'ok','data'=>$fabricante->aviones()->get()],200);
//return
response()->json(['status'=>'ok','data'=>$fabricante->aviones],200);
}
/**
* Store a newly created resource in storage.
*
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 55
* @return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($idFabricante,$idAvion)
{
//
return "Se muestra avión $idAvion del fabricante
$idFabricante";
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($idFabricante,$idAvion)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($idFabricante,$idAvion)
{
//
}
}
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 56
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
$this->middleware('auth.basic',['only'=>['store','update','destroy']]);
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 57
{
// Devolverá todos los fabricantes.
// return "Mostrando todos los fabricantes de la base de
datos.";
// return Fabricante::all(); No es lo más correcto por que
se devolverían todos los registros. Se recomienda usar Filtros.
// Se debería devolver un objeto con una propiedad como
mínimo data y el array de resultados en esa propiedad.
// A su vez también es necesario devolver el código HTTP de
la respuesta.
//php
http://elbauldelprogramador.com/buenas-practicas-para-el-diseno-de-una-api-RESTful-pragmatica/
//
https://cloud.google.com/storage/docs/json_api/v1/status-codes
return
response()->json(['status'=>'ok','data'=>Fabricante::all()], 200);
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
return
response()->json(['errors'=>array(['code'=>422,'message'=>'Faltan datos
necesarios para el proceso de alta.'])],422);
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
// return "Se muestra Fabricante con id: $id";
// Buscamos un fabricante por el id.
$fabricante=Fabricante::find($id);
return
response()->json(['status'=>'ok','data'=>$fabricante],200);
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
//
}
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Response;
$this->middleware('auth.basic',['only'=>['store','update','destroy']]);
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index($idFabricante)
{
// Devolverá todos los aviones.
//return "Mostrando los aviones del fabricante con Id
$idFabricante";
$fabricante=Fabricante::find($idFabricante);
if (! $fabricante)
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 404.
// En code podríamos indicar un código de error
personalizado de nuestra aplicación si lo deseamos.
return
response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra
un fabricante con ese código.'])],404);
}
return
response()->json(['status'=>'ok','data'=>$fabricante->aviones()->get()],200);
//return
response()->json(['status'=>'ok','data'=>$fabricante->aviones],200);
}
/**
* Store a newly created resource in storage.
*
* @return Response
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 61
*/
public function store(Request $request,$idFabricante)
{
/* Necesitaremos el fabricante_id que lo recibimos en la
ruta
#Serie (auto incremental)
Modelo
Longitud
Capacidad
Velocidad
Alcance */
// Buscamos el Fabricante.
$fabricante= Fabricante::find($idFabricante);
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($idFabricante,$idAvion)
{
//
return "Se muestra avión $idAvion del fabricante
$idFabricante";
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($idFabricante,$idAvion)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($idFabricante,$idAvion)
{
//
}
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 63
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
$this->middleware('auth.basic',['only'=>['store','update','destroy']]);
}
// Mejora en la respuesta.
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 64
return response()->json(['datos'=>Fabricante::all()],200);
//return
response()->json(['status'=>'ok','data'=>Fabricante::all()], 200);
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
http://jsonapi.org/format/
// Devolvemos el código HTTP 201 Created – [Creada]
Respuesta a un POST que resulta en una creación. Debería ser combinado
con un encabezado Location, apuntando a la ubicación del nuevo recurso.
$response =
Response::make(json_encode(['data'=>$nuevoFabricante]),
201)->header('Location',
'http://www.dominio.local/fabricantes/'.$nuevoFabricante->id)->header('Content-Type',
'application/json');
return $response;
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
// return "Se muestra Fabricante con id: $id";
// Buscamos un fabricante por el id.
$fabricante=Fabricante::find($id);
return
response()->json(['status'=>'ok','data'=>$fabricante],200);
/**
* Update the specified resource in storage.
*
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 66
if ($direccion)
{
$fabricante->direccion = $direccion;
$bandera=true;
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 67
if ($telefono)
{
$fabricante->telefono = $telefono;
$bandera=true;
}
if ($bandera)
{
// Almacenamos en la base de datos el registro.
$fabricante->save();
return
response()->json(['status'=>'ok','data'=>$fabricante], 200);
}
else
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 304 Not Modified – [No Modificada] Usado
cuando el cacheo de encabezados HTTP está activo
// Este código 304 no devuelve ningún body, así
que si quisiéramos que se mostrara el mensaje usaríamos un código 200
en su lugar.
return
response()->json(['errors'=>array(['code'=>304,'message'=>'No se ha
modificado ningún dato de fabricante.'])],304);
}
}
$fabricante->nombre = $nombre;
$fabricante->direccion = $direccion;
$fabricante->telefono = $telefono;
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 68
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
//
}
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
$this->middleware('auth.basic',['only'=>['store','update','destroy']]);
}
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 69
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index($idFabricante)
{
// Devolverá todos los aviones.
//return "Mostrando los aviones del fabricante con Id
$idFabricante";
$fabricante=Fabricante::find($idFabricante);
if (! $fabricante)
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 404.
// En code podríamos indicar un código de error
personalizado de nuestra aplicación si lo deseamos.
return
response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra
un fabricante con ese código.'])],404);
}
return
response()->json(['status'=>'ok','data'=>$fabricante->aviones()->get()],200);
//return
response()->json(['status'=>'ok','data'=>$fabricante->aviones],200);
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store(Request $request,$idFabricante)
{
/* Necesitaremos el fabricante_id que lo recibimos en la
ruta
#Serie (auto incremental)
Modelo
Longitud
Capacidad
Velocidad
Alcance */
campos.
if ( !$request->input('modelo') ||
!$request->input('longitud') || !$request->input('capacidad') ||
!$request->input('velocidad') || !$request->input('alcance') )
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 422 Unprocessable Entity – [Entidad
improcesable] Utilizada para errores de validación.
return
response()->json(['errors'=>array(['code'=>422,'message'=>'Faltan datos
necesarios para el proceso de alta.'])],422);
}
// Buscamos el Fabricante.
$fabricante= Fabricante::find($idFabricante);
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($idFabricante,$idAvion)
{
//
return "Se muestra avión $idAvion del fabricante
$idFabricante";
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update(Request $request, $idFabricante, $idAvion)
{
// Comprobamos si el fabricante que nos están pasando
existe o no.
$fabricante=Fabricante::find($idFabricante);
if ($longitud)
{
$avion->longitud = $longitud;
$bandera=true;
}
if ($capacidad)
{
$avion->capacidad = $capacidad;
$bandera=true;
}
if ($velocidad)
{
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 73
$avion->velocidad = $velocidad;
$bandera=true;
}
if ($alcance)
{
$avion->alcance = $alcance;
$bandera=true;
}
if ($bandera)
{
// Almacenamos en la base de datos el registro.
$avion->save();
return
response()->json(['status'=>'ok','data'=>$avion], 200);
}
else
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 304 Not Modified – [No Modificada] Usado
cuando el cacheo de encabezados HTTP está activo
// Este código 304 no devuelve ningún body, así
que si quisiéramos que se mostrara el mensaje usaríamos un código 200
en su lugar.
return
response()->json(['errors'=>array(['code'=>304,'message'=>'No se ha
modificado ningún dato del avión.'])],304);
}
$avion->modelo = $modelo;
$avion->longitud = $longitud;
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 74
$avion->capacidad = $capacidad;
$avion->velocidad = $velocidad;
$avion->alcance = $alcance;
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($idFabricante,$idAvion)
{
//
}
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
$this->middleware('auth.basic',['only'=>['store','update','destroy']]);
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
// Devolverá todos los fabricantes.
// return "Mostrando todos los fabricantes de la base de
datos.";
// return Fabricante::all(); No es lo más correcto por que
se devolverían todos los registros. Se recomienda usar Filtros.
// Se debería devolver un objeto con una propiedad como
mínimo data y el array de resultados en esa propiedad.
// A su vez también es necesario devolver el código HTTP de
la respuesta.
//php
http://elbauldelprogramador.com/buenas-practicas-para-el-diseno-de-una-api-RESTful-pragmatica/
//
https://cloud.google.com/storage/docs/json_api/v1/status-codes
return
response()->json(['status'=>'ok','data'=>Fabricante::all()], 200);
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
// return "Se muestra Fabricante con id: $id";
// Buscamos un fabricante por el id.
$fabricante=Fabricante::find($id);
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 77
return
response()->json(['status'=>'ok','data'=>$fabricante],200);
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update(Request $request, $id)
{
// Comprobamos si el fabricante que nos están pasando
existe o no.
$fabricante=Fabricante::find($id);
$telefono=$request->input('telefono');
if ($direccion)
{
$fabricante->direccion = $direccion;
$bandera=true;
}
if ($telefono)
{
$fabricante->telefono = $telefono;
$bandera=true;
}
if ($bandera)
{
// Almacenamos en la base de datos el registro.
$avion->save();
return
response()->json(['status'=>'ok','data'=>$fabricante], 200);
}
else
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 304 Not Modified – [No Modificada] Usado
cuando el cacheo de encabezados HTTP está activo
// Este código 304 no devuelve ningún body, así
que si quisiéramos que se mostrara el mensaje usaríamos un código 200
en su lugar.
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 79
return
response()->json(['errors'=>array(['code'=>304,'message'=>'No se ha
modificado ningún dato de fabricante.'])],304);
}
}
$fabricante->nombre = $nombre;
$fabricante->direccion = $direccion;
$fabricante->telefono = $telefono;
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
// Primero eliminaremos todos los aviones de un fabricante
y luego el fabricante en si mismo.
// Comprobamos si el fabricante que nos están pasando
existe o no.
$fabricante=Fabricante::find($id);
}
}
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Fabricante;
use App\Avion;
$this->middleware('auth.basic',['only'=>['store','update','destroy']]);
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index($idFabricante)
{
// Devolverá todos los aviones.
//return "Mostrando los aviones del fabricante con Id
$idFabricante";
$fabricante=Fabricante::find($idFabricante);
if (! $fabricante)
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 404.
// En code podríamos indicar un código de error
personalizado de nuestra aplicación si lo deseamos.
return
response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra
un fabricante con ese código.'])],404);
}
response()->json(['status'=>'ok','data'=>$fabricante->aviones],200);
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store(Request $request,$idFabricante)
{
/* Necesitaremos el fabricante_id que lo recibimos en la
ruta
#Serie (auto incremental)
Modelo
Longitud
Capacidad
Velocidad
Alcance */
// Buscamos el Fabricante.
$fabricante= Fabricante::find($idFabricante);
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($idFabricante,$idAvion)
{
//
return "Se muestra avión $idAvion del fabricante
$idFabricante";
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update(Request $request, $idFabricante, $idAvion)
{
// Comprobamos si el fabricante que nos están pasando
existe o no.
$fabricante=Fabricante::find($idFabricante);
if (!$fabricante)
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 404.
// En code podríamos indicar un código de error
personalizado de nuestra aplicación si lo deseamos.
return
response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra
un fabricante con ese código.'])],404);
}
if ($longitud)
{
$avion->longitud = $longitud;
$bandera=true;
}
if ($capacidad)
{
$avion->capacidad = $capacidad;
$bandera=true;
}
if ($velocidad)
{
$avion->velocidad = $velocidad;
$bandera=true;
}
if ($alcance)
{
$avion->alcance = $alcance;
$bandera=true;
}
if ($bandera)
{
// Almacenamos en la base de datos el registro.
$avion->save();
return
response()->json(['status'=>'ok','data'=>$avion], 200);
}
else
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 304 Not Modified – [No Modificada] Usado
cuando el cacheo de encabezados HTTP está activo
// Este código 304 no devuelve ningún body, así
que si quisiéramos que se mostrara el mensaje usaríamos un código 200
en su lugar.
return
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 86
response()->json(['errors'=>array(['code'=>304,'message'=>'No se ha
modificado ningún dato de fabricante.'])],304);
}
$avion->modelo = $modelo;
$avion->longitud = $longitud;
$avion->capacidad = $capacidad;
$avion->velocidad = $velocidad;
$avion->alcance = $alcance;
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($idFabricante,$idAvion)
{
// Comprobamos si el fabricante que nos están pasando
existe o no.
$fabricante=Fabricante::find($idFabricante);
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 88
return response()->json(['status'=>'ok','data'=>Avion::all()],
200);
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
// return "Se muestra Fabricante con id: $id";
// Buscamos un fabricante por el id.
$avion=Avion::find($id);
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 404.
// En code podríamos indicar un código de error
personalizado de nuestra aplicación si lo deseamos.
return
response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra
un avión con ese código.'])],404);
}
return response()->json(['status'=>'ok','data'=>$avion],200);
}
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
$this->middleware('auth.basic',['only'=>['store','update','destroy']]);
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
// Devuelve todos los fabricantes en JSON.
// return Fabricante::all();
// Mejora en la respuesta.
// Devolvemos explícitamente el código 200 http de datos
encontrados.
// Se puede poner como 404 cuando no se encuentra nada.
//return response()->json(['datos'=>Fabricante::all()],200);
// Con caché.
return response()->json(['status'=>'ok','data'=>$fabricantes],
200);
// Sin caché.
//return
response()->json(['status'=>'ok','data'=>Fabricante::all()], 200);
}
/**
* Store a newly created resource in storage.
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 91
*
* @return Response
*/
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
// return "Se muestra Fabricante con id: $id";
// Buscamos un fabricante por el id.
$fabricante=Fabricante::find($id);
return
response()->json(['status'=>'ok','data'=>$fabricante],200);
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update(Request $request, $id)
{
// Comprobamos si el fabricante que nos están pasando
existe o no.
$fabricante=Fabricante::find($id);
if (!$fabricante)
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 404.
// En code podríamos indicar un código de error
personalizado de nuestra aplicación si lo deseamos.
return
response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra
un fabricante con ese código.'])],404);
}
if ($bandera)
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 94
{
// Almacenamos en la base de datos el registro.
$avion->save();
return
response()->json(['status'=>'ok','data'=>$fabricante], 200);
}
else
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 304 Not Modified – [No Modificada] Usado
cuando el cacheo de encabezados HTTP está activo
// Este código 304 no devuelve ningún body, así
que si quisiéramos que se mostrara el mensaje usaríamos un código 200
en su lugar.
return
response()->json(['errors'=>array(['code'=>304,'message'=>'No se ha
modificado ningún dato de fabricante.'])],304);
}
}
$fabricante->nombre = $nombre;
$fabricante->direccion = $direccion;
$fabricante->telefono = $telefono;
/**
* Remove the specified resource from storage.
*
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 95
}
}
• Véase el siguiente ejemplo dónde se usa caché (durante 20 segundos) en el método index() de
FabricanteAvionController:
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
$this->middleware('auth.basic',['only'=>['store','update','destroy']]);
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index($idFabricante)
{
// Devolverá todos los aviones.
//return "Mostrando los aviones del fabricante con Id
$idFabricante";
$fabricante=Fabricante::find($idFabricante);
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 97
if (! $fabricante)
{
// Se devuelve un array errors con los errores
encontrados y cabecera HTTP 404.
// En code podríamos indicar un código de error
personalizado de nuestra aplicación si lo deseamos.
return
response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra
un fabricante con ese código.'])],404);
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store(Request $request,$idFabricante)
{
/* Necesitaremos el fabricante_id que lo recibimos en la
ruta
#Serie (auto incremental)
Modelo
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 98
Longitud
Capacidad
Velocidad
Alcance */
// Buscamos el Fabricante.
$fabricante= Fabricante::find($idFabricante);
201)->header('Location',
'http://www.dominio.local/aviones/'.$nuevoAvion->serie)->header('Content-Type',
'application/json');
return $response;
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($idFabricante,$idAvion)
{
//
return "Se muestra avión $idAvion del fabricante
$idFabricante";
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update(Request $request, $idFabricante, $idAvion)
{
// Comprobamos si el fabricante que nos están pasando
existe o no.
$fabricante=Fabricante::find($idFabricante);
{
$avion->capacidad = $capacidad;
$bandera=true;
}
if ($bandera)
{
// Almacenamos en la base de datos el registro.
$avion->save();
return
response()->json(['status'=>'ok','data'=>$avion], 200);
}
else
{
// Devolveremos un código 304 Not Modified –
[No Modificada] Usado cuando el cacheo de encabezados HTTP está activo
// Este código 304 no devuelve ningún body, así
que si quisiéramos que se mostrara el mensaje usaríamos un código 200
en su lugar.
return
response()->json(['code'=>304,'message'=>'No se ha modificado ningún dato
de fabricante.'],304);
}
response()->json(['errors'=>array(['code'=>422,'message'=>'Faltan valores
para completar el procesamiento.'])],422);
}
$avion->modelo = $modelo;
$avion->longitud = $longitud;
$avion->capacidad = $capacidad;
$avion->velocidad = $velocidad;
$avion->alcance = $alcance;
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($idFabricante,$idAvion)
{
// Comprobamos si el fabricante que nos están pasando
existe o no.
$fabricante=Fabricante::find($idFabricante);
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
// Versionado de la ruta
Route::group(array('prefix'=>'api/v1.0'),function()
{
// resource recibe nos parámetros(URI del recurso, Controlador que
gestionará las peticiones)
Route::resource('fabricantes','FabricanteController',['except'=>['edit','create']
]); // Todos los métodos menos Edit que mostraría un formulario
de edición.
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Fabricante;
use Response;
use Illuminate\Support\Facades\Cache;
$this->middleware('auth.basic',['only'=>['store','update','destroy']]);
/**
* @return Response
*/
// return Fabricante::all();
$fabricantes=Cache::remember('cachefabricantes',15/60,function()
{
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 106
// En lugar de devolver
// return Fabricante::all();
//
gráficas.
permite construir
cada 10 elementos.
});
caché.
// return response()->json(['status'=>'ok',
'data'=>Fabricante::all()],200);
// return response()->json(['status'=>'ok',
'data'=>$fabricantes],200);
return response()->json(['status'=>'ok',
'siguiente'=>$fabricantes->nextPageUrl(),'anterior'=>$fabricantes->previousPageUrl(),'data'=>$fabricantes->items()],200);
/**
* @return Response
*/
formulario
/*
//
*/
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 107
/**
* @return Response
*/
if (!$request->input('nombre') ||
!$request->input('direccion') || !$request->input('telefono'))
Devolvemos error.
return
response()->json(['errors'=>array(['code'=>422,'message'=>'Faltan datos
$nuevoFabricante=Fabricante::create($request->all());
$respuesta=
Response::make(json_encode(['data'=>$nuevoFabricante]),201)->header('Location','http://www.dominio.local/fabricantes/'.$nuevoFabricante->id)->header('Content-Type','application/json');
return $respuesta;
/**
* @return Response
*/
$fabricante=Fabricante::find($id);
if (! $fabricante)
return
response()->json(['errors'=>Array(['code'=>404,'message'=>'No se encuentra
return
response()->json(['status'=>'ok','data'=>$fabricante],200);
/**
* @return Response
*/
/*
//
*/
/**
* @return Response
*/
devolvemos error.
$fabricante=Fabricante::find($id);
if (! $fabricante)
return
response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra
campos recibidos.
$nombre=$request->input('nombre');
$direccion=$request->input('direccion');
$telefono=$request->input('telefono');
(Total)
if ($request->method()=='PATCH')
$bandera=false;
$fabricante->nombre=$nombre;
$bandera=true;
$fabricante->direccion=$direccion;
$bandera=true;
$fabricante->telefono=$telefono;
$bandera=true;
if ($bandera)
// Grabamos el fabricante.
$fabricante->save();
return
response()->json(['status'=>'ok','data'=>$fabricante],200);
else
return
response()->json(['errors'=>array(['code'=>304,'message'=>'No se ha
return
response()->json(['errors'=>array(['code'=>422,'message'=>'Faltan valores
$fabricante->nombre=$nombre;
$fabricante->direccion=$direccion;
$fabricante->telefono=$telefono;
// Grabamos el fabricante
$fabricante->save();
return
response()->json(['status'=>'ok','data'=>$fabricante],200);
/**
* @return Response
*/
// Borrado de un fabricante.
$fabricante=Fabricante::find($id);
if (! $fabricante)
return
response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra
}
LARAVEL Framework - Tutorial 01 - Creación de API RESTful 111
// un código 200.
así
// $aviones = $fabricante->aviones()->get();
$aviones = $fabricante->aviones;
if (sizeof($aviones) >0)
fabricante sería:
// $fabricante->aviones->delete();
return
response()->json(['errors'=>array(['code'=>409,'message'=>'Este fabricante
$fabricante->delete();
return response()->json(['code'=>204,'message'=>'Se ha
Referencias
[1] http:/ / www. laravel. com
[2] https:/ / chrome. google. com/ webstore/ detail/ postman-rest-client/ fdmmgilgnpjigdojojpjoooidkmcomcm?hl=es
[3] https:/ / chrome. google. com/ webstore/ detail/ advanced-rest-client/ hgmloofddffdnphfgcellkdfbfbjeloo?hl=es
[4] http:/ / asiermarques. com/ 2013/ conceptos-sobre-apis-rest/
[5] http:/ / en. wikipedia. org/ wiki/ Active_record_pattern
[6] http:/ / laravel. com/ docs/ 5. 0/ eloquent
[7] https:/ / styde. net/ aprende-a-usar-eloquent-el-orm-de-laravel/
[8] http:/ / laravel. com/ docs/ 5. 0/ artisan
[9] http:/ / laravel. com/ docs/ 5. 0/ controllers
[10] http:/ / laravel. com/ docs/ 5. 0/ routing
[11] http:/ / es. wikipedia. org/ wiki/ Facade_%28patr%C3%B3n_de_dise%C3%B1o%29
[12] http:/ / es. wikipedia. org/ wiki/ Inyecci%C3%B3n_de_dependencias
[13] http:/ / laravel. com/ docs/ 5. 0/ requests
[14] https:/ / manuais. iessanclemente. net/ index. php/ Control_de_versiones_con_Git_y_GitHub#RESUMEN_Y_USO_B. C3.
81SICO_de_Git_por_comandos
[15] http:/ / rails. mx/ blog/ 2013/ 08/ 09/ flujo-colaborativo-de-trabajo-con-git-y-github. html
Fuentes y contribuyentes del artículo 113
Licencia
Creative Commons Reconocimiento
http:/ / creativecommons. org/ licenses/ by/ 3. 0/