Construindo uma API REST Completa com Laravel na Prática Já leu

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 e navegue até o diretório do projeto. Configure seu arquivo com as credenciais do banco de dados. Execute 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: Edite a migration criada em : Execute . Seu Model já existe com proteções padrão: Controllers RESTful Gere um Controller de recurso com . Isso cria automaticamente os

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.

Referências


Artigos relacionados