Lumen is the best PHP framework to build the Restful API. Lumen was developed by Taylor Otwell, the developer behind the most popular PHP framework today, Laravel. We could say, the Lumen Framework is a derivative of Laravel. The following tutorial will discuss, what is Lumen? and the tutorial to create a restful API using Lumen 5.5.
If previously I discussed the article about the Slim framework, Lumen has the same goal, which is a micro-framework tasked to build APIs easily, quickly and efficiently. Besides, Lumen can handle 1900 requests per second like the picture below.
The advantages of Lumen framework itself in my experience are:
- Many features such as middleware authentication.
- Strong MVC concept.
- Migrate and eloquent features that speed up the creation and query of databases
Many people say that Laravel is a heavy PHP framework, but Lumen is created with speed and simplify of the features in Laravel. In this article, we will prove how quickly and easily make the API use Lumen Framework.
Another tutorial : How To Load All Data Before Rendering View Component In Angular 4
Table of Contents
Prepare to create a web API with lumen 5.5
System Requirement
Before starting the creation of the API, there are some requirements that must be fulfilled, so that Lumen framework 5.5 runs well on the server
- PHP 7.0
- OpenSSL PHP Extension
- PDO PHP Extension
- Mbstring PHP Extension
Installation
To install Lumen is quite easy, using a composer you just need to run the following script
1 | composer create-project --prefer-dist laravel/lumen lumenapi |
Configuration
Before running Lumen, there are some configurations in the .env file that must be adjusted. Open the .env file, while the default file is as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | APP_ENV=local APP_DEBUG=true APP_KEY=VUEdpbKOpVlP4817 APP_TIMEZONE=Asia/Jakarta DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=your-db-name DB_USERNAME=your-db-user DB_PASSWORD=your-db-password CACHE_DRIVER=file QUEUE_DRIVER=sync |
Unlike Laravel, APP_KEY has not filled automatically. You can fill APP_KEY manually.
Then the APP_TIMEZONE option. Adjust to the time zone of application used. I am as an Indonesian developer using timezone “Asia/Jakarta.” You can see the timezone list here.
Lumen Early Installation Test
Lumen does not provide tools to run a built-in web server like Laravel (PHP artisan serve). We can use the built-in web server directly with PHP.
1 | $ PHP -S localhost:8888 -t public |
or you can copy the entire Lumen project into the HTML (/var/www/html/) or htdocs folder (inside the XAMPP folder) and run it as usual.
1 | http://ipaddress/lumenproject/public/ |
Till this step, the preparation of the Web API using the Lumen 5.5 framework has been completed. The next step we create a simple REST API Lumen where the API server used for new user registration, login application and get API_TOKEN to retrieve user’s data using token authentication.
Creating a Simple REST API Using the Lumen 5.5 Framework For Beginners
Please edit the boostrap / app.php file. We will activate the auth and eloquent feature. Eliminate some comments in the app.php like the following:
1 2 3 4 5 6 | $app->withFacades(); $app->withEloquent(); $app->routeMiddleware([ 'auth' => App\Http\Middleware\Authenticate::class, ]); $app->register(App\Providers\AuthServiceProvider::class); |
By default, the Facades and Eloquent features are removed so that Lumen can work faster.
Migration Lumen
Database migration is one of the features to create database schema quickly and easily. For the simple application of REST API, we will create schema table for the user.
1 | php artisan make:migration create_users_table --create=users |
Make sure the file formed like the following image in the folder database/migrations/
Edit the above file and add the following schema:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('username'); $table->string('email')->unique(); $table->string('password'); $table->string('api_token'); $table->rememberToken(); $table->timestamps(); $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } } |
When done, migrate with the following command:
1 | php artisan migrate |
Check your database through phpmyadmin and make sure the user’s table has been established
Creating a Model in the Lumen 5.5 Framework
After creating the migration automatically, then the model for the user has been formed in the folder /app/User.php . To understand more about the model, please read at https://laravel.com/docs/5.5/eloquent. Make sure the User configuration is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?php namespace App; use Illuminate\Auth\Authenticatable; use Laravel\Lumen\Auth\Authorizable; use Illuminate\Database\Eloquent\Model; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract; class User extends Model implements AuthenticatableContract, AuthorizableContract { use Authenticatable, Authorizable; protected $fillable = [ 'username', 'email', 'password', 'api_token' ]; protected $hidden = [ 'password','api_token' ]; } |
Explanation:
In Lumen Laravel, there are some special variables used to configure table settings in the database. As the example above is the variable $fillable , $hidden . And much more like $primaryKey , $timestamps that you can read at https://laravel.com/docs/5.5/eloquent.
- $fillable is a variable that serves to grant any column permissions from this users’ table that we can use.
- $hidden works to prevent specific fields from being displayed when we run the query to get all data from columns in table users.
Creating a Controller In Lumen Framework
Unfortunately, lumen laravel doesn’t provide php artisan feature to make the controller file automatically. So we create the controller manually. The lumen controller works as well as Laravel to build the business logic on the application.
Although lumen does not provide the feature of creating the controller automatically, Lumen provides exampleController.php which can be used as a mock-up to create a new controller.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Validation\ValidationException; use App\User; class UserController extends Controller { public function register(Request $request) { $rules = [ 'username' => 'required', 'email' => 'required', 'password' => 'required', ]; $customMessages = [ 'required' => 'Please fill attribute :attribute' ]; $this->validate($request, $rules, $customMessages); try { $hasher = app()->make('hash'); $username = $request->input('username'); $email = $request->input('email'); $password = $hasher->make($request->input('password')); $save = User::create([ 'username'=> $username, 'email'=> $email, 'password'=> $password, 'api_token'=> '' ]); $res['status'] = true; $res['message'] = 'Registration success!'; return response($res, 200); } catch (\Illuminate\Database\QueryException $ex) { $res['status'] = false; $res['message'] = $ex->getMessage(); return response($res, 500); } } public function get_user() { $user = User::all(); if ($user) { $res['status'] = true; $res['message'] = $user; return response($res); }else{ $res['status'] = false; $res['message'] = 'Cannot find user!'; return response($res); } } } |
Add the code below in the Controller.php in the folder /app/Http/Controllers/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Validation\ValidationException; use Laravel\Lumen\Routing\Controller as BaseController; class Controller extends BaseController { protected function buildFailedValidationResponse(Request $request, array $errors) { return response(["success"=> false , "message" => $errors],401); } } |
A brief description:
The above code, we create the registration function in the UserController class. The registration method used to register the new user.
1 2 3 4 5 6 7 8 9 10 | $rules = [ 'username' => 'required', 'email' => 'required', 'password' => 'required', ]; $customMessages = [ 'required' => 'Please fill attribute :attribute' ]; $this->validate($request, $rules, $customMessages); |
Before the new user created, Lumen will validate the parameters needed to register the new user.
To get the return response as a JSON format in the Lumen validation function, we can inject the buildFailedValidationResponse function in the Controller.php in the /app/Http/Controllers/ folder. The Controller.php file is the parent class of the UserController that we created.
1 2 3 4 5 6 7 | try { // query code here } catch (\Illuminate\Database\QueryException $ex) { //return response if fails here } |
The next step is create the LoginController.php which used as a login controller. Copy the following code in the LoginController.php.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Validation\ValidationException; use Illuminate\Support\Facades\Hash; use App\User; class LoginController extends Controller { public function login(Request $request) { $rules = [ 'email' => 'required', 'password' => 'required' ]; $customMessages = [ 'required' => ':attribute tidak boleh kosong' ]; $this->validate($request, $rules, $customMessages); $email = $request->input('email'); try { $login = User::where('email', $email)->first(); if ($login) { if ($login->count() > 0) { if (Hash::check($request->input('password'), $login->password)) { try { $api_token = sha1($login->id_user.time()); $create_token = User::where('id', $login->id_user)->update(['api_token' => $api_token]); $res['status'] = true; $res['message'] = 'Success login'; $res['data'] = $login; $res['api_token'] = $api_token; return response($res, 200); } catch (\Illuminate\Database\QueryException $ex) { $res['status'] = false; $res['message'] = $ex->getMessage(); return response($res, 500); } } else { $res['success'] = false; $res['message'] = 'Username / email / password not found'; return response($res, 401); } } else { $res['success'] = false; $res['message'] = 'Username / email / password not found'; return response($res, 401); } } else { $res['success'] = false; $res['message'] = 'Username / email / password not found'; return response($res, 401); } } catch (\Illuminate\Database\QueryException $ex) { $res['success'] = false; $res['message'] = $ex->getMessage(); return response($res, 500); } } } |
A brief description :
The Users will login in the application using the email name. The server will checks whether the user’s email has been registered in the database or not.
1 | $login = User::where('email', $email)->first(); |
If the email has registered, Lumen would check whether the password recorded on the database is the same as the password sent by the user from the following function:
1 | if (Hash::check($request->input('password'), $login->password)) |
If the login has been successful, the lumen server will establish a new token (lumen auth) to be updated into the database and returned it as a response.
Creating a Lumen Framework Routing
The Route in the Lumen laravel framework is located in the routes/web.php file. Please copy the following code on web.php:
1 2 3 4 5 6 7 | <?php $router->get('/', function () use ($router) { return $router->app->version(); }); $router->post('/login', 'LoginController@login'); $router->post('/register', 'UserController@register'); $router->get('/user', ['middleware' => 'auth', 'uses' => 'UserController@get_user']); |
API Token validation with Middleware
According to the Laravel official site, HTTP middleware is
HTTP middleware provides a convenient mechanism for filtering HTTP requests entering your application
So, the middleware authentication is a function that runs before the client request gets into the controller. Middleware will check whether the user has permission to access the API.
1 2 3 4 | $app->routeMiddleware([ 'auth' => App\Http\Middleware\Authenticate::class, ]); $app->register(App\Providers\AuthServiceProvider::class); |
We have enabled Authenticate middleware in the initial configuration above on the bootstrap/app.php file.
The next step, add the following authentication code in authentication middleware in the app/Http/Middleware/Authenticate.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <?php namespace App\Http\Middleware; use Closure; use Illuminate\Contracts\Auth\Factory as Auth; use App\User; class Authenticate { protected $auth; public function __construct(Auth $auth) { $this->auth = $auth; } public function handle($request, Closure $next, $guard = null) { if ($this->auth->guard($guard)->guest()) { if ($request->has('api_token')) { try { $token = $request->input('api_token'); $check_token = User::where('api_token', $token)->first(); if ($check_token) { $res['status'] = false; $res['message'] = 'Unauthorize'; return response($res, 401); } } catch (\Illuminate\Database\QueryException $ex) { $res['status'] = false; $res['message'] = $ex->getMessage(); return response($res, 500); } } else { $res['status'] = false; $res['message'] = 'Login please!'; return response($res, 401); } } return $next($request); } } |
Up to this point the creation of REST API Using Lumen 5.5 For beginners has been completed, the next step is testing API
Testing Lumen Rest API using POSTMAN
User registration
Login user
Get all user with api_token
Conclusion Using Lumen Laravel
Lumen Laravel is the best Rest API framework I have ever used, the reason is:
- Easy & Complete Documentation
- Open Source
- MVC Architecture
- Has a Migration Feature
- Security
- Large Community
Lumen was created by Laravel developers to accommodate the needs of developers who want to develop applications on a smaller scale than Laravel. Because many libraries were removed in Laravel Lumen, Lumen can be used as a framework for creating REST APIs.
Unfortunately, Lumen Laravel only runs on PHP version 7 and above. But things aren’t an obstacle, but instead, we are forced to work better on PHP7.
In terms of security, you don’t need to worry, we can implement middleware authentication to block unknown access.
Okay, its finished, tutorial lumen 5.5 for beginners has been completed, to download the full project please use the following link
Bonus Lumen Example
Thus my tutorial about Restful API Tutorial With Lumen Laravel 5.5 For Beginners, Hopefully useful
Great post! Managed to get this all up and running, going to attempt to build a headless blog with an admin publisher route.
I did spot an error in your code after some trial and error. Your api_token update statement on login uses $login->id_user when it should use $login->id
Hope this helps.
There is an error on the file Authenticate.php
The line : if ($check_token) {
Must be: if (!$check_token) {
Or any token will works.
this project is wery good but you can call api_token null
http://localhost:8888/user?api_token url so gives user data
so you can solve this bug & re update
here we go https://seegatesite.com/tutorial-crud-client-and-api-server-using-jquery-and-lumen-part-1/
First of all Thankyou for this wonderful Code but I got error when i run api for get user list
Function name must be a string
check your function name in contoller…dont use number