RESTful API in Lumen, A Laravel Micro Framework

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”

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.

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:


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.


<?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”.


<?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.

$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


$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


$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


<?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.


curl -I http://localhost:8000/api/v1/book

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"}'

curl -i -X DELETE http://localhost:8000/api/v1/book/2

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.

DownloadGithub


  • Brian garcia

    php artisan make:controller is not working.

    • currently make controller is not available in artisan command for lumen, you can check available commands by

      php artisan

  • Richard Forbes

    Correction:
    php artisan make:migration create_books_table –create=books, left off a ‘-‘

  • Muktar Ajad

    Very easy post. My first tutorial in Lumen and like it.

  • Mubashar Sheikh

    Hi i have to upload my Lumen project on 1and1 server can you please help me to upload it step by step 🙂

  • rahul

    can anyone tell how to call a lumen api from a external source .
    or from a different laravel project without using curl.
    My other approach is what if i want to use lumen along sidemy laravel project .?

  • Aneudy Amparo

    Gracias!!!

  • Loc Dai Le

    I’m new to php and larval framework.

    public function getBook($id){

    $Book = Book::find($id);

    return response()->json($Book);

    }

    Is Book::find($id); a function call? If it is then where is it declared and implemented?

    • Rogério Tadim

      yes, it is.

      It is implemented within Model class once Book extends Model.

  • kosh

    cd /var/www/html ….there is a step missing in your tutorial…this folder does not exist on my mac be default. what step is needed to serve html files from this location?

    • from which directory you serve the server side files? check in your mac and use that path.

      • kosh

        Need instructions for setting up this folder “/var/www/html”

        • Yudha Wijaya

          mac: /Library/WebServer/Documents

  • Rogério Tadim

    when a execute “php artisan” I get:

    PHP Fatal error: Class ‘PDO’ not found in /home/users/balakiii/lumen_rest_ce/vendor/laravel/lumen-framework/config/database.php on line 16

    [SymfonyComponentDebugExceptionFatalErrorException]
    Class ‘PDO’ not found

    Any idea?

    • Rogério Tadim

      just install php-mysql… lol

    • Kepro

      rly? utfg

    • oliveirarthur

      Is php-pear installed?

  • Luis Barral

    just perfect dude! thx!

  • Deniz

    This article is not about securing the API, it’s about getting it up and running.

  • san

    I am getting error internal server error while calling the route “http://localhost:8000/api/v1/book/”

    • Novri Oov Auliansyah

      if you want to see information book on database, please try to call “http://localhost:8000/api/v1/books”.
      please see on routes: $app->post(‘book’,’BookController@createBook’); its for create new one.
      🙂

  • Eder Weiß

    En Lumen 5.3.0 el comando php artisan serve ha sido removido, asi que podemos usar lo siguiente desde la terminal ubicados dentro de la carpeta de nuestro proyecto:

    php -S localhost:8000 -t ./public

  • somecoolguy

    Hi,

    Very easy to follow tutorial. But I can’t get routes to be opened. consider:

    $app->get(‘/’, function() use ($app) {
    return “Lumen RESTful API By CoderExample (https://coderexample.com)”;
    });

    $app->get(‘admin’, function() use ($app){
    return “admin”;
    });

    the root / path works, but the admin doesn’t. In fact no other route seem to work except /

    • try this

      “`
      $app->get(‘/admin’, function() use ($app){
      return “admin”;
      });
      “`

      this will work

  • Rutika Dabholkar

    i got dis error when i used the following command

    “php artisan”

    Fatal error: Class ‘Memcached’ not found in C:xampphtdocslumen_rest_cevendor
    illuminatecacheMemcachedConnector.php on line 72

    [SymfonyComponentDebugExceptionFatalErrorException]
    Class ‘Memcached’ not found

    any idea????

  • oleg sapishchuk

    You created Lumen API, but not Lumen REST API. REST APIs must be hypertext-driven. It means that you are building URIs from templates in documentation and not getting links in the resource representations, that’s not REST.
    Any way good to read something new.

  • Ting Zhong Loou

    php artisan make:migration create_books_table –create=books
    ,
    –create=books, “–” is right!

  • Novri Oov Auliansyah
  • hasan hasibul

    Use this boilerplate for creating RESTFul api with Lumen. Features included: OAuth2 Authentication, Authorization, Fractal, Repository Pattern, CORS Support, Endpoint Testing, Unit Testing, Build Process and many more. https://github.com/hasib32/rest-api-with-lumen