A Simple API using Laravel 5.8

Fill in witty sub-title later

Aidan Bridge
May 17 · 7 min read


Easy enough

Using the Terminal, change directory to where you normally keep your projects or code.

Enter the below commands to get your Laravel project up and running.

$ laravel new recipes-api
...this command takes a minute or so...
$ cd recipes-api
$ php artisan serve
Laravel development server started: <http://127.0.0.1:8000>

Hopefully you will see message as above and be able to use the browser be to navigate to the address and see as below.

default homepage

Great! Now let’s stop the server (control + c) and carry on with the tutorial.


These are instructions only if using mac and vim

$ git init
$ git add .
$ git commit

This will open up the commit file in vim

  • Press ‘i’ for insert/write mode
  • Type commit message, e.g. “Initial Commit”
  • Press esc to exit insert/write mode
  • Type :wq and then press enter to save your file and exit

Go back to your Terminal and make sure you are in your Laravel project folder. For this Project it is recipes-api/

The below command will create an empty SQLite database within the database folder.

$ touch database/database.sqlite

Also within the Project directory there will be an .env file, we need to edit this so that out Laravel application knows which database we are using. Change the settings within it to the same as below. I am using the absolute path because currently there are some issues with seeding SQLite databases and this is the easiest workaround.

DB_CONNECTION=sqlite
DB_DATABASE={ABSOLUTE_PATH_TO}/database/database.sqlite

Now is the time to open up your Laravel Project folder in your preferred IDE/Text Editor


Utilising the power of Laravel

$ php artisan make:model Recipe -mcrf

In the Terminal if you enter the above command it will create a model called ‘Recipe’, create a Migration File, a Controller File, a Factory File and specify that our model is a resource.

If you don’t understand what that all means, do not worry, I will explain as we go through the tutorial.

Now lets open up the migration file that was just created

~database/migrations/YYYY_MM_DD_hhmmss_create_recipes_table.php

The purpose of this migration file is to provide the schema to create the required tables in our specified database. ‘id’ and ‘timestamps’ are auto-generated (the timestamps method creates two columns in the database, created_at and modified_at). I have also added the columns; name, ingredients, method and cuisine, as well as defining the data-types.


$ php artisan migrate

When we run the above command it will run all the new migrations located in the migrations folder, therefore it should create the recipes table we have just defined.

We can check to see that this has worked by accessing your sqlite database either through a GUI such as ‘DB Browser for SQLite’ or through the terminal using the commands below.

$ sqlite3
sqlite> .open {PATHTO}/database.database.sqlite
sqlite> PRAGMA table_info(recipes);

You should see as below:

0|id|integer|1||1
1|created_at|datetime|0||0
2|updated_at|datetime|0||0
3|name|varchar|1||0
4|ingredients|varchar|1||0
5|method|text|1||0
6|cuisine|varchar|1||0

If you change anything in migration file, add new column or change data type then in the Terminal you will need to run below command to refresh your tables.

$ php artisan migrate:refresh

Factory time

An API isn’t much use if we don’t have any data to retrieve so we are going to utilise a Laravel factory to populate our database with dummy data.

We already created the factory earlier so now we need to open the file and edit as below.

~/database/factories/RecipeFactory.php

Here we are utilising the Faker library to generate data for our database. The above code is telling our factory that when it is run we would like Faker to create random data for the columns we defined earlier.


Giving the factory instructions

Now we need to create a Seeder which will provide instructions for our Factory to follow.

$ php artisan make:seeder RecipeSeeder

Open up the newly created RecipeSeeder class and edit as below

~/database/seeds/RecipeSeeder.php

The above code should be fairly self explanatory, when the run function is called it will create 15 new records for us in the database, as outlined in our factory.

Finally we need to edit the DatabaseSeeder file so that we when we run the artisan command $ php artisan db:seed it runs our RecipeSeeder class.

~/database/seeds/DatabaseSeeder.php

Okay, now we should be able to run $ php artisan db:seed from the Terminal to populate the database.

We can check this worked as before, either using a GUI or via the command line as below.

sqlite> select * from recipes;

Not so fat

In the original artisan command we already created the Recipe Controller so lets’s open up that file now.


~/recipes-api/app/Http/Controllers/RecipeController.php

To retrieve everything from the recipes table we edit the index function. Create the variable $recipes and use the eloquent method all() on the Recipe model, lastly we return a JSON representation of this data as the response.


~/recipes-api/app/Http/Controllers/RecipeController.php

To retrieve a single recipe, using the id as the identifier, we will update the show() function as above. Easy.


~/recipes-api/app/Http/Controllers/RecipeController.php

To enable the storage of new recipes in the database we need to edit the store() function. Here we take the $request parameter, call the validate method to validate that the required values have been provided (you can set these to nullable if certain values are not required). Then we use the create() function with the $request as a parameter. Finally we return a success message and the newly created recipe as a JSON response.


~/recipes-api/app/Http/Controllers/RecipeController.php

Finally we want to add the ability to update an existing recipe. To do this we will, funnily enough, edit the update() function. As before, we are first validating the request, then we are using the provided $recipe parameter to update the correct recipe. Finally we return a success message and the newly updated recipe as a JSON response.


For POST and PUT

To enable our POST and PUT requests to work we need a quick update of our Recipe Model. Update as below, this is telling our application that we are allowing this Model to write to the database.

~/recipes-api/app/Recipe.php

En-route to completion

The last thing that needs to be done to get our API up and running is to set up our routes. The purpose for this is that the application knows what functions to run when we hit certain endpoints.

~/recipes-api/routes/api.php

Make sure you are editing the api.php file, then add the routes as above.

Breaking down each line:

Route::HTTP verb('endpoint/{parameter}'),'controller@function');

As illustrated above, what we are doing is informing our application that when it receives a HTTP request at certain endpoints then it should run a specified function located in a specified controller.


Browser and Postman

To try and keep this tutorial succinct I will not explain how to test your Laravel application using PHPUnit rather I will show you how to manually test that your API is working using the browser and Postman.


Let’s start up our server: $ php artisan serve

We should now be able to use a browser to navigate to: http://127.0.0.1:8000/api/recipes or if your have altered the default localhost then it will be whatever you have set it to then /api/recipes .

Hopefully you should see some data similar to below. (I am using the Chrome extension JSONView to prettify the JSON)

http://127.0.0.1:8000/api/recipes

Now let us test returning/getting a single recipe, for this we just need to add a ID to the previous URL. For example: http://127.0.0.1:8000/api/recipes/3 you should see as below.

http://127.0.0.1:8000/api/recipes/3

Great! Our GET routes are working! Next to test our POST and PUT routes we will use Postman.

Copy all the settings and data as below, notice how the data is almost the same as the response from GET, however, without an ID or created/updated date.

When you click ‘Send’ you should get a response as below:


Perfect! Finally we need to test our PUT request. For a PUT request we need to alter the URL to include the ID of the Recipe we wish to change.

When you click ‘Send’ you should get a response as below:

Excellent! Your API is fully functioning! Well done, you can now expand and adapt as you desire.

Aidan Bridge

Written by