DEV Community

Cover image for Minha arquitetura API no Laravel
Jhonatan Henkel
Jhonatan Henkel

Posted on

Minha arquitetura API no Laravel

Faz um tempo que não escrevo mais aqui, mas vamos lá, hoje vamos conversar sobre a arquitetura que eu uso no Laravel.

A estrutura de pastas e arquivos que eu desenvolvi ao longo do tempo me ajudou a ganhar agilidade desenvolvendo no dia a dia.

Estrutura de pasta

projeto
|--app
| |--Infra
| |--Models
| |--Modules
|--config
| |--develop
| |--prod

Fora do padrão que temos do Laravel ao dar o start, tenho essa estrutura.

Em Infra, deixo tudo que se aplica a escopo global da aplicação, como por exemplo, controllers a serem estendidos, validadores de requisições, enums, abstrações uteis (email, sentry), middle wares e outras coisas mais...

Em Models, fica os models do Laravel, organizados por módulo, então se eu tenho um model de usuário e outro de endereço do usuário, ambos ficam na pasta User.

Em módules fica todos os módulos separados por pasta, de forma clara a qual módulo estamos trabalhando. Dentro de cada módulo tenho as pastas referente a controllers, enum, use cases e demais itens específicos para esse módulo.

As pastas develop e prod, eu deixo os docker files, docker compose, configurações do opcache, etc...

Controllers

Eu gosto de trabalhar com controllers basic para fazer todo o trabalho repetitivo. Dentro de Infra/Controllers tenho um controller basic para cada ação do CRUD.

Exemplo de controller basic:

abstract class BaseCreateController extends Controller
{
    abstract protected function getUseCase(): ICreateUseCase;
    abstract protected function getRules(): array;
    abstract protected function getModelName(): string;

    public function __invoke(Request $request): JsonResponse
    {
        ForbiddenException::validatePolicy(GatesAbilityEnum::Create, $this->getModelName());
        Validator::validateRequest($request, $this->getRules());
        $result = $this->getUseCase()->execute($request->json()->all());
        if ($result) {
            return ResponseApi::renderCreated($result);
        }
        return ResponseApi::renderInternalServerError('Erro ao inserir item.');
    }
}
Enter fullscreen mode Exit fullscreen mode

Por esse controller, já temos todas as tratativas para exceptions de request inválida e falta de acesso ao endpoint, tratados no middle ware do Laravel.

O controller de um módulo fica assim:

class ClientCreateController extends BaseCreateController
{
    public function __construct(protected ClientCreateUseCase $useCase)
    {
    }

    protected function getUseCase(): ICreateUseCase
    {
        return $this->useCase;
    }

    protected function getRules(): array
    {
        return [
            // regras do json de request
        ];
    }

    protected function getModelName(): string
    {
        return Client::class;
    }
}
Enter fullscreen mode Exit fullscreen mode

Use Cases

Todo use case implementa uma interface, para garantir a comunicação correta com o controller.

O use case do controller acima, ficaria assim:

class ClientCreateUseCase implements ICreateUseCase
{
    public function execute(array $data): array
    {
        $client = Client::create([
            // campos
        ]);
        return $client->toArray();
    }
}
Enter fullscreen mode Exit fullscreen mode

Dessa forma, com poucos arquivos, temos uma estrutura robusta e fácil de se trabalhar, já que não precisarei me preocupar com padrão de response, validar request e acesso do usuário. Isso tudo já fica abstraído no controller base.

O máximo que terei que fazer é criar e registrar policy para o módulo.

Por hoje é só pessoal. Até a próxima.

Heroku

Deploy with ease. Manage efficiently. Scale faster.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay