Todo framework de desenvolvimento entrega uma arquitetura padronizada com o objetivo de organizar o trabalho das equipes de projetos de software com boas práticas de programação. Com o framework Laravel isto não é diferentes, e neste artigo você terá uma visão geral dos componentes que compõem sua arquitetura.

Note que para cada componente do PHP Laravel descrito aqui, um artigo específico pode ser sugerido para aprofundamente e aprendizado no uso do mesmo.

Principais componentes da arquitetura do Laravel

A arquitetura criada para o framework foi desenvolvida de maneira modular por características.

Desta forma diversos componentes são entregues, cada qual com um objetivo e uma solução para problemas comuns no desenvolvimento de sistemas para web.

A seguir uma visão geral dos principais (ou mais usados) componentes disponíveis no core do framework Laravel:

Service Containers

Os containers de serviço Laravel são uma ferramenta poderosa para gerenciar dependências de classes e executar injeção de dependências. Por meio deles as dependências de uma determinada classe são “injetadas” (como objetos instanciados) na classe que a usará, por meio do construtor ou, em alguns casos, dos métodos “setter”.

Service Providers

Os “provedores de serviço” são o local central de todo o bootstrap (inicialização) de todos os aplicativos Laravel.

Seu próprio aplicativo construído com o framework, bem como todos os serviços principais do Laravel, são inicializados através de provedores de serviços.

Em geral isto significa: registrar ligações de contêineres de serviço - services containers, ouvintes de eventos - listeners, middlewares e até mesmo rotas. Em resumo, os provedores de serviços - service providers, são o local central para configurar seu aplicativo.

Se você abrir o arquivo config/app.php verá um array de providers configurados. São todas as classes de provedor de serviço que serão carregadas em seu aplicativo. Por padrão, um conjunto de provedores de serviços principais do Laravel estão listados neste array.

Esses provedores inicializam os componentes principais do Laravel, como o mailer, fila - queue, cache, banco de dados - database e outros. Muitos desses provedores são do tipo “provedores tardios”, o que significa que não serão carregados em todas as solicitações, mas apenas quando os serviços que fornecem forem realmente necessários.

Facades

As fachadas fornecem uma interface “estática” para as classes disponíveis no contêiner de serviço do aplicativo. O Laravel vem com muitas fachadas que fornecem acesso a quase todos os seus recursos.

As facades do Laravel servem como “proxies estáticos” para classes subjacentes no contêiner de serviço, fornecendo o benefício de uma sintaxe concisa e expressiva enquanto mantém mais testabilidade e flexibilidade do que os métodos estáticos tradicionais.

Todas as fachadas do Laravel são definidas no namespace Illuminate\Support\Facades.

Roteamento - Laravel routes

Routes são configurações que ensinam ao Laravel quais as “rotas” sua aplicação está preparada para aceitar nas requisições HTTP, e quem (ações de controladores) irá tratar cada uma delas.

Todas as rotas do Laravel são definidas em seus arquivos de rota, que estão localizados no diretório routes. Esses arquivos são carregados automaticamente pelo App\Providers\RouteServiceProvider do seu aplicativo. O arquivo routes/web.php define as rotas que são para sua interface web. Essas rotas são atribuídas ao grupo de middleware da web, que fornece recursos como estado da sessão e proteção contra CSRF. As rotas em routes/api.php não têm estado e são atribuídas ao grupo de middleware api.

Middlewares

Middlewares são um mecanismo para inspecionar e filtrar solicitações HTTP que entram em seu aplicativo. Por exemplo, o Laravel inclui um middleware que verifica se o usuário do seu aplicativo está autenticado. Caso não esteja, o middleware redirecionará o usuário para a tela de login do seu aplicativo. No entanto, se o usuário estiver autenticado, o middleware permitirá que a solicitação prossiga no fluxo de controle do aplicativo.

Você pode construir middlewares adicionais para executar uma variedade de tarefas além da autenticação. Por exemplo, um middleware de auditoria pode registrar todas as requisições HTTP recebidas em seu aplicativo.

Existem vários middlewares incluídos no framework Laravel, e estão localizados no diretório app/Http/Middleware.

Controllers

Controladores são utilizados para, em vez de definir toda a lógica de tratamento de sua solicitação como scripts ou funções anônimas em seus arquivos de rota, você pode organizar esse comportamento usando classes “controladoras” ou “controllers”.

Os controladores podem agrupar a lógica de tratamento de solicitação relacionada em uma única classe. Por exemplo, uma classe UserController pode manipular todas as solicitações de entrada relacionadas aos usuários, incluindo mostrar, criar, atualizar e excluir usuários. Por padrão, os controladores são armazenados no diretório app/Http/Controllers.

Views

Obviamente, não é prático retornar strings inteiras de documentos HTML diretamente de seus routes e controllers.

Para resolver isto, o Laravel implementa a camada de visões. As visualizações - views, fornecem uma maneira conveniente de colocar todo o seu HTML em arquivos separados. Desta maneiraq, as views separam a lógica do seu controlador / aplicativo da sua lógica de apresentação e são armazenadas no diretório resources/views.

Blade engine template

Para que você não precise misturar código PHP nas suas visões, juntamente com código HTML, o Laravel dispõe do motor de templates Blade.

Ele é um template engine simples, porém poderoso, que, ao contrário de alguns mecanismos de templates de visões de PHP, o Blade não o restringe de usar código PHP puro neles. Na verdade, todos os templates Blade são compilados em código PHP puro e armazenados em cache até serem modificados, o que significa que o Blade adiciona essencialmente zero sobrecarga ao seu aplicativo. Os arquivos de template Blade usam a extensão de arquivo .blade.php e são normalmente armazenados no diretório resources/views.

HTTP Requests

A classe Illuminate\Http\Request do Laravel fornece uma maneira orientada a objetos de interagir com a solicitação HTTP atual sendo tratada pelo seu aplicativo, bem como recuperar a entrada, cookies e arquivos que foram enviados com a requisição.

HTTP Responses

Normalmente, você não retornará apenas strings ou matrizes simples de suas ações de rota ou pelos seus controladores. Em vez disso, você retornará instâncias ou visualizações completas do objeto Illuminate\Http\Response.

Ao retornar uma instância de resposta completa, o objeto permite que você personalize o código de status HTTP da resposta e os cabeçalhos. Uma instância Response é herdada da classe Symfony\Component\HttpFoundation\Response, que fornece uma variedade de métodos para construir respostas HTTP.

Session

Como os aplicativos baseados em HTTP não mantém estado, as sessões fornecem uma maneira de armazenar informações sobre o usuário entre as requisições do cliente. Estas informações são normalmente colocadas em um armazenamento / back-end persistente que pode ser acessado a partir de solicitações subsequentes.

O Laravel vem com uma variedade de back-ends de sessão que são acessados por meio de uma API expressiva e unificada. Inclui suporte para back-ends populares, como Memcached, Redis e bancos de dados.

Validations

O Laravel fornece várias abordagens diferentes para validar os dados de entrada de sua aplicação. O mais comum é pelo uso do método de validação disponível em todas as requisições HTTP de entrada, porém o framework possibilita outras estratégias para validar e sanitizar a entrada de dados de usuários.

Ele também inclui uma ampla variedade de regras de validação que facilitam para você aplicar aos dados, até mesmo fornecendo a capacidade de validar se os valores são únicos em uma determinada tabela do banco de dados.

Além destas características avançadas na validação dos dados, ainda é possível escrever suas próprias regras para reuso em toda a aplicação.

Error handling

Quando você inicia um novo projeto Laravel, o tratamento de erros e exceções já está configurado nativamente para você em sua aplicação.

A classe App\Exceptions\Handler é onde todas as exceções lançadas por seu aplicativo são registradas e, em seguida, processadas e gerenciadas para o usuário.

Logging

Para ajudá-lo a acompanhar o que está acontecendo em sua aplicação, o Laravel fornece serviços de registro de log (históricos) robustos que permitem que você grave mensagens em arquivos, no log de erros do sistema operacional, em banco de dados, e até mesmo para o Slack para notificar sua equipe inteira.

O log do Laravel é baseado em “canais”. Cada canal representa uma maneira específica de gravar informações de registro. Por exemplo, o canal único (single) grava arquivos de log em um único arquivo de log, enquanto o canal slack envia mensagens de log ao Slack. As mensagens de log podem ser gravadas em vários canais simultâneos e com base em sua gravidade.

Por dentro, o Laravel utiliza a biblioteca Monolog, que fornece suporte para uma variedade de manipuladores de log poderosos. O Laravel facilita a configuração desses manipuladores, permitindo que você os misture e combine para personalizar o gerenciamento de log do seu aplicativo.

Database - Bancos de Dados

Praticamente todos os aplicativos da web ou de ambiente móvel modernos interagem com um banco de dados.

O Laravel torna o uso de bancos de dados para gerenciamento das informações extremamente simples, dando suporte a uma variedade de bancos de dados por meio de: SQL puro, um criador de consultas (Query Builder) fluente e o Eloquent ORM.

Atualmente, o Laravel fornece suporte nativo para quatro bancos de dados:

  • MySQL 5.7+
  • PostgreSQL 9.6+
  • SQLite 3.8.8+
  • SQL Server 2017+

Outros bancos de dados são suportados com o uso de pacotes de extensão do framework como:

Query Builder

O construtor de consultas de banco de dados (Query Builder) é um componente do Laravel que fornece interface conveniente e fluente para criar e executar consultas SQL aos banco de dados.

Ele pode ser usado para realizar a maioria das operações de banco de dados em sua aplicação e funciona perfeitamente com todos os sistemas de banco de dados suportados pelo Laravel ou estendidos com os pacotes.

O Query Builder Laravel usa ligação de parâmetros PDO (PHP Data Objects) para proteger sua aplicação contra ataques de injeção SQL - SQL injection. Portanto, não há necessidade de você se preocupar em limpar ou higienizar (sanitizar) as entradas do usuário (inputs) com as strings passadas para o construtor de consultas como ligações de consulta.

Eloquent ORM

O Laravel inclui o Eloquent, um mapeador objeto-relacional (ORM - Object Relational Mapping) que torna o uso e interação com seu banco de dados uma tarefa simples e flexível.

Ao usar o componente Laravel Eloquent, cada tabela de banco de dados possui um “Modelo” (do MVC - Model View Controller) correspondente que é usado para interagir com essa tabela.

O Eloquent é um ORM que aplica o padrão de projeto Active Record.

Além de recuperar registros da tabela do banco de dados, os modelos do Eloquent também permitem inserir, atualizar e excluir registros da tabela, de maneira direta e com alta produtividade em código.

Componentes avançados do Laravel

Além dos componentes mais comuns e essenciais para qualquer aplicação Laravel, descritos anteriormente, o framework entrega uma arquitetura rica de componentes de natureza mais avançada, permitindo a você desenvolvedor construir aplicações web de grande porte com alta produtividade e com complexidade reduzida.

A seguir apresento alguns dos componentes avançados que você pode utilizar com Laravel e são entregues nativamente pelo framework:

Console Artisan

Artisan é a interface de linha de comando incluída no Laravel.

O Artisan existe na raiz de seu aplicativo como o script artisan e fornece vários comandos úteis que podem ajudá-lo enquanto você constrói seu aplicativo.

Para ver uma lista de todos os comandos Artisan disponíveis, você pode usar o comando list na raiz do projeto:

php artisan list

Além de entregar uma série de comandos úteis com o Artisan, você pode construir seus próprios comandos em sua aplicação, tornando tarefas administrativas mais fáceis de serem executadas por linha de comnado.

Tinker (REPL)

Laravel Tinker é um REPL poderoso para o framework, desenvolvido com o pacote PsySH.

Todos os aplicativos Laravel incluem o Tinker por padrão.

O Tinker permite que você interaja com todo o seu aplicativo Laravel na linha de comando, incluindo seus modelos do Eloquent, Jobs, eventos e muito mais.

Para entrar no ambiente Tinker, execute o comando tinker do Artisan:

php artisan tinker

Broadcasting

Em muitos aplicativos modernos da Web modernos os WebSockets são usados ​​para implementar interfaces de usuário atualizadas em tempo real.

Sua utilização comum é para quando alguns dados são atualizados no servidor, uma mensagem é enviada por uma conexão WebSocket para ser recebida e tratada pelo cliente - navegador Web ou aplicação móvel.

WebSockets fornecem uma alternativa mais eficiente para consultar continuamente o servidor de seu aplicativo quanto a alterações de dados que devem ser refletidas em sua IU - interface de usuário.

Por exemplo, imagine que seu aplicativo seja capaz de exportar os dados de um usuário para um arquivo CSV e enviá-lo por e-mail.

No entanto, a criação desse arquivo CSV leva vários minutos, portanto, você opta por criar e enviar o CSV em um trabalho de uma fila - queue job.

Após o Job executar, e o CSV for criado e enviado ao usuário, podemos usar a transmissão de eventos para despachar um evento App\Events\UserDataExported que é recebido pelo JavaScript de nosso aplicativo.

Assim que o evento for recebido, podemos exibir uma mensagem para o usuário de que seu CSV foi enviado por e-mail sem que ele precise atualizar a página do navegador constantemente, ou que implementemos chamadas Ajax temporizadas perguntando ao servidor se a exportação finalizou.

Para ajudá-lo a construir recursos desta naturezaz em sua aplicação, o Laravel torna mais fácil “transmitir” seus eventos do lado do servidor através de uma conexão WebSocket.

Transmitir seus eventos Laravel permite que você compartilhe os mesmos nomes de eventos e dados entre seu aplicativo Laravel do lado do servidor e seu aplicativo JavaScript do lado do cliente.

Os conceitos básicos por trás da transmissão são simples: os clientes se conectam a canais nomeados no frontend, enquanto seu aplicativo Laravel transmite eventos para esses canais no backend. Esses eventos podem conter quaisquer dados adicionais que você deseja disponibilizar para o front-end.

Cache

Algumas das tarefas de recuperação ou processamento de dados realizadas por seu aplicativo podem exigir muito da CPU ou levar vários segundos para serem concluídas.

Para estes casos, é comum armazenar em cache os dados recuperados por um determinado espaço de tempo para que possam ser recuperados rapidamente em solicitações subsequentes para os mesmos contextos de dados.

Os dados em cache geralmente são persistidos em um armazenamento de dados muito rápido, como Memcached ou Redis.

Felizmente, o Laravel fornece uma API expressiva e unificada para vários back-ends de cache, permitindo que você aproveite a recuperação de dados extremamente rápida e acelere sua aplicação web.

Coleções - Collections

A classe Illuminate\Support\Collection fornece um wrapper (agregador ou invólucro) conveniente e fluente para trabalhar com matrizes e vetores de dados.

Por exemplo, verifique o código a seguir. Usaremos o helper collect para criar uma nova instância de coleção da array, executar a função strtoupper em cada elemento e, em seguida, remover todos os elementos vazios:

$collection = collect(['ademir', 'alexsandra', null])->map(function ($name) {
    return strtoupper($name);
})->reject(function ($name) {
    return empty($name);
});

Como você pode ver, a classe Collection permite que você encadeie seus métodos (chain of methods) para realizar o mapeamento e a redução fluentes da array subjacente. Em geral, as coleções são imutáveis, o que significa que cada método Collection retorna uma instância de Collection inteiramente nova.

Eventos

Os eventos do Laravel fornecem uma implementação do padrão de projeto de Observer, permitindo que você se inscreva e escute vários eventos que ocorrem dentro de sua aplicação.

As classes de eventos são normalmente armazenadas no diretório app/Events, enquanto seus ouvintes são armazenados em app/Listeners.

Os eventos servem como uma ótima maneira de desacoplar vários aspectos do seu aplicativo, já que um único evento pode ter vários ouvintes que não dependem uns dos outros.

Por exemplo, você pode enviar uma notificação do Slack ao seu usuário sempre que um pedido for realizado. Em vez de acoplar seu código de processamento de pedido ao código de notificação do Slack, você pode gerar um evento App\Events\OrderShipped que um ouvinte pode receber e usar para executar a lógica de envio de uma notificação do Slack.

File Storage

O Laravel fornece um poderoso componente de abstração de sistema de arquivos, graças ao pacote Flysystem PHP de Frank de Jonge.

A integração do Laravel Flysystem fornece drivers simples para trabalhar com sistemas de arquivos locais, SFTP e Amazon S3.

É incrivelmente simples alternar entre essas opções de armazenamento entre a máquina de desenvolvimento local e o servidor de produção, pois a API permanece a mesma chamada para cada sistema.

Dentro do arquivo de configuração do componente, você pode configurar todos os “discos” do seu sistema de arquivos. Cada disco representa um driver de armazenamento e local de armazenamento específicos.

Configurações de exemplo para cada driver suportado estão incluídas no arquivo de configuração para que você possa modificar a configuração para refletir suas preferências de armazenamento e credenciais.

Por exemplo, o driver local interage com os arquivos armazenados localmente no servidor que executa o aplicativo Laravel enquanto o driver s3 é usado para gravar no serviço de armazenamento em nuvem S3 da Amazon.

HTTP Client

O Laravel fornece uma API mínima e expressiva em torno do cliente Guzzle HTTP, permitindo que você faça solicitações HTTP para se comunicar com outras aplicações web.

O wrapper do Laravel em torno do Guzzle concentra-se em seus casos de uso mais comuns e em uma experiência de desenvolvedor facilitada.

Localization

Os recursos de localização do Laravel fornecem uma maneira conveniente de recuperar strings em vários idiomas, permitindo que você suporte facilmente várias línguas em seu aplicativo.

Ele oferece duas maneiras de gerenciar strings de tradução.

Primeiro, as strings de idioma podem ser armazenadas em arquivos no diretório resources/lang.

Nesse diretório, pode haver subdiretórios para cada idioma suportado pelo aplicativo. Esta é a abordagem que o Laravel usa para gerenciar strings de tradução para recursos integrados do Laravel, como mensagens de erro de validação.

A outra maneira são as strings de tradução que podem ser definidas em arquivos JSON que são colocados no diretório resources/lang.

Ao adotar essa abordagem, cada idioma suportado por seu aplicativo teria um arquivo JSON correspondente neste diretório. Essa abordagem é recomendada para aplicativos que têm um grande número de strings traduzíveis.

Mail

Enviar e-mail não precisa ser complicado, por isso o Laravel fornece uma API de e-mail limpa e simples desenvolvida pela popular biblioteca SwiftMailer.

Laravel e SwiftMailer fornecem drivers para envio de e-mail via SMTP, Mailgun, Postmark, Amazon SES e sendmail, permitindo que você comece a enviar e-mails rapidamente através de um serviço local ou baseado em nuvem de sua escolha.

Notifications

Além do suporte para envio de e-mail, o Laravel oferece suporte para envio de notificações através de uma variedade de canais de entrega, incluindo e-mail, SMS (via Vonage, anteriormente conhecido como Nexmo) e Slack.

Além disso, uma variedade de canais de notificação criados pela comunidade estão disponíveis como pacotes e podem fornecer envios de notificações para dezenas de canais diferentes.

As notificações também podem ser armazenadas em um banco de dados para que possam ser exibidas em sua interface da web.

Normalmente, as notificações devem ser mensagens curtas e informativas que notificam os usuários sobre algo que ocorreu em seu aplicativo. Por exemplo, se você estiver escrevendo um aplicativo de faturamento, poderá enviar uma notificação de “Fatura paga” para seus usuários por meio dos canais de e-mail e SMS.

Desenvolvimento de Pacotes

Os pacotes são a principal forma de adicionar funcionalidade ao Laravel estendendo suas funções nativas.

Os pacotes podem resolver qualquer problema de software, desde uma ótima maneira de trabalhar com datas como Carbon ou um pacote que permite a você associar arquivos a modelos do Eloquent como a biblioteca de mídia Laravel do Spatie.

Existem diferentes tipos de pacotes. Alguns pacotes são independentes, o que significa que funcionam com qualquer estrutura PHP. Carbon e PHPUnit são exemplos de pacotes independentes. Qualquer um desses pacotes pode ser usado com o Laravel, basta inserí-los nos requires de em seu arquivo composer.json.

Por outro lado, outros pacotes são especificamente planejados para uso com o Laravel. Esses podem ter rotas, controladores, visões e configurações especificamente destinadas a aprimorar um aplicativo Laravel.

Tudo isto significa que você pode escrever pacotes com lógicas ou módulos reaproveitáveis dentro de sua empresa, ou até mesmo distribuí-los para iso pela comunidade.

Queues - Filas de execução

Ao construir seu aplicativo da web, você pode ter algumas tarefas que demoram para serem executadas nas requisições HTTP, como analisar e armazenar um arquivo CSV.

O Laravel possibilita que sejam criadas filas de execução “tardia”, permitindo que você crie trabalhos enfileirados que podem ser processados ​​em segundo plano.

Ao mover tarefas demoradas para uma fila, seu aplicativo pode responder às requisições HTTP da web com alta velocidade e fornecer uma melhor experiência de usuário aos seus clientes.

As filas do Laravel fornecem uma API de enfileiramento unificada em uma variedade de back-ends de filas diferentes, como Amazon SQS, Redis ou mesmo um banco de dados relacional.

As opções de configuração de fila do Laravel são armazenadas no arquivo de configuração config/queue.php de sua aplicação.

Neste arquivo, você encontrará configurações de conexão para cada um dos drivers de fila incluídos na estrutura, como banco de dados, drivers Amazon SQS, Redis e Beanstalkd, bem como um driver síncrono que executará trabalhos imediatamente (para uso durante desenvolvimento local).

Um driver de fila nula também está incluído, para ser usado em testes sendo que descarta os trabalhos enfileirados.

Agendamento de tarefas - Task Scheduling

É provável que você tenha escrito um script de configuração do cron para cada tarefa que precisava agendar em seu servidor. No entanto, isso pode rapidamente se tornar complexo de gerenciar porque sua programação de tarefas não está no mesmo local de controle de origem do sistema, sendo assim você deve usar o SSH em seu servidor para visualizar suas entradas cron existentes ou adicionar entradas adicionais.

O agendador de comandos do Laravel oferece uma nova abordagem para gerenciar tarefas agendadas em seu servidor.

O agendador permite que você defina de forma fluente e expressiva sua agenda de comandos dentro de seu próprio aplicativo Laravel.

Ao usar o scheduler do Laravel, apenas uma única entrada cron é necessária em seu servidor.

Desta maneira, sua programação de tarefas de execução periódica é definida no método de programação do arquivo app/Console/Kernel.php.

Testes - Automated testing

O Laravel foi construído com os testes em mente.

Na verdade, o suporte para teste com PHPUnit está incluído “out of the box” no arquivo phpunit.xml, e já está configurado para seu aplicativo.

O framework também fornece métodos auxiliares convenientes que permitem que você teste expressivamente seus aplicativos.

Por padrão, o diretório de testes do seu aplicativo contém dois subdiretórios: Feature e Unit.

Os testes de unidade são testes que se concentram em uma parte muito pequena e isolada de seu código. Na verdade, a maioria dos testes de unidade provavelmente se concentra em um único método. Testes dentro do seu diretório de teste “Unit” não inicializam seu aplicativo Laravel e, portanto, não podem acessar o banco de dados de seu aplicativo ou outros serviços do framework.

Os testes de recursos - Feature, podem testar uma parte maior do seu código, incluindo como vários objetos interagem entre si ou até mesmo uma solicitação HTTP completa para um endpoint JSON.

Geralmente, a maioria dos seus testes devem ser testes de recursos ou de funcionalidades do sistema. Esses tipos de teste fornecem a maior confiança de que o sistema como um todo está funcionando conforme o esperado.

Considerações finais

O framework Laravel é uma excelente adição para qualquer stack de desenvolvimento de aplicações Web baseado em linguagem de programação PHP.

Neste artigo eu apresentei os componentes mais comuns no uso de aplicações desenvolvidas com Laravel, bem como parte dos componentes avançados que podem facilitar a escalabilidade de seus sistemas sem necessariamente responsabilizar você desenvolvedor a implementar toda complexidade de lógica necessária para isto.