Fundações: Preparando o Ambiente
Antes de construir sua API REST em Laravel, você precisa dominar os conceitos fundamentais. Uma API REST (Representational State Transfer) comunica através de endpoints HTTP, utilizando métodos como GET, POST, PUT e DELETE. Laravel, com sua arquitetura elegante, oferece ferramentas poderosas para isso através do Eloquent ORM e das rotas.
Instale Laravel 11 executando composer create-project laravel/laravel api-rest e navegue até o diretório do projeto. Configure seu arquivo .env com as credenciais do banco de dados. Execute php artisan migrate para criar as tabelas padrão. Isso estabelece a base sólida para qualquer aplicação profissional.
Estruturando Models, Migrations e Controllers
Models e Migrations
O coração de uma API REST repousa nos Models e nas Migrations. Uma Migration define a estrutura do banco de dados, enquanto o Model representa os dados em PHP. Crie um modelo de Produto:
php artisan make:model Produto -m
Edite a migration criada em database/migrations/:
Schema::create('produtos', function (Blueprint $table) {
$table->id();
$table->string('nome');
$table->text('descricao')->nullable();
$table->decimal('preco', 10, 2);
$table->integer('estoque')->default(0);
$table->timestamps();
});
Execute php artisan migrate. Seu Model app/Models/Produto.php já existe com proteções padrão:
class Produto extends Model
{
use HasFactory;
protected $fillable = ['nome', 'descricao', 'preco', 'estoque'];
protected $casts = [
'preco' => 'decimal:2',
];
}
Controllers RESTful
Gere um Controller de recurso com php artisan make:controller ProdutoController --resource. Isso cria automaticamente os sete métodos necessários. Implemente os principais:
<?php
namespace App\Http\Controllers;
use App\Models\Produto;
use Illuminate\Http\Request;
class ProdutoController extends Controller
{
public function index()
{
return response()->json(Produto::all(), 200);
}
public function store(Request $request)
{
$validated = $request->validate([
'nome' => 'required|string|max:255',
'descricao' => 'nullable|string',
'preco' => 'required|numeric|min:0',
'estoque' => 'integer|min:0'
]);
$produto = Produto::create($validated);
return response()->json($produto, 201);
}
public function show($id)
{
$produto = Produto::findOrFail($id);
return response()->json($produto, 200);
}
public function update(Request $request, $id)
{
$produto = Produto::findOrFail($id);
$validated = $request->validate([
'nome' => 'string|max:255',
'descricao' => 'nullable|string',
'preco' => 'numeric|min:0',
'estoque' => 'integer|min:0'
]);
$produto->update($validated);
return response()->json($produto, 200);
}
public function destroy($id)
{
$produto = Produto::findOrFail($id);
$produto->delete();
return response()->json(null, 204);
}
}
Registre as rotas em routes/api.php:
Route::apiResource('produtos', ProdutoController);
Isso gera automaticamente todas as rotas REST padrão com prefixo /api/produtos.
Validação, Autenticação e Boas Práticas
Validação e Resources
Validação deve ser robusta. Crie um FormRequest dedicado:
php artisan make:request StoreProdutoRequest
public function rules()
{
return [
'nome' => 'required|string|max:255|unique:produtos',
'preco' => 'required|numeric|min:0.01',
'estoque' => 'integer|min:0'
];
}
Use StoreProdutoRequest no seu Controller para validação automática. Para responder consistentemente, crie um Resource:
php artisan make:resource ProdutoResource
public function toArray($request)
{
return [
'id' => $this->id,
'nome' => $this->nome,
'preco' => (float) $this->preco,
'estoque' => $this->estoque,
'criado_em' => $this->created_at->format('Y-m-d H:i:s')
];
}
Use ProdutoResource::collection(Produto::all()) no método index().
Autenticação com Sanctum
Laravel Sanctum oferece autenticação token simples e segura. Instale com php artisan install:api. Crie um Controller de autenticação:
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class AuthController extends Controller
{
public function login(Request $request)
{
$credentials = $request->validate([
'email' => 'required|email',
'password' => 'required'
]);
$user = User::where('email', $credentials['email'])->first();
if (!$user || !Hash::check($credentials['password'], $user->password)) {
return response()->json(['message' => 'Credenciais inválidas'], 401);
}
$token = $user->createToken('api-token')->plainTextToken;
return response()->json(['token' => $token], 200);
}
public function logout(Request $request)
{
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'Deslogado'], 200);
}
}
Proteja suas rotas em routes/api.php:
Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('produtos', ProdutoController);
Route::post('logout', [AuthController::class, 'logout']);
});
Route::post('login', [AuthController::class, 'login']);
Testes e Deployment
Testando sua API
Laravel oferece suporte nativo a testes. Crie um teste:
php artisan make:test ProdutoControllerTest
<?php
namespace Tests\Feature;
use App\Models\Produto;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ProdutoControllerTest extends TestCase
{
use RefreshDatabase;
public function test_pode_listar_produtos()
{
Produto::create([
'nome' => 'Notebook',
'preco' => 3000.00,
'estoque' => 5
]);
$response = $this->getJson('/api/produtos');
$response->assertStatus(200)
->assertJsonCount(1);
}
public function test_pode_criar_produto()
{
$response = $this->postJson('/api/produtos', [
'nome' => 'Mouse',
'preco' => 50.00,
'estoque' => 10
]);
$response->assertStatus(201)
->assertJsonPath('nome', 'Mouse');
}
}
Execute os testes com php artisan test. Testes garantem que sua API funciona conforme esperado conforme você evolui o código.
Conclusão
Você aprendeu que construir uma API REST profissional em Laravel envolve três pilares: estrutura sólida através de Models e Controllers RESTful, segurança robusta com validação e autenticação Sanctum, e confiabilidade através de testes. Domine esses conceitos e você terá domínio total sobre APIs em Laravel. Na prática, sempre considere paginação, rate limiting e versionamento de API para aplicações em produção.