{"id":199,"date":"2023-08-17T22:36:42","date_gmt":"2023-08-17T22:36:42","guid":{"rendered":"https:\/\/robetorr.com\/?p=199"},"modified":"2023-08-17T22:41:11","modified_gmt":"2023-08-17T22:41:11","slug":"instalar-backend-api-rest-con-laravel-lumen","status":"publish","type":"post","link":"https:\/\/robetorr.com\/index.php\/2023\/08\/17\/instalar-backend-api-rest-con-laravel-lumen\/","title":{"rendered":"Instalar Backend API REST con Laravel Lumen"},"content":{"rendered":"\n<p>Proceso de instalacion paso a paso de un backend sencillo de una sola tabla de base de datos usando PHP framework Laravel Lumen version 10:<\/p>\n\n\n\n<p>Requisito previo obviamente en para este tutorial, tener Linux + Apache Server + PHP &gt; 8.0 y Mysql server o Postgresql. <\/p>\n\n\n\n<p>Ademas, Laravel <a href=\"https:\/\/lumen.laravel.com\/docs\/10.x\" data-type=\"URL\" data-id=\"https:\/\/lumen.laravel.com\/docs\/10.x\" target=\"_blank\" rel=\"noreferrer noopener\">Lumen<\/a> requiere que tengas instaladas de las siguentes extensiones de PHP:<\/p>\n\n\n<ul>\n<li>OpenSSL PHP<\/li>\n<li>PDO PHP<\/li>\n<li>Mbstring<\/li>\n<li>ZIP (opcional)<\/li>\n<li>XML (opcional)<\/li>\n<li>curl (vamos a probar conexiones con php-curl)<\/li>\n<\/ul>\n<p>Tambien debes tener instalado <a href=\"https:\/\/getcomposer.org\/\" target=\"_blank\" rel=\"noopener\">composer<\/a> (es un manejador de dependencias de PHP)<\/p>\n<p>\u00a0<\/p>\n<h3>Paso 1:<\/h3>\n<p>Instalar Laravel Lumen de la siguiente forma:<\/p>\n<p>En la consola de Linux ejecutamos composer de la siguiente manera:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>composer create-project --prefer-dist laravel\/lumen api-test<\/code><\/pre>\n\n\n<h3>Paso 2<\/h3>\n<p>Generar una App Key para nuestro backend, para esto ejecutamos en la consola de Linux lo siguiente:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>php -r \"echo bin2hex(random_bytes(32));\"<\/code><\/pre>\n\n\n<p>Esto devuelve como resultado algo como esto:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>54e2adb7d8eed9619e700f04aef3fde231d917d17ebc5867224d7a74fcb8f929<\/code><\/pre>\n\n\n<h3>Paso 3<\/h3>\n<p>Editamos el archivo .env que se encuentra en el directorio raiz de la aplicacion en nuestro caso, la aplicacion quedo instalada en la carpeta llamada api-test por lo tanto el .env debe estar ubicado en api-test\/.env.<\/p>\n<p>Editaremos la linea con la variable\u00a0 APP_KEY y en ella pegamos el string que generamos en el <strong>Paso 2<\/strong><\/p>\n<p>Ademas en este paso, aprovechamos de agregar los parametros asociados a la base de datos DB_DATABASE, DB_USERNAME, DB_PASSWORD y DB_CONNECTION (mysql en este caso).<\/p>\n<p>El .env por el momento, deberia quedar asi:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>APP_NAME=Lumen\nAPP_ENV=local\nAPP_KEY=54e2adb7d8eed9619e700f04aef3fde231d917d17ebc5867224d7a74fcb8f929\nAPP_DEBUG=true\nAPP_URL=http:\/\/localhost\nAPP_TIMEZONE=UTC\n\nLOG_CHANNEL=stack\nLOG_SLACK_WEBHOOK_URL=\n\nDB_CONNECTION=mysql\nDB_HOST=127.0.0.1\nDB_PORT=3306\nDB_DATABASE=apitest\nDB_USERNAME=tunombredeusuario\nDB_PASSWORD=tupassword\n\nCACHE_DRIVER=file\nQUEUE_CONNECTION=sync<\/code><\/pre>\n\n\n<p>Destacamos el parametro DB_DATABASE al que le asignamos el valor de apitest, debido a que mas adelante, debemos crear una base de datos en mysql con ese mismo nombre.<\/p>\n<p><\/p>\n<h3>Paso 4<\/h3>\n<p>Editamos el archivo que esta en la carpeta bootstrap\/app.php por ahora solo descomentamos las siguientes lineas:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>  $app-&gt;withFacades();\n  $app-&gt;withEloquent();<\/code><\/pre>\n\n\n<h3>Paso 5<\/h3>\n<p>Creamos la migracion para la tabla opiniones, para ello, desde la consola de linux ejecutamos la siguiente linea:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>php artisan make:migration create_opiniones_table <\/code><\/pre>\n\n\n<p>El resultado devuelto debe ser algo como esto:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>INFO  Migration &#91;\/home\/robetorr\/api-test\/database\/migrations\/2023_08_17_205246_create_opiniones_table.php] created successfully.<\/code><\/pre>\n\n\n<h3>Paso 6<\/h3>\n<p>Editar 2023_08_17_205246_create_opiniones_table.php (<strong>archivo generado en el paso 5<\/strong>) que se encuentra ubicado en la carpeta database\/migrations de la aplicacion y agregar los siguientes campos:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    \/**\n     * Run the migrations.\n     *\/\n    public function up(): void\n    {\n        Schema::create('opiniones', function (Blueprint $table) {\n            $table-&gt;bigIncrements();\n            $table-&gt;text('nombre');\n            $table-&gt;text('email');\n            $table-&gt;text('mensaje');            \n            $table-&gt;timestamps();\n        });\n    }\n\n    \/**\n     * Reverse the migrations.\n     *\/\n    public function down(): void\n    {\n        Schema::dropIfExists('opiniones');\n    }\n};<\/code><\/pre>\n\n\n<h3>Paso 7 MySql<\/h3>\n<p>Entramos a mysql<\/p>\n\n\n<pre class=\"wp-block-code\"><code> mysql -u robetorr -p<\/code><\/pre>\n\n\n<p>Creamos la base de datos&nbsp;<\/p>\n\n\n<pre class=\"wp-block-code\"><code>create database apitest;<\/code><\/pre>\n\n\n<p>Salimos de mysql (ctrl+d)<\/p>\n<h3>Paso 6<\/h3>\n<p>Ejecutar la migracion. En la raiz de la aplicacion ejecutar:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>php artisan migrate<\/code><\/pre>\n\n\n<p>Si todo esta bien y los parametros del .env coinciden con los de tu base de datos, esto debe devolver lo siguiente:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>INFO  Preparing database.  \n\n  Creating migration table ............................................................................................. 916ms DONE\n\n   INFO  Running migrations.  \n\n  2023_08_17_205246_create_opiniones_table ........................................................................... 1,206ms DONE<\/code><\/pre>\n\n\n<p>Has creado la tabla opiniones en la base de datos apitest.<\/p>\n<h3>Paso 7<\/h3>\n<p>Creamos el modelo en la carpeta app\/Model y lo llamaremos app\/Model\/Opinion.php debe quedar asi:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\nnamespace App\\Models;\n\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Opinion extends Model\n{\n    protected $fillable = &#91;'nombre', 'email','mensaje'];\n}<\/code><\/pre>\n\n\n<h3>Paso 8<\/h3>\n<p>Creamos el controlador en app\/Http\/Controllers\/ y lo llamaremos app\/Controllers\/OpinionController.php y creamos los metodos index,show,store,update y destroy. El arcivo deberia quedar de esta manera:<\/p>\n<p><\/p>\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\nnamespace App\\Http\\Controllers;\nuse Illuminate\\Http\\Request;\nuse App\\Models\\Opinion;\n\nclass OpinionController extends Controller\n{\n    \/**\n     * Create a new controller instance.\n     *\n     * @return void\n     *\/\n    public function __construct()\n    {\n        \/\/\n    }\n    public function index(){\n        try\n        {\n            $Opiniones = Opinion::all();\n        }\n        catch (Exception $e)\n        {\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; '500',\n                'response' =&gt; 'Internal Server Error',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; 'Error-1',\n                    \/\/\"exception\" =&gt; $e-&gt;getMessage(),\n                    'errorMessage' =&gt; 'Error getting Opinions'\n                ]\n            ], 500);\n        }\n\n        if($Opiniones)\n        {\n            $data = &#91;];\n            foreach($Opiniones as $Opinion)\n            {\n                $types = &#91;];\n                $types = &#91;\n                    'id' =&gt; $Opinion-&gt;id,\n                    'nombre' =&gt; $Opinion-&gt;nombre,\n                    'email' =&gt; $Opinion-&gt;email,\n                    'id_post' =&gt; $Opinion-&gt;id_post,\n                    'mensaje' =&gt; $Opinion-&gt;mensaje\n                ];\n                $data&#91;] = $types;\n            }\n        }\n\n        if($data)\n        {\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; 200,\n                'response' =&gt; 'OK',\n                'data' =&gt; $data\n            ], 200);\n        }\n        else\n        {\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; 404,\n                'response' =&gt; 'Not Found',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; 'Error-2',    \n                    'errorMessage' =&gt; 'Opinions was not found'\n                ]\n            ], 404);\n        }\n    }\n    public function show($id){\n        try\n        {\n            $Opinion = Opinion::where('id', $id)-&gt;first();\n        }\n        catch (Exception $e)\n        {\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; '500',\n                'response' =&gt; 'Internal Server Error',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; 'Error-1',\n                    \/\/\"exception\" =&gt; $e-&gt;getMessage(),\n                    'errorMessage' =&gt; 'Error getting Opinions'\n                ]\n            ], 500);\n        }\n        if($Opinion)\n        {\n            $data = &#91;];\n            $data = &#91;\n                'id' =&gt; $Opinion-&gt;id,\n                'nombre' =&gt; $Opinion-&gt;nombre,\n                'email' =&gt; $Opinion-&gt;email,\n                'id_post' =&gt; $Opinion-&gt;id_post,\n                'mensaje' =&gt; $Opinion-&gt;mensaje\n            ];\n        }\n\n        if($data)\n        {\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; 200,\n                'response' =&gt; 'OK',\n                'data' =&gt; $data\n            ], 200);\n        }\n        else\n        {\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; 404,\n                'response' =&gt; 'Not Found',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; 'Error-2',    \n                    'errorMessage' =&gt; 'Opinion was not found'\n                ]\n            ], 404);\n        }\n    }\n    public function store(Request $request){\n        $data = new Opinion();\n        if($request-&gt;input('nombre')){\n            $data-&gt;nombre = $request-&gt;input('nombre');\n        }else{\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; '422',\n                'response' =&gt; 'Validation Error',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; '001',\n                    'error' =&gt; 'Nombre no puede estar vacio'\n                ]\n            ], 422);\n        }\n        if($request-&gt;input('email')){\n            $data-&gt;email = $request-&gt;input('email');\n        }else{\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; '422',\n                'response' =&gt; 'Validation Error',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; '002',\n                    'error' =&gt; 'Email no puede estar vacio'\n                ]\n            ], 422);\n        }\n        if($request-&gt;input('mensaje')){\n            $data-&gt;mensaje = $request-&gt;input('mensaje');\n        }else{\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; '422',\n                'response' =&gt; 'Validation Error',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; '003',\n                    'error' =&gt; 'mensaje no puede estar vacio'\n                ]\n            ], 422);\n        }\n        try \n        {\n            $data-&gt;save();\n            return response()-&gt;json(&#91;'responseCode' =&gt; 200, 'response' =&gt; 'OK', 'data' =&gt; $data], 200); \n        } \n        catch (Exception $e) \n        {\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; '500',\n                'response' =&gt; 'Internal Server Error',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; 'Error-1',\n                    \/\/\"exception\" =&gt; $e-&gt;getMessage(),\n                    'errorMessage' =&gt; 'Error storing Opinions'\n                ]\n            ], 500);\n        }\n    }\n    public function update($id, Request $request){\n        try\n        {\n            $data = Opinion::where('id',$id)-&gt;first();\n        }\n        catch (Exception $e)\n        {\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; '500',\n                'response' =&gt; 'Internal Server Error',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; 'Error-1',\n                    \/\/\"exception\" =&gt; $e-&gt;getMessage(),\n                    'errorMessage' =&gt; 'Error getting Opinions'\n                ]\n            ], 500);\n        }\n        if($request-&gt;input('nombre')){\n            $data-&gt;nombre = $request-&gt;input('nombre');\n        }else{\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; '422',\n                'response' =&gt; 'Validation Error',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; '001',\n                    'error' =&gt; 'Nombre no puede estar vacio'\n                ]\n            ], 422);\n        }\n        if($request-&gt;input('email')){\n            $data-&gt;email = $request-&gt;input('email');\n        }else{\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; '422',\n                'response' =&gt; 'Validation Error',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; '002',\n                    'error' =&gt; 'Email no puede estar vacio'\n                ]\n            ], 422);\n        }\n        if($request-&gt;input('mensaje')){\n            $data-&gt;mensaje = $request-&gt;input('mensaje');\n        }else{\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; '422',\n                'response' =&gt; 'Validation Error',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; '003',\n                    'error' =&gt; 'mensaje no puede estar vacio'\n                ]\n            ], 422);\n        }\n        try \n        {\n            $data-&gt;save();\n            return response()-&gt;json(&#91;'responseCode' =&gt; 200, 'response' =&gt; 'OK', 'data' =&gt; $data], 200); \n        } \n        catch (Exception $e) \n        {\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; '500',\n                'response' =&gt; 'Internal Server Error',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; 'Error-1',\n                    \/\/\"exception\" =&gt; $e-&gt;getMessage(),\n                    'errorMessage' =&gt; 'Error updating Opinions'\n                ]\n            ], 500);\n        }\n    }\n    public function destroy($id){\n        try\n        {\n            $data = Opinion::where('id',$id)-&gt;first();\n        }\n        catch (Exception $e)\n        {\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; '500',\n                'response' =&gt; 'Internal Server Error',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; 'Error-1',\n                    \/\/\"exception\" =&gt; $e-&gt;getMessage(),\n                    'errorMessage' =&gt; 'Error getting Opinion'\n                ]\n            ], 500);\n        }\n        try \n        {\n            $data-&gt;delete();\n            return response()-&gt;json(&#91;'responseCode' =&gt; 200, 'response' =&gt; 'OK', 'data' =&gt; $data], 200); \n        } \n        catch (Exception $e) \n        {\n            return response()-&gt;json(&#91;\n                'responseCode' =&gt; '500',\n                'response' =&gt; 'Internal Server Error',\n                'data' =&gt; &#91;\n                    'errorCode' =&gt; 'Error-1',\n                    \/\/\"exception\" =&gt; $e-&gt;getMessage(),\n                    'errorMessage' =&gt; 'Error deleting Opinion'\n                ]\n            ], 500);\n        }\n    }\n}<\/code><\/pre>\n\n\n<h3>Paso 9<\/h3>\n<p>Editamos el archivo routes\/web.php y agregamos las rutas de la siguiente manera:<\/p>\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\n\/** @var \\Laravel\\Lumen\\Routing\\Router $router *\/\n\n\/*\n|--------------------------------------------------------------------------\n| Application Routes\n|--------------------------------------------------------------------------\n|\n| Here is where you can register all of the routes for an application.\n| It is a breeze. Simply tell Lumen the URIs it should respond to\n| and give it the Closure to call when that URI is requested.\n|\n*\/\n\n$router-&gt;get('\/', function () use ($router) {\n    return $router-&gt;app-&gt;version();\n});\n\n$router-&gt;group(&#91;'prefix' =&gt; 'api'], function () use ($router) {\n\n  $router-&gt;get('opinion\/all', &#91;'uses' =&gt; 'OpinionController@index']);\n  $router-&gt;get('opinion\/{id}', &#91;'uses' =&gt; 'OpinionController@show']);\n  $router-&gt;post('opinion', &#91;'uses' =&gt; 'OpinionController@store']);\n  $router-&gt;put('opinion\/{id}', &#91;'uses' =&gt; 'OpinionController@update']);\n  $router-&gt;delete('opinion\/{id}', &#91;'uses' =&gt; 'OpinionController@destroy']);\n\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Proceso de instalacion paso a paso de un backend sencillo de una sola tabla de base de datos usando PHP framework Laravel Lumen version 10: Requisito previo obviamente en para este tutorial, tener Linux + Apache Server + PHP &gt; 8.0 y Mysql server o Postgresql. Ademas, Laravel Lumen requiere que tengas instaladas de las [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/robetorr.com\/index.php\/wp-json\/wp\/v2\/posts\/199"}],"collection":[{"href":"https:\/\/robetorr.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/robetorr.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/robetorr.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/robetorr.com\/index.php\/wp-json\/wp\/v2\/comments?post=199"}],"version-history":[{"count":4,"href":"https:\/\/robetorr.com\/index.php\/wp-json\/wp\/v2\/posts\/199\/revisions"}],"predecessor-version":[{"id":203,"href":"https:\/\/robetorr.com\/index.php\/wp-json\/wp\/v2\/posts\/199\/revisions\/203"}],"wp:attachment":[{"href":"https:\/\/robetorr.com\/index.php\/wp-json\/wp\/v2\/media?parent=199"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/robetorr.com\/index.php\/wp-json\/wp\/v2\/categories?post=199"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/robetorr.com\/index.php\/wp-json\/wp\/v2\/tags?post=199"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}