Creating a basic CRUD Restful API with Laravel
Laravel is a software development framework that has been in existence since June 2011. Credit to Taylor Otwell the founder of Laravel. It was developed as a multifunctional MVC framework and has been applied to many different software development use cases, primarily to build web applications as well as Restful API applications. In the tutorial below we will demonstrate a basic CRUD Restful API developed with the Laravel Framework. Our ultimate goal is to demonstrate how to build a RESTful API without getting into the nitigrity of API authentication and authorization (we are keeping it real simple and basic in the blog).
The API will simulate a Todo application that consists of users and tasks. Each task is related to only one user, while each user can have as many tasks as possible. Each task has a name and it can either be marked as complete or not complete. The source code to this project can be found on Github, feel free to check it out when you want to.
Step 1: Creating a Laravel Project
Laravel uses Composer as a package management tool. Therefore it's very crucial that you install it first before going any further with this project.
Create a fresh Laravel app
composer create-project --prefer-dist laravel/laravel todo
Install all the dependencies using composer
composer install
Serve your API using Laravel’s built-in development server, this serves your app on port 3000, you can override this port by adding the --port <#> argument.
php artisan serve
Step 2: Creating Models
Make sure that you cd into your project directory before running the below commands. The command creates a Todo model alongside its migration as per the -m argument.
php artisan make:model Todo -m
To solve the Mass Assignment Exception error that might arise, navigate to the app directory and add the following field at the top of your Todo model
protected $guarded = [];
Step 3: Create the controllers
The artisan command below creates a controller of the name TodosController and binds it to the Todo model.
The --api argument adds the methods that are generally used by an API resource to the created controller.
php artisan make:controller TodosController --model=Todo --api
Take note the User model has been created for us already by default, all we need is create a corresponding controller for the User model with the command below
php artisan make:controller UsersController --model=User --api
Step 4: Creating the Migrations
Navigate to the database directory under migrations you will find the create_tasks_table migration, append the fields below in the up part of the file.
$table->string('task');
$table->boolean('completed')->default('0');
$table->integer('user_id')->nullable();
Step 5: Run your migrations
The command below basically adds your tables to your database
php artisan migrate
Step 6: Modeling Relationships
Go to the Todo model and define the relationship that deals with the owner of a task. Since we have a one to many relation: which means one Todo belongs to one User, and one User has many Todos. Please paste the code below into your Todo model.
public function owner()
{
return $this->belongsTo(User::class, 'user_id');
}
Equally, we have to model the User has many Todos relation. The code below helps us achieve just that. Please paste it into the User model
public function todos()
{
return $this->hasMany(Todo::class);
}
Step 7: Define Model Factories
Factories are the perfect way that allows you to generate data for your database (seed you database). The fields in your factory should correspond to your model, in this instance the Task Model. Take note the User factory already comes predefined for you and ready to use, so no need to create it again.
It can be seen under the database/factories directory. We will create the Tasks factory below.
$user_id = \App\User::all()->random()->id;
return [
'task' => $faker->sentence,
'completed' => $faker->boolean(),
'user_id' => $user_id
];
Step 8: Seeding your database
Laravel comes with many different approaches that allow you to seed your database,
- ranging from the popular Laravel tinker package,
- or using the artisan command below
php artisan db:seed
We will use the Laravel tinker approach. Laravel tinker is a command-line interface tool for manipulating and testing your database. The artisan command opens the tinker CLI:
php artisan tinker
Let’s seed the users table with as many rows of data as we want, let’s try 20 users.
factory(App\User::class, 20)->create()
Let’s seed the todos table with 40 rows of data.
factory(App\Todo::class, 40)->create()
Step 9: API endpoints
Let’s open the api.php file in our routes folder to define our API endpoints. Add the following piece of code to your API routes file (api.php) which you can find in the routes folder.
Route::resource('todos', 'TodosController');
Route::resource('users', 'UsersController');
Step 10: Controller Implementation
Let’s start off with the TodosController
- Add the following code to your index method in the TodosController
return response()->json(Todo::all());
- Add the following code to your show method in the TodosController
return response()->json($todo->with('owner')->get()->where('id', '=', $todo->id));
- Add the following code into your store method
$todo = Todo::create([
'task' => $request->task,
'completed' => $request->completed ? $request->completed : 0,
'user_id' => User::all()->random()->id
]);return response()->json(['message' => 'Todo successfully created']);
- Add the following code into your destroy method
$todo->delete();return response()->json(['message' => 'Todo with id {$todo->id} has been successfully deleted']);
- Add the following code to the update method
if ($request->task)
$todo->task = $request->task;
if ($request->completed)
$todo->completed = $request->completed;$todo->save();return response()->json($todo);
Let’s change gears and open up the UsersController
- Add the following code to your index method
return response()->json(User::all()->first()->with('todos')->get());
- Add the following code to your show method
return response()->json($user->with('todos')->get()->where('id', '=', $user->id));
- Add the following code into your store method
$todo = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt('secret')
]);return response()->json(['message' => 'User successfully created']);
# bcrypt is the hashing algorithm used by Laravel to hash passwords
- Add the following code to your destroy method
$user->delete();return response()->json(['message' => "User with id {$user->id} has been successfully deleted"]);
- Add the following code to the update method
if ($request->name)
$user->name = $request->name;
if ($request->email)
$user->email = $request->email;$user->save();return response()->json($user);
TESTING TIME
# Now we are ready to test the API, let’s move on to the next step.
Step 10: Testing the RESTful API using POSTMAN
Firstly, I’d like to congratulate and applaud 👏👏 you for making it this far in this tutorial.
Let’s go ahead and install POSTMAN. As soon as the installation is done, lets proceed with testing the API below.
- GET -- http://localhost:<PORT>/api/todos
# This 👆 endpoint will allow us to list all the tasks/todos
- GET -- http://localhost:<PORT>/api/todos/1
# This 👆 endpoint will allow us to list one specific tasks/todos
- POST -- http://localhost:<PORT>/api/todos
# This 👆 endpoint will allow us to create a task
Lets pass it some data below.
task: Upload app to github
- DELETE -- http://localhost:<PORT>/api/todos/1
# This 👆 endpoint will allow us to delete a task
- PUT -- http://localhost:<PORT>/api/todos/1
The put endpoint calls the update method, therefore it requires that you pass it with some data. Ensure that you use the x-www-form-urlencoded data.
Let’s update this task with the following information:
task: Test this api
completed: 1
Perfect! Now let’s move on to the users API endpoints
- GET -- http://localhost:<PORT>/api/users
# This endpoint above allows us to list all the users.
- GET -- http://localhost:<PORT>/api/users/1
# This endpoint allows us to list a specific user
- POST -- http://localhost:<PORT>/api/users
# This endpoint allows us to create a user. Please take note we gave the user a default password in the store method, that is why we do not need to pass it here.
Let's pass this endpoint some data to create a todo.
name: Laravel Namibia
email: laranamibia@gmail.com
- DELETE -- http://localhost:<PORT>/api/users/1
# This endpoint is going to delete a user with id 1
- PUT -- http://localhost:<PORT>/api/users/1
# This endpoint will allow us to update a user model. Please use the x-www-form-urlencoded data
Conclusions
RESTful APIs have been a thing for quite some time now, and as the demand for Big Data increases due to the constant pressure from AI application, the developer community has also been encouraged to build applications in such a manner that encourages third-party tools and applications to seamlessly integrate with this applications and easily make use of the rich data collected over the years, to build AI tools that solve real problems without a hassle.
This tutorial’s aim was to help get your feet wet as far as API development is concerned in Laravel. I encourage you to check more of the existing resources available out there. There will be a sequel tutorial that will focus on best practices when it comes to API authentication.