Hello Developers,
In this tutorial, I will show how you build a simple CRUD REST API
application using Laravel. Here I will use Laravel Resource. To learn more about Laravel resources, please see my previous tutorial regarding Laravel Resource. Follow the steps for better understanding.
Install Laravel Project In Your Environment
First, you need to go to your development workspace. My workspace is situated in D:/
drive. Open a command prompt and write the below code to install Laravel.
laravel new example-app
Database Configuration
After installing the project, open the project in your code editor. Now we have to configure the database credentials. As I am using the wamp server, I have to start the server and open the localhost/phpmyadmin
. In there I will create a database named example-app.
After that, add the credentials to the project .env file
/.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=example-app
DB_USERNAME=[USERNAME]
DB_PASSWORD=[PASSWORD]
Create Controllers, Models, and Views
You can make all the elements like controllers, models, migration, and seeder. Request, policy by the following command:
php artisan make:model Author -a -r
After successfully running the command the response looks like this:
Prepare the Controllers, Models,and Views
Let’s complete the migration file by adding the fields we needed in the database table. Open the author migration that we created.
/database/migrations/[date]_create_authors_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAuthorsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('authors', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('authors');
}
}
Then we need to open the Author model. Write below the use HasFactory, $protected
array, Adding the protected fillable make sure that we can add the name when we use the eloquent create method.
/app/Models/Author.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Author extends Model
{
use HasFactory;
protected $fillable = ['name'];
}
I think we are ready to migrate the database. Sometimes you might get the below error:
To solve this, just Update /app/Providers/AppServiceProvideer.php
file. Add the below lines:
use Illuminate\Support\Facades\Schema;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Schema::defaultStringLength(191);
}
Then run the below command:
php artisan migrate
After that, we need dummy data, the best way to make it faster, use factory. in the AuthorFactory.php
file add the below line to generate the sample data in the Author table.
/database/factories/AuthorFactory
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class AuthorFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->name,
];
}
}
After that, add the below lines to run this AuthorFactory.php
file. This factory file creates dummy data for our project.
/database/seeder/DatabaseSeeder
<?php
namespace Database\Seeders;
use App\Models\Author;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
Author::factory(15)->create();
}
}
Then run the below code to execute the seeder we have just written:
php artisan db:seed
Now check the table, you can see that there are some dummy data to complete our tutorials.
Configure Resource Controller
The best way to represent the data is to use AuthorResource. The resource can easily define how we transform the models into API resources. To generate resources we can write the make:resource
artisan command. Default resources will be placed in the app/Http/Resource
directory.
php artisan make:resource AuthorResource
In resource, you can make your custom format to represent the data you want to show users. To do so, I have made a format.
/app/Http/Resources/AuthorResources.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class AuthorResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'data' => [
'id' => (string) $this->id,
'type' => 'Authors',
'attributes' => [
'name' => $this->name,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]
]
];
}
}
To make the API, we need to define routes to the api.php
file. Let's write down the below lines to the api.php
route:
/routes/api.php
<?php
use App\Http\Controllers\AuthorController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::prefix('v1')->group(function () {
Route::get('/authors', [AuthorController::class, 'index']);
});
If you want to follow that approach, you must write every single route for the CRUD
operation. We can make it easier by replacing it with the resource list instead of defining every single endpoint. First, you have to remove the previous route, then add the following lines:
<?php
use App\Http\Controllers\AuthorController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::prefix('v1')->group(function () {
Route::apiResource('authors', AuthorController::class);
});
If you want to check whether everything is correctly defiled or not, you can run the below command to see all the defined routes:
php artisan route:list
Now complete our main part. The controller's index function will fetch all the data like this:
use App\Http\Resources\AuthorResource;
public function index()
{
return AuthorResource::collection(Author::all());
}
Create method is used for creating the author. Let's see. As we have the StoreAuthorRequest.php
file generated while we running php artisan make:model Author -a -r
, that's why we have to authorize the user in the StoreAuthorRequest.php
and UpdateAuthorRequest.php
file.
/app/Http/Requests/StoreAuthorRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreAuthorRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
}
/app/Http/Requests/UpdateAuthorRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UpdateAuthorRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
}
The create method simply adds a value to the name key like this:
public function store(StoreAuthorRequest $request)
{
$author = Author::create([
'name' => $request->input('name')
]);
return new AuthorResource($author);
}
The postman output for storing data is given below:
In the update method we have to pass an id, by that id the data will be changed like this:
public function update(UpdateAuthorRequest $request, Author $author)
{
$author->update([
'name' => $request->input('name')
]);
return new AuthorResource($author);
}
The postman output for updating data is given below:
Now the easy method is the delete method. Just put an id to delete a row. The function is given below:
public function destroy(Author $author)
{
$author->delete();
return response(null, 204);
}
If we combine all the functions in the controller, the controller will look like this:
/app/Http/Controllers/AuthorController.php
<?php
namespace App\Http\Controllers;
use App\Models\Author;
use App\Http\Resources\AuthorResource;
use App\Http\Requests\StoreAuthorRequest;
use App\Http\Requests\UpdateAuthorRequest;
class AuthorController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return AuthorResource::collection(Author::all());
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\StoreAuthorRequest $request
* @return \Illuminate\Http\Response
*/
public function store(StoreAuthorRequest $request)
{
$author = Author::create([
'name' => $request->input('name')
]);
return new AuthorResource($author);
}
/**
* Display the specified resource.
*
* @param \App\Models\Author $author
* @return \Illuminate\Http\Response
*/
public function show(Author $author)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Author $author
* @return \Illuminate\Http\Response
*/
public function edit(Author $author)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \App\Http\Requests\UpdateAuthorRequest $request
* @param \App\Models\Author $author
* @return \Illuminate\Http\Response
*/
public function update(UpdateAuthorRequest $request, Author $author)
{
$author->update([
'name' => $request->input('name')
]);
return new AuthorResource($author);
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Author $author
* @return \Illuminate\Http\Response
*/
public function destroy(Author $author)
{
$author->delete();
return response(null, 204);
}
}
That's all for today. Hope this might help you in the journey of development.
Read More: How to build API resources using Laravel