<h2>Fundações: Preparando o Ambiente</h2>
<p>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.</p>
<p>Instale Laravel 11 executando <code>composer create-project laravel/laravel api-rest</code> e navegue até o diretório do projeto. Configure seu arquivo <code>.env</code> com as credenciais do banco de dados. Execute <code>php artisan migrate</code> para criar as tabelas padrão. Isso estabelece a base sólida para qualquer aplicação profissional.</p>
<h2>Estruturando Models, Migrations e Controllers</h2>
<h3>Models e Migrations</h3>
<p>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:</p>
<pre><code class="language-bash">php artisan make:model Produto -m</code></pre>
<p>Edite a migration criada em <code>database/migrations/</code>:</p>
<pre><code class="language-php">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();
});</code></pre>
<p>Execute <code>php artisan migrate</code>. Seu Model <code>app/Models/Produto.php</code> já existe com proteções padrão:</p>
<pre><code class="language-php">class Produto extends Model
{
use HasFactory;
protected $fillable = ['nome', 'descricao', 'preco', 'estoque'];
protected $casts = [
'preco' => 'decimal:2',
];
}</code></pre>
<h3>Controllers RESTful</h3>
<p>Gere um Controller de recurso com <code>php artisan make:controller ProdutoController --resource</code>. Isso cria automaticamente os sete métodos necessários. Implemente os principais:</p>
<pre><code class="language-php"><?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);
}
}</code></pre>
<p>Registre as rotas em <code>routes/api.php</code>:</p>
<pre><code class="language-php">Route::apiResource('produtos', ProdutoController);</code></pre>
<p>Isso gera automaticamente todas as rotas REST padrão com prefixo <code>/api/produtos</code>.</p>
<h2>Validação, Autenticação e Boas Práticas</h2>
<h3>Validação e Resources</h3>
<p>Validação deve ser robusta. Crie um FormRequest dedicado:</p>
<pre><code class="language-bash">php artisan make:request StoreProdutoRequest</code></pre>
<pre><code class="language-php">public function rules()
{
return [
'nome' => 'required | string | max:255 | unique:produtos', 'preco' => 'required|numeric|min:0.01', 'estoque' => 'integer|min:0'
];
}</code></pre>
<p>Use <code>StoreProdutoRequest</code> no seu Controller para validação automática. Para responder consistentemente, crie um Resource:</p>
<pre><code class="language-bash">php artisan make:resource ProdutoResource</code></pre>
<pre><code class="language-php">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')
];
}</code></pre>
<p>Use <code>ProdutoResource::collection(Produto::all())</code> no método <code>index()</code>.</p>
<h3>Autenticação com Sanctum</h3>
<p>Laravel Sanctum oferece autenticação token simples e segura. Instale com <code>php artisan install:api</code>. Crie um Controller de autenticação:</p>
<pre><code class="language-php"><?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);
}
}</code></pre>
<p>Proteja suas rotas em <code>routes/api.php</code>:</p>
<pre><code class="language-php">Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('produtos', ProdutoController);
Route::post('logout', [AuthController::class, 'logout']);
});
Route::post('login', [AuthController::class, 'login']);</code></pre>
<h2>Testes e Deployment</h2>
<h3>Testando sua API</h3>
<p>Laravel oferece suporte nativo a testes. Crie um teste:</p>
<pre><code class="language-bash">php artisan make:test ProdutoControllerTest</code></pre>
<pre><code class="language-php"><?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');
}
}</code></pre>
<p>Execute os testes com <code>php artisan test</code>. Testes garantem que sua API funciona conforme esperado conforme você evolui o código.</p>
<h2>Conclusão</h2>
<p>Você aprendeu que construir uma API REST profissional em Laravel envolve três pilares: <strong>estrutura sólida</strong> através de Models e Controllers RESTful, <strong>segurança robusta</strong> com validação e autenticação Sanctum, e <strong>confiabilidade</strong> 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.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://laravel.com/docs/11/eloquent-resources" target="_blank" rel="noopener noreferrer">Laravel Documentation - API Resources</a></li>
<li><a href="https://laravel.com/docs/11/sanctum" target="_blank" rel="noopener noreferrer">Laravel Sanctum - Token Authentication</a></li>
<li><a href="https://restfulapi.net/" target="_blank" rel="noopener noreferrer">RESTful API Design Best Practices</a></li>
<li><a href="https://laravel.com/docs/11/testing" target="_blank" rel="noopener noreferrer">Laravel Testing Documentation</a></li>
<li><a href="https://laravel.com/docs/11/eloquent" target="_blank" rel="noopener noreferrer">Eloquent ORM Guide</a></li>
</ul>