Criando uma API RESTful Completa com Laravel
Neste tutorial, vamos construir uma API RESTful completa em Laravel para gerenciar tarefas, aproveitando todo o poder do framework — que é voltado para produtividade, clareza e robustez.
O Laravel foi criado e é mantido por Taylor Otwell, sendo um framework opiniativo que prioriza convenções sobre configurações. Isso significa menos tempo gasto com ajustes manuais e mais foco na lógica de negócio.
O que é uma API RESTful?
Antes de codificar, é importante entender o conceito.
REST (Representational State Transfer) é um estilo arquitetural para comunicação entre sistemas, normalmente usando o protocolo HTTP.
Nas APIs RESTful:
- Os endpoints representam recursos.
-
Os verbos HTTP indicam ações:
- GET → Recuperar recursos
- POST → Criar recursos
- PUT → Atualizar recursos
- DELETE → Excluir recursos
Cada requisição é sem estado (stateless), ou seja, o servidor não guarda contexto entre chamadas.
Passo 1 — Criando o projeto Laravel
Com PHP e Composer instalados, crie o projeto:
composer create-project laravel/laravel task-api
Abra o projeto no VS Code ou no editor de sua preferência.
Passo 2 — Configurando o banco de dados
No arquivo .env
, ajuste para o seu ambiente:
DB_DATABASE=task_api
DB_USERNAME=seu_usuario
DB_PASSWORD=sua_senha
Passo 3 — Criando a migration
As migrations permitem versionar e criar tabelas no banco.
Execute:
php artisan make:migration create_tasks_table --create=tasks
Defina a estrutura em database/migrations/xxxx_xx_xx_create_tasks_table.php
:
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description')->nullable();
$table->boolean('completed')->default(false);
$table->timestamps();
});
Crie a tabela:
php artisan migrate
Passo 4 — Criando Model e Controller
Laravel segue o padrão MVC.
php artisan make:model Task
php artisan make:controller TaskController --api
No modelo app/Models/Task.php
:
class Task extends Model
{
use HasFactory;
protected $fillable = ['title', 'description', 'completed'];
}
Passo 5 — Definindo rotas
No routes/api.php
:
Route::apiResource('tasks', TaskController::class);
Isso já cria automaticamente todas as rotas CRUD.
Passo 6 — Implementando o Controller
Em app/Http/Controllers/TaskController.php
:
<?php
namespace App\Http\Controllers;
use App\Models\Task;
use Illuminate\Http\Request;
class TaskController extends Controller {
public function index()
{
return response()->json(Task::all(), 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, 200);
}
public function destroy(Task $task)
{
$task->delete();
return response()->json(null, 204);
}
}
Passo 7 — Testando a API
Você pode testar com Postman, Insomnia ou com a extensão REST Client no VS Code.
Exemplo de requisição .http
:
### Criar nova tarefa
POST http://127.0.0.1:8000/api/tasks
Content-Type: application/json
{
"title": "Estudar Laravel"
}
### Listar tarefas
GET http://127.0.0.1:8000/api/tasks
Passo 8 — Automatizando testes com PHPUnit
Crie uma factory:
php artisan make:factory TaskFactory
database/factories/TaskFactory.php
:
public function definition(): array
{
return [
'title' => fake()->sentence(),
'description' => fake()->paragraph(),
'completed' => false,
];
}
Crie o teste:
php artisan make:test TaskApiTest
tests/Feature/TaskApiTest.php
(exemplo de teste de criação):
<?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' => 'Nova Tarefa',
'description' => 'Descrição da tarefa',
'completed' => false,
]);
$response->assertStatus(201);
$response->assertJson([
'title' => 'Nova Tarefa',
'description' => 'Descrição da tarefa',
'completed' => false,
]);
}
public function test_can_list_tasks(): void
{
Task::factory()->count(3)->create();
$response = $this->getJson('/api/tasks');
$response->assertStatus(200);
$response->assertJsonCount(3);
}
public function test_can_show_task(): void
{
$task = Task::factory()->create();
$response = $this->getJson("/api/tasks/{$task->id}");
$response->assertStatus(200);
$response->assertJson([
'title' => $task->title,
]);
}
public function test_can_update_task(): void
{
$task = Task::factory()->create();
$response = $this->putJson("/api/tasks/{$task->id}", [
'title' => 'Tarefa Atualizada',
'description' => 'Nova descrição',
'completed' => true,
]);
// Mantendo 201 para compatibilidade com o seu controller atual
$response->assertStatus(201);
$response->assertJson([
'title' => 'Tarefa Atualizada',
'description' => 'Nova descrição',
'completed' => true,
]);
}
public function test_can_delete_task(): void
{
$task = Task::factory()->create();
$response = $this->deleteJson("/api/tasks/{$task->id}");
$response->assertStatus(204);
}
}
Execute:
php artisan test
Top comments (0)