A few months ago, after I wrote my first article about building a simple Task Manager in React, I had on mind to integrate React in Laravel and build a RESTful API where we’d fetch our data from, instead of fetching it from a public API like it’s the case with the project from my first article.
So, here it is: A simple task manager built in React and Laravel!
Just to give you an idea of what we’ll be doing:
Now, let’s see the steps of building this tiny app.
Setup
First, we’ll create an initial Laravel project by running the following command:
composer create-project --prefer-dist laravel/laravel <name-of-app>
Once we have the Laravel project, we’ll enter the project’s directory and will add a React preset to it with this command:
php artisan preset react
Now, we’ll modify the file webpack.mix.js
, so the React components are compiled properly:
Now, by running the two commands below, we have our project set up and we can dive into the code implementation.
npm install
npm run dev
API implementation (Laravel)
For the API, we’ll use Laravel Resources and we’ll organize the code according to the Repository design pattern.
In this app, we’ll have only two resources: User and Task. These resources are related in such a way that a user can have multiple tasks, while a task belongs to only one user.
Routes
When it comes to creating API endpoints, I usually like to start by creating all the needed routes for a particular resource, so let’s do that by adding the following routes to our api.php
file:
Models, Migrations & Controllers
Since Laravel comes with the model and migration for Users, we only need to create a model, a migration, and a controller for Tasks. We can do that with this command:
php artisan make:model -mc Task
Where we create a model named Task and we add the flags:
- m — which creates a migration for the corresponding model;
- c — which creates a controller for the model;
Now we should have the model under the app
folder and the migration in the database/migrations
folder and they should look like this:
As we can see, the relations of the models are set as described earlier, so a task belongsTo()
one user, while the user hasMany()
tasks.
Note that we don’t touch the default migration of the users table.
As for the controller, we have the file TaskController.php
created under the app/Http/Controllers
folder and we’ll talk about its code a bit later in this article.
Resources
Next, we’ll create the needed resources by running the following commands:
php artisan make:resource User
php artisan make:resource Task
These commands should create a folder named Resources
under the app/Http
folder and there should be the files: Task.php
and User.php
. These files are a definition of all the resources’ fields that will be sent in the responses.
Check the content of these files below:
Repositories setup
As I mentioned earlier, we’ll use Repositories to organize the code, so to implement this we’ll create a folder named Repositories
under the app folder and inside of it we’ll add the following two files named Repository.php
and RepositoryInterface.php
, respectively:
The Repository interface defines the methods that the Repository class should implement and the Repository class consists of their implementations.
These methods work as per the following:
getItems()
: Returns the items of a RepositorysetItems()
: Sets the items to the RepositorysetError()
: Sets a boolean that tells if an error occurred or nothasError()
: Returns a boolean depending on the error that was set
Tasks CRUD functionality
We’ll implement the CRUD operations for Tasks by creating the class Tasks
that will extend the Repository
class and will look like this:
Each method of this class returns an object instance from the Repository
class. This means that every endpoint of this class will return an object which will have the info if any error occurred during the execution of the code and if there wasn’t any error, it will have the needed items — in this case, the needed tasks).
If we should return a single item in the Repository, we use the resource Task
that we created. On the other hand, if we need to return a list of items, then we use the predefined method collection()
that can be used on Resource
— objects. This method returns a Collection of Tasks.
Now that we have the Tasks Repository ready, we should implement the endpoints in our TaskController
. We’ll do that by adding the following code in it:
Each endpoint in the controller does the following:
- Calls an endpoint from the Tasks Repository;
- Checks if any error has occurred during the execution of the code of the called endpoint;
- If there was an error, it returns a
JSON
response with an empty array asdata
and status of500 Internal Server Error
; - If there’s no error, it returns a
JSON
response with an array with the correspondingdata
and status of200 OK
;
With this done, we have our API ready to accept the incoming requests.
Front End implementation (React)
In this project, we’ll have only two React components: Task and Main.
The Task component receives a task as a parameter and according to its values, it defines the Single Task section which shows its title, description, and status (Done/Undone). If no task is selected there’s a message notifying the user about that.
The Main component is our parent component and it keeps an array of tasks that initially is empty, but it fills up whenever the component is mounted. This is done in the componentDidMount() method which makes a request to the /api/tasks
route and sets the state of the tasks
to be the array of tasks that are returned in the response of the request.
The other methods in this component work as per the following:
- handleClick(): sets the state of
currentTask
to be the selected task; - renderTasks(): defines the appearance of the tasks;
- render(): shows all of the tasks and the Single Task section. It calls the renderTasks() method which adds all of the tasks inside the list and it includes the
<Task/>
component with the currently selected task as a parameter;
Conclusion
The integration of React in Laravel is very easy and fun at the same time, and we managed to use Resources — which was the first time for me, so this project was a complete win because I learned something new, and I documented my findings, so hopefully, you also did learn something new by following this article!
I would also like to mention that for now, we’re not using the routes for users
but they exist to announce the future work of this project which includes an authentication system.
Any step that was omitted can probably be found in the README of the repo or you can ask away in the comments. Also, feel free to fork it and play around with it or even improve it and send me a pull request, so we can discuss it together!
Keep coding, do awesome stuff, and stay happy! 😊