lumen

Lumen is a “micro-framework” built on top of Laravel’s components created by Taylor Otwell who is also responsible for Laravel.

It has been designed to develop micro services like small application or web service. It has been developed for speed. In Lumen Symfony’s Routing component which has been used by Laravel replaced by FastRoute to enhance performance. You can check more cool features here.

In this tutorial, we’ll implement a simple RESTful API. This API based on storing and showing book information.

Installing Lumen

We’ll install lumen through Composer, So the first check is composer installed or not? Using following command in your terminal or command prompt.

composer

If you able to see some composer commands feel free to proceed otherwise take a look this easy composer tutorial.

After installing composer, we’ll change our directory to server root folder.

cd /var/www/html

Now tell composer to create a lumen project “lumen_rest_ce” from “laravel/lumen” package (packagist.org).

composer create-project laravel/lumen lumen_rest_ce

Composer will create a folder “lumen_rest_ce” and install all files of lumen including dependency.

You can check all artisan command which are available in Lumen by

php artisan

Now run Lumen on your local server and open localhost:8000 in your browser

php artisan serve

lumen

If you’ll able to see above image on your browser. Cool !!!

Configuration

Now create a database in your phpmyadmin or other mysql client and edit the credential “lumen_rest_ce/.env.example” file to “lumen_rest_ce/.env”

1
2
3
4
5
DB_CONNECTION=mysql
DB_HOST=localhost
DB_DATABASE=lumen_rest_ce
DB_USERNAME=root
DB_PASSWORD=your_password

Now open “lumen_rest_ce/bootstrap/app.php” and uncomment following lines.

1
2
3
4
5
6
Dotenv::load(__DIR__.'/../'); 
  
$app->withFacades();
  
$app->withEloquent();

First we are fetching credential from .env file and then we’ll use Facade class and Elequent ORM.

Migration

Its time to write our database schema for migration, we’ll create table “books” which has total 6 columns. id (int & auto incremented), title ( varchar), author (varchar), isbn (varchar) , created_at (timestamp) and updated_at (timestamp).

We’ll use migration which is revision manager for the database like svn or git.

In your terminal/command prompt write

php artisan make:migration create_books_table –create=books

It will create a migration file under “database/migration”. Open the file, you’ll find “CreateBooksTable” class has been created, this class has two method one is “up” where we’ll write our table schema, another is “down”, where we’ll drop our table which will call at the time of rollback.

Now edit this migration file like this:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
 
class CreateBooksTable extends Migration {
 
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('books', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('title');
            $table->string('author');
            $table->string('isbn');
            $table->timestamps();
        });
    }
 
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('books');
    }
 
}

To create the table in your database, we have to migrate or run our migration file

php artisan migrate

A table has been created in your database.

Model

Now create a Book model under “app/Book.php” and use book table instance.

01
02
03
04
05
06
07
08
09
10
11
<?php namespace App;
  
use Illuminate\Database\Eloquent\Model;
  
class Book extends Model
{
     
     protected $fillable = ['title', 'author', 'isbn'];
     
}
?>

Also create a BookController.php under “app/Http/Controllers”.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<?php
  
namespace App\Http\Controllers;
  
use App\Book;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
  
  
class BookController extends Controller{
  
 .....
 .....
 
}
?>

Route

Now open “app/Http/routes.php” , you’ll file one routed already exists.

1
2
$app->get('/', function() use ($app) {
..

We need write some more routes and corresponding Controller method in order to create RESTful API.

MethodUrlControler@method 
GEThttp://localhost:8000/api/v1/bookBookController@indexAll Books
GEThttp://localhost:8000/api/v1/book{id}BookController@getbookFetch Book By id
POSThttp://localhost:8000/api/v1/bookBookController@createBookCreate a book record
PUThttp://localhost:8000/api/v1/book{id}BookController@updateBookUpdate Book By id
DELETEhttp://localhost:8000/api/v1/book{id}BookController@deleteBookDelete Book By id

we have appended api/v1 (ie, version v1) in all routes. It’s a good practice in order to create web services.

So now our routes.php will be like

01
02
03
04
05
06
07
08
09
10
11
12
13
14
$app->get('/', function() use ($app) {
    return "Lumen RESTful API By CoderExample (https://coderexample.com)";
});
 
 
$app->get('api/v1/book','App\Http\Controllers\BookController@index');
 
$app->get('api/v1/book/{id}','App\Http\Controllers\BookController@getbook');
 
$app->post('api/v1/book','App\Http\Controllers\BookController@createBook');
 
$app->put('api/v1/book/{id}','App\Http\Controllers\BookController@updateBook');
 
$app->delete('api/v1/book/{id}','App\Http\Controllers\BookController@deleteBook');

Yes we can group this routes according to prefix and namespaces , So we dont have to append “api/v1” in every routes or write “App\Http\Controllers”.

Here is is our modified routes.php

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
$app->get('/', function() use ($app) {
    return "Lumen RESTful API By CoderExample (https://coderexample.com)";
});
 
$app->group(['prefix' => 'api/v1','namespace' => 'App\Http\Controllers'], function($app)
{
    $app->get('book','BookController@index');
  
    $app->get('book/{id}','BookController@getbook');
      
    $app->post('book','BookController@createBook');
      
    $app->put('book/{id}','BookController@updateBook');
      
    $app->delete('book/{id}','BookController@deleteBook');
});

Controller

Now edit BookController.php and according to routes implement those method.

Here is our Modified BookController.php

01
02
03
04
05
06
07
08
09
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
<?php
  
namespace App\Http\Controllers;
  
use App\Book;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
  
  
class BookController extends Controller{
  
  
    public function index(){
  
        $Books  = Book::all();
  
        return response()->json($Books);
  
    }
  
    public function getBook($id){
  
        $Book  = Book::find($id);
  
        return response()->json($Book);
    }
  
    public function createBook(Request $request){
  
        $Book = Book::create($request->all());
  
        return response()->json($Book);
  
    }
  
    public function deleteBook($id){
        $Book  = Book::find($id);
        $Book->delete();
 
        return response()->json('deleted');
    }
  
    public function updateBook(Request $request,$id){
        $Book  = Book::find($id);
        $Book->title = $request->input('title');
        $Book->author = $request->input('author');
        $Book->isbn = $request->input('isbn');
        $Book->save();
  
        return response()->json($Book);
    }
  
}

Testing

Now your API is ready. Its time tests the app. For testing, you can use CURL.

1
2
3
4
5
6
7
8
9
 
curl -v -H "Accept:application/json" http://localhost:8000/api/v1/book/2
 
curl -i -X POST -H &quot;Content-Type:application/json&quot; http://localhost:8000/api/v1/book -d '{&quot;title&quot;:&quot;Test Title&quot;,&quot;author&quot;:&quot;test author&quot;,&quot;isbn&quot;:&quot;12345&quot;}'
 
curl -v -H "Content-Type:application/json" -X PUT http://localhost:8000/api/v1/book -d '{"title":"Test updated title","author":"test upadted author","isbn":"1234567"}'
 

I found a chrome extension “POSTMAN” to test RESTful apis easy way.

After installing “POSTMAN” open it typing “chrome://apps/” in your chrome address bar.

Postman

Conclusion

That’s all. Our basic API is tested now. Though it’s not production ready example, for production we need to consider authentication, validation, error handling and much more other stuff.

Source Code is available in Github just clone/download into your server and run “composer install” to download all dependencies.

In coderexample we’ll be posting some more interesting post about Lumen and Laravel 5. keep in touch and spread the post if possible. Feel free to comment your queries.