Simple CRUD REST API With Lumen + MySQL + Eloquent ORM
Tags: php, laravel, sql, webdev
Published: 2020-10-21 18:12:41

# **Introduction**

Hello there ! I am Rep , Software Engineer in the making and currently a 3rd year Computer Engineering student ! In this post i am going to share a quick guide on creating a CRUD ( Create , Read , Update , Delete ) Rest API With Lumen , MySQL Database and also Eloquent ORM .

# **Why Lumen ?**
When you are only intended to Create an API , you wont need lots of Laravel default Libraries / Dependencies , because the goals is only to output a plain data formatted with most probably JSON , therefore we'll use Lumen , a micro-framework which utilize laravel's best part , with smaller size and faster execution time too!

# **What should i know or have to follow this post?**

## Tools
### Make sure you already installed :
* PHP 7.2 or Higher
* Composer 
* MySQL Server ( You can install it via XAMPP on Windows , or via your favorite Packet Manager on UN*X like system)
* PHPMyAdmin ( You get this automatically via XAMPP , you can install it on linux via Packet Manager also)


## Knowledge
### Several things you need to know before following this post : 
* Basic Request / Response on Web 
* PHP ( Very , very , very mandatory )
* A bit of Laravel Knowledge
* SQL Knowledge (would be really helpful)

# **Configuring the Project**

In this tutorial , we'll create a simple CRUD for a Product Entity , we'll name our project "product-rest-api" , please kindly remember that by the time this tutorial is being written , the latest release of Lumen and Laravel is 8.0 .

### Creating The Project

Firstly , we'll have to create the project first , by executing this command :

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/oasduyegejtmq9ptm3bv.png)


Once the project has successfuly built , you can change your directory to the project directory (product-rest-api) and run this command to start the server : 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qti8097hsb3p8k5ghagx.png)

You can test the endpoint via Postman or Your web browser by sending a GET request to the "/" route 

Result : 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/um5fvk9rhd265r5wp30v.png)

If you get the same response as shown on image above , it means that the project has built sucessfully and you're ready to move on to the next step.

### Configuring The Database 

We need a database to later save / hold the migrated table from lumen , therefore we'll need to create one in MySQL , i'll give the database name "product-rest" , and i'll do it via the terminal to speed up the process , you can also create it via PHPMyAdmin.

**Note : if you are using Windows and XAMPP , dont forget to turn on the MySQL Service and Apache (if you are going to use PHPMyAdmin) via the XAMPP Control Panel.
If you are using linux , start the mysql / mariadb service via your terminal
**

#### Creating The Database Via Terminal / CMD : 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/kdmh5guw9pivpwf3el0m.png)

Once you're done with the database , now open your favorite Code Editor and open your project folder . Once your project folder are loaded , open the `.env` file , and do the configuration for your project database **(don't forget to stop the server running first)**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/fp8cnaxxjxostuflh5nn.png)

The Important part of the `.env` file configuration as shown above is to make sure you filled your Database Configuration correctly , configuration related to Database are those started with `**DB_**`.

One more step is done , the next step is to create the database migration or defining the database schema , while working with laravel , you could easily utilize the artisan's `make:model` with -m option to automatically generate a model and a migration , unfortunately this is not available in Lumen , therefore we'd have to create the migration first and later on , create the Model .

Create the product table migration with this command  :

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9whr6n37p5un6mlpclke.png)

Command above will create you a migration file which will be located on `database/migrations` , locate the `create_products_table` file and open it up.

Once you already opened it , we'll start on Creating the product schema , it'll just have some basics data like :
* Name
* Price
* Category

Lets jump right into the code , inside the `CreateProductsTable` class , you will find a `public function up()` , we'll define our schema there , or to put simply , the function will looked like this : 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/v7m1rb1ysmz7wunr3rdy.png)

Once we already done with defining the schema , we would have to create a Model class named `Product.php` , but before we do that , keep in mind that Lumen dont have Facades nor Eloquent enabled by default , therefore we'll need to first turn it on by uncommenting these following lines located on `bootstrap/app.php` on line 26 and 28 respectively

**Line to Uncomment**
* `$app->withFacades();`
* `$app->withEloquent();`


Next thing is to create the Product.php file inside the app/Models directory , and fill it with these code : 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dzzlww8vc3rn0chkuqgu.png)

The `protected $guarded = []` means that we'll allow the web app to fill datas to any column on the table.

The last configuration we'll have to do is to run the migration , it can be done by simply running this command below 

`php artisan migrate`

Check your database , and see you'll get the product table with 4 columns containing id , name , price and category .


#Building The Logic


### Defining the routes

Our API will have 5 Endpoints , those are : 
* `GET /product to get all products data`
* `GET /product/{id} to get a product by its ID`
* `POST /product to create new product`
* `PUT /product/{id} to update a product base on its id`
* `DELETE /product/{id} to delete a product base on its id`

Before we create the routes , it'll be better to create the controller first and then create functions that will represents each action. In order to do so , we need to create a `ProductController.php` file first on the app/Http/Controllers directory 

First , we'll need to use the Product Model inside this class and we'll also need to parse incoming request , therefore we'll add these lines of code: 

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

And after that , we'll need to create a function that would return all Products data , to do so , we'll create a function named index , the controller will look pretty much like this : 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/saz7bngrqufladwmjpzv.png)

Next up, below the index function , we'll create a function called show , which will take up a parameter of id , and return a product based on it id :

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3e5d1ba5drpjnl6r6j4j.png)

We're done showing products , now its time to create a new one with the create function , which will accept a parameter of `$request with type Request` :

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lfgnd15gushmyqvqmq9n.png)

Fancy an update to your product? we'll create  a function which will takes two parameter consist of `$request with type Request` and the product's id we're going to update : 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ova5j44itw9pu9hau16k.png)

What will happen if the product is no longer produced ? it will get deleted from the product list , therefore the last function we are going to create is a delete function which will takes up a parameter of product id : 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ap1o6a9lpo1zaas9n7ni.png)

The Full ProductController.php Code would look like this : 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/m5gm69ss3usnrf6iorzv.png)

## Creating The Routes 

We're done with all the logics , but how could we access all these logics , the answer is by binding the route to the controller's function .

Navigate to routes directory , and open up the web.php , we'll changed it , so it'll match the routes we have defined above before :

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/oxcf3d5y2fapnxbw56q1.png)


That's it for the codes and logic stuff , next up we'll test the Routes , starting from creating the product first , you might realize that we dont have any product yet .

** Note : you could also use Seeder to Seed data into your database first **


# Testing the EndPoints 

###Create Product 

Create a POST request to `localhost:8000/product` via Postman , and fill the body section with raw option , and toggle the JSON Option , more or less like this : 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lk0z7rece1jj8odvt7mn.png)

Create 2 or 3 Products so that we could see the difference between index and show function afterwards.

### Show Products
Now open a new tab in postman, we'll send a GET request to `localhost:8000/product` which is binded to `index()` function and will return all products 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/au0e3gpq1nwf0dt0yw28.png)

And turns out , it works , it gives us all of the products data.

### Show Product by ID
In my products data , i have products with ID of 2 , 3 and 4 , you could check it from the previous response , and try to access only 1 product by sending a GET Request to `localhost:8000/{id}` in this case i'll try to get a product with id of 2 , so the request will be a GET to `localhost:8000/2` : 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dxcxwjdzj6kgsmq8mqex.png)

Yes ! it responded correctly by showing us only a data which id is 2 .

### Update Product

To update a product , we'll have to send a PUT request, which will require request parameters , just like we did with **Create Product** request , and the id of product we're going to update , therefore it will be a PUT request to : `localhost:8080/product/{id}` this time i will update the previous data of ID 2 , and change the product price to $3000 , notice that you'll need to re-write the name and category data as well.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/aj76ymf6f1ju2bzc54rp.png)

And once again , it works perfectly , it send us back a json response with the product's updated data.

##Delete a Product

Because i changed the price just recently , turns out people are started to grab the Laptops very quickly and it is now out of stock until a new version released .

So now we'd have to delete the product , by sending a DELETE request to `localhost:8000/product/2`

We'll also later validate this request by showing all products, because it should have been gone afterwards.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qpzdyhpkl0hc3a1si7pn.png)

And if we checked it by sending a GET request to `/product` , it returned : 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gw66kb3b1peqp4r1zp3y.png)

It has been verified that all of the routes are working properly , because it only responded with 2 items with ID of 3 and 4.



# That's a Wrap

Thanks for you all who finally made it to the bottom and successfully created a REST API with Lumen , there's a lot of things you could improve from the current API , such as request validation etc. 

And if you want to see the source code , feel free to fork it from my repository at : https://github.com/rizqyep/product-rest-api

Happy Coding !