Creating A REST API With Lumen

In this post, we will learn how you can easily create a simple REST API using Lumen. To illustrate this API, we'll create a Products table, and then perform CRUD Operations. If you don't know how to install the Lumen, then please read this POST: Lumen Installation

For this tutorial, we're going to use PHP-7.1 and Lumen-5.5.2. We're also going to use a MySQL database.

MySQL Connection 

As you know Lumen stores all the configuration options in .env file. We need to add the database configuration details in our .env file. Here, my database name is: lumen_tutorial, database username is : root and database password is : root, you might have different values for these variables, so change it accordingly.

APP_ENV=local
APP_DEBUG=true
APP_KEY=ae2783e1a58024cd21d154c0a2d48789
APP_TIMEZONE=UTC
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=lumen_tutorial
DB_USERNAME=root
DB_PASSWORD=root
CACHE_DRIVER=file
QUEUE_DRIVER=sync

Now open up bootstrap/app.php and find the following lines:

//$app->withFacades();
//$app->withEloquent();

Uncomment them and now our app hookup Eloquent to the database that we've configured in our .env file.

The Facade class is a static interface to classes available in the application’s service containers. This class is required to access certain core components of Lumen. Eloquent is the ORM that is used  communicate with the MySQL database.

Migration

It's time to create the database schema. Create a table for Products with four fields including the auto-increment id. The other three fields are name, description, status, created_at and updated_at. To create the table, run:

php artisan make:migration create_table_products --create=products

This will create a <date>_create_table_products.php file inside the database/migrations/ folder. I will now edit this file and define the table.

Schema::create('products', function (Blueprint $table) {
  $table->increments('id');
  $table->string('name');
  $table->string('description');
  $table->smallInteger('status');
  $table->dateTime('created_at');
  $table->dateTime('updated_at')->nullable();
});

The up function will be triggered when the table is actually created during the migration. The down function (no changes required in this function) will delete the table if the need arises. Now run the migration using:

php artisan migrate

you will see the below type of messages.

Migration table created successfully.
Migrating: 2018_01_11_110420_create_table_products
Migrated:  2018_01_11_110420_create_table_products

At this point, the table has been created and can be viewed in MySQL manager.

Making Model

Next step is the creation of the model. Create the app/Product.php file and add the following code:

<?php 

namespace App;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{ 
   protected $fillable = ['name', 'description', 'status'];  
}

?>

Making Controller

Create a controller inside the app/Http/Controllers/ProductController.php.

<?php

namespace App\Http\Controllers;

use App\Product;
use Illuminate\Http\Request;

class ProductController extends Controller{

 public function store(Request $request){
     $product = Product::create($request->all());

     return response()->json($product);
 }
}
?>

Making Routes

Now all that remains is the addition of the routes. I will write routes for creating, updating, deleting and viewing products. Open up app/Http/routes.php and add the following route.

// all the routes related to Product module
$router->group(['prefix' => 'api/v1/product/'], function($router)
{
      $router->post('create','ProductController@store');
});

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

Testing the API

For this I will be using Postman you can use any REST Client. So open postman. And write a URL. In my case the BASE URL is localhost/lumen-exception/public/ and we will add what we created after this. So let's test create product first, for this put the URL in postman, select request type as POST and add required parameters. (You can take help from the below screenshot).

When  we click Send, the values are being stored in products table. You can call this API multiple times with different values so we have enough data in our product table. Here, I have created approx 10 records using this API, you can create as your wish.

So upto this we have successfully created one api for creating a Product. Now we will create other apis of CRUD operations.

 

Get All the Products

Open the ProductController and add the below code:

public function index(Request $request)
{
    $products = Product::all();
    return response()->json($products);     
}

After adding above lines in controller, open route file which is web.php in which we already have defined one route. Add a new route for getting all the products:

$router->get('all','ProductController@index');

Now we have two routes for two actions like:

// all the routes related to Product module
$router->group(['prefix' => 'api/v1/product/'], function($router)
{
    $router->get('all','ProductController@index');
    $router->post('create','ProductController@store');
});

Go to Postman, enter the URL as : http://localhost/lumen-exception/public/api/v1/product/all  and set the API method as GET. You can see its returning all the products records.

 

Get Single Product

Open the ProductController and add the below code:

public function getProduct($id){
    $product  = Product::find($id);
    return response()->json($product);
}

Add a new route for getting particular product:

$router->get('{id}','ProductController@getProduct');

Now we have three routes:

// all the routes related to Product module 
$router->group(['prefix' => 'api/v1/product/'], function($router)
{
      $router->get('all','ProductController@index');
      $router->get('{id}','ProductController@getProduct');     
      $router->post('create','ProductController@store');
}); 

Go to Postman, enter the URL as : http://localhost/lumen-exception/public/api/v1/product/1  and set the API method as GET. You can see its returning the product with passed id:1

 

Update a Product

Open the ProductController and add the below code:

public function updateProduct(Request $request, $id)
{
    $product              = Product::find($id);
    $product->name        = $request->input('name');
    $product->description = $request->input('description');
    $product->status      = $request->input('status');
    $product->save();
    return response()->json($product);   
}

Now we have four routes:

// all the routes related to Product module 
$router->group(['prefix' => 'api/v1/product/'], function($router)
{
     $router->get('all','ProductController@index');
     $router->get('{id}','ProductController@getProduct');     
     $router->post('create','ProductController@store');
     $router->put('update/{id}','ProductController@updateProduct');    
});

Go to Postman, enter the URL as : http://localhost/lumen-exception/public/api/v1/product/update/1 and set the API method as PUT. You can see the record is updated with new values.

 

Delete a Product

Open the ProductController and add the below code:

public function deleteProduct($id){
    $product  = Product::find($id);
    $product->delete();
    return response()->json('product deleted');
}

Now we have five routes:

// all the routes related to Product module 
$router->group(['prefix' => 'api/v1/product/'], function($router)
{
     $router->get('all','ProductController@index');
     $router->get('{id}','ProductController@getProduct');     
     $router->post('create','ProductController@store');
     $router->put('update/{id}','ProductController@updateProduct');
     $router->delete('delete/{id}','ProductController@deleteProduct');    
});

Go to Postman, enter the URL as : http://localhost/lumen-exception/public/api/v1/product/delete/1 and set the API method as DELETE. You can see the record is deleted. Below is complete file of controller:
 

<?php
 
namespace App\Http\Controllers;
 
use App\Product;
use Illuminate\Http\Request;
 
class ProductController extends Controller{

 public function store(Request $request){
     $product = Product::create($request->all());
     return response()->json($product);
 }
 
 public function index(Request $request)
    {
        $products = Product::all();
        return response()->json($products);     
    }
 
 public function getProduct($id){
        $product  = Product::find($id);
        return response()->json($product);
    }
 
 public function updateProduct(Request $request, $id)
    {
        $product              = Product::find($id);
        $product->name        = $request->input('name');
        $product->description = $request->input('description');
        $product->status      = $request->input('status');
        $product->save();
        return response()->json($product);   
    }
 
 public function deleteProduct($id){
        $product  = Product::find($id);
        $product->delete();
        return response()->json('product deleted');
    }
}
?>