Hello! In this tutorial, we’ll be building a complete REST API in Laravel to manage tasks. I'll guide you through the basic steps, from setting up the project to creating automated tests.
Create a new Laravel project:
composer create-project laravel/laravel task-api cd task-api code .
Configure the database:
In the .env file, set your database configurations:
DB_DATABASE=task_api DB_USERNAME=your_username DB_PASSWORD=your_password
Generate the tasks table:
Run the command to create a new migration for the tasks table:
php artisan make:migration create_tasks_table --create=tasks
In the migration file (database/migrations/xxxx_xx_xx_create_tasks_table.php), define the table structure:
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { Schema::create('tasks', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('description')->nullable(); $table->boolean('completed')->default(false); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('tasks'); } };
Run the migration to create the table:
php artisan migrate
Create the model and controller for the task:
php artisan make:model Task php artisan make:controller TaskController --api
Define the Task model (app/Models/Task.php):
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Task extends Model { use HasFactory; protected $fillable = ['title', 'description', 'completed']; }
In the routes/api.php file, add the routes for the TaskController:
<?php use App\Http\Controllers\TaskController; use Illuminate\Support\Facades\Route; Route::apiResource('tasks', TaskController::class);
In the TaskController, we’ll implement the basic CRUD methods.
<?php namespace App\Http\Controllers; use App\Models\Task; use Illuminate\Http\Request; class TaskController extends Controller { public function index() { $tasks = Task::all(); return response()->json($tasks, 200); } public function store(Request $request) { $request->validate([ 'title' => 'required|string|max:255', 'description' => 'nullable|string' ]); $task = Task::create($request->all()); return response()->json($task, 201); } public function show(Task $task) { return response()->json($task, 200); } public function update(Request $request, Task $task) { $request->validate([ 'title' => 'required|string|max:255', 'description' => 'nullable|string', 'completed' => 'boolean' ]); $task->update($request->all()); return response()->json($task, 201); } public function destroy(Task $task) { $task->delete(); return response()->json(null, 204); } }
Now we’ll test each endpoint manually, using a VS Code extension called REST Client (https://marketplace.visualstudio.com/items?itemName=humao.rest-client). If you prefer, you can also use Insomnia or Postman!
After installing the extension, create an .http file in your project folder with the following content:
### Create New Task POST http://127.0.0.1:8000/api/tasks HTTP/1.1 content-type: application/json Accept: application/json { "title": "Study Laravel" } ### Show Tasks GET http://127.0.0.1:8000/api/tasks HTTP/1.1 content-type: application/json Accept: application/json ### Show Task GET http://127.0.0.1:8000/api/tasks/1 HTTP/1.1 content-type: application/json Accept: application/json ### Update Task PUT http://127.0.0.1:8000/api/tasks/1 HTTP/1.1 content-type: application/json Accept: application/json { "title": "Study Laravel and Docker", "description": "We are studying!", "completed": false } ### Delete Task DELETE http://127.0.0.1:8000/api/tasks/1 HTTP/1.1 content-type: application/json Accept: application/json
This file lets you send requests directly from VS Code using the REST Client extension, making it easy to test each route in your API.
Next, let’s create tests to ensure each route works as expected.
First, create a factory for the Task model:
php artisan make:factory TaskFactory
<?php namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; class TaskFactory extends Factory { public function definition(): array { return [ 'title' => fake()->sentence(), 'description' => fake()->paragraph(), 'completed' => false, ]; } }
PHPUnit Configuration:
<?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true" > <testsuites> <testsuite name="Unit"> <directory>tests/Unit</directory> </testsuite> <testsuite name="Feature"> <directory>tests/Feature</directory> </testsuite> </testsuites> <source> <include> <directory>app</directory> </include> </source> <php> <env name="APP_ENV" value="testing" /> <env name="BCRYPT_ROUNDS" value="4" /> <env name="CACHE_DRIVER" value="array" /> <env name="DB_CONNECTION" value="sqlite" /> <env name="DB_DATABASE" value=":memory:" /> <env name="MAIL_MAILER" value="array" /> <env name="PULSE_ENABLED" value="false" /> <env name="QUEUE_CONNECTION" value="sync" /> <env name="SESSION_DRIVER" value="array" /> <env name="TELESCOPE_ENABLED" value="false" /> </php> </phpunit>
Create an integration test:
php artisan make:test TaskApiTest
In the tests/Feature/TaskApiTest.php file, implement the tests:
<?php namespace Tests\Feature; use App\Models\Task; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; class TaskApiTest extends TestCase { use RefreshDatabase; public function test_can_create_task(): void { $response = $this->postJson('/api/tasks', [ 'title' => 'New Task', 'description' => 'Task Description', 'completed' => false, ]); $response->assertStatus(201); $response->assertJson([ 'title' => 'New Task', 'description' => 'Task Description', 'completed' => false, ]); } public function test_can_list_tasks() { Task::factory()->count(3)->create(); $response = $this->getJson('/api/tasks'); $response->assertStatus(200); $response->assertJsonCount(3); } public function test_can_show_task() { $task = Task::factory()->create(); $response = $this->getJson("/api/tasks/{$task->id}"); $response->assertStatus(200); $response->assertJson([ 'title' => $task->title, 'description' => $task->description, 'completed' => false, ]); } public function test_can_update_task() { $task = Task::factory()->create(); $response = $this->putJson("/api/tasks/{$task->id}", [ 'title' => 'Update Task', 'description' => 'Update Description', 'completed' => true, ]); $response->assertStatus(201); $response->assertJson([ 'title' => 'Update Task', 'description' => 'Update Description', 'completed' => true, ]); } public function test_can_delete_task() { $task = Task::factory()->create(); $response = $this->deleteJson("/api/tasks/{$task->id}"); $response->assertStatus(204); $this->assertDatabaseMissing('tasks', ['id' => $task->id]); } }
Run the tests:
php artisan test
*Thank you! *
The above is the detailed content of How to Create REST API Using Laravel. For more information, please follow other related articles on the PHP Chinese website!