Every development framework delivers standardized architecture to organize the activity of software project teams with good programming practices. With Laravel framework this is no different, and in this article you will have an overview of the components that make up your architecture.
Note that for each component of the Laravel PHP described here, a specific article may be suggested for deepening and learning in the use of it.
If you don’t know the Laravel framework, start with the article:
Main elements of Laravel Architecture
The architecture created for the framework was modularly developed by characteristics.
Thus several components are delivered, each with a goal and a solution to common problems in the development of web softwares.
Next an overview of the main (or more used) components available in the core of the Laravel framework:
Service Containers
Laravel service containers are a powerful tool for managing class dependencies and performing dependency injection.Through them the dependencies of a particular class are “injected” (as instant objects) in the class that will use it, through the builder or, in some cases, the “setter” methods.
Service Providers
The service providers are the central place for all bootstrapping of Laravel applications.
Your own application built with the framework, as well as all of Laravel’s core services, are initialized through service providers.
In general, this means registering service container bindings, event listeners, middleware, and even routes. In summary, service providers are the central location for configuring your application.
If you open the config/app.php
file, you’ll see an array of configured providers. These are all of the service provider classes that will be loaded in your application. By default, a set of Laravel’s core service providers are listed in this array.
These providers initialize Laravel’s core components like the mailer, queue, cache, database, and others. Many of these providers are “deferred providers”, meaning they won’t be loaded on every request but only when the services they provide are actually needed.
Facades
The facades provide a “static” interface to the classes available in the application’s service container. Laravel comes with many facades that provide access to almost all of its resources.
Laravel’s facades serve as “static proxies” to underlying classes in the service container, providing the benefit of a concise and expressive syntax while maintaining more testability and flexibility than traditional static methods.
All Laravel facades are defined in the Illuminate\Support\Facades
namespace.
Routing - Laravel routes
Routes are configurations that teach Laravel which “routes” your application is prepared to accept in HTTP requests, and who (controller actions) will handle each one of them.
All Laravel routes are defined in its route
files, which are located in the routes directory. These files are automatically loaded by your application’s App\Providers\RouteServiceProvider
. The routes/web.php
file defines the routes that are for your web interface. These routes are assigned to the web middleware group, which provides resources such as session state and CSRF protection. The routes in routes/api.php have no state and are assigned to the api middleware group.
Middlewares
Middlewares are a mechanism for inspecting and filtering HTTP requests that enter your application. For example, Laravel includes a middleware that checks if the user of your application is authenticated. If not, the middleware will redirect the user to the login screen of your application. However, if the user is authenticated, the middleware will allow the request to proceed in the application’s control flow.
You can build additional middlewares to perform a variety of tasks beyond authentication. For example, an auditing middleware can log all HTTP requests received in your application.
There are several middlewares included in the Laravel framework, and they are located in the app/Http/Middleware
directory.
Controllers
Controllers are used so that instead of defining all the request handling logic as scripts or anonymous functions in your route files, you can organize this behavior using “controller” classes.
Controllers can group related request handling logic into a single class. For example, a UserController class can handle all incoming requests related to users, including displaying, creating, updating, and deleting users. By default, controllers are stored in the app/Http/Controllers
directory.
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
So that you don’t have to mix PHP code in your views, along with HTML code, Laravel provides the Blade template engine.
It is a simple yet powerful template engine that, unlike some PHP view template engines, does not restrict you from using pure PHP code in them. In fact, all Blade templates are compiled into pure PHP code and cached until modified, which means that Blade essentially adds zero overhead to your application. Blade template files use the .blade.php
file extension and are typically stored in the resources/views
directory.
HTTP Requests
The Illuminate\Http\Request
class in Laravel provides an object-oriented way to interact with the current HTTP request being handled by your application, as well as retrieve input, cookies, and files that were sent with the request.
HTTP Responses
Typically, you won’t just return strings or simple arrays from your route actions or controllers. Instead, you’ll return instances or full views of the Illuminate\Http\Response
object.
By returning a complete response instance, the object allows you to customize the HTTP status code of the response and headers. A Response instance is inherited from the Symfony\Component\HttpFoundation\Response
class, which provides a variety of methods to construct HTTP responses.
Session
Since HTTP-based applications do not maintain state, sessions provide a way to store information about the user between client requests. This information is typically placed in a persistent storage/backend that can be accessed from subsequent requests.
Laravel comes with a variety of session backends that are accessed through an expressive and unified API. It includes support for popular backends such as Memcached, Redis, and databases.
Validations
Laravel provides several different approaches to validate the input data of your application. The most common is through the validation method available on all incoming HTTP requests, but the framework also enables other strategies to validate and sanitize user input data.
It also includes a wide variety of validation rules that make it easy for you to apply to the data, even providing the ability to validate if the values are unique in a specific database table.
In addition to these advanced features in data validation, it is still possible to write your own rules for reuse throughout the application.
Error handling
When you start a new Laravel project, error and exception handling is already natively configured for you in your application.
The App\Exceptions\Handler
class is where all exceptions thrown by your application are registered and then processed and managed for the user.
Logging
To help you keep track of what’s happening in your application, Laravel provides robust logging services that allow you to record messages in files, the operating system’s error log, a database, and even to Slack to notify your entire team.
Laravel’s log is based on “channels”. Each channel represents a specific way of logging information. For example, the single channel logs log files to a single log file, while the slack channel sends log messages to Slack. Log messages can be recorded on multiple channels simultaneously and based on their severity.
Under the hood, Laravel uses the Monolog library, which provides support for a variety of powerful log handlers. Laravel makes it easy to configure these handlers, allowing you to mix and match them to customize your application’s log management.
Database
Almost all modern web or mobile applications interact with a database.
Laravel makes the use of databases for information management extremely simple, supporting a variety of databases through: raw SQL, a fluent query builder, and the Eloquent ORM.
Currently, Laravel provides native support for four databases:
- MySQL 5.7+
- PostgreSQL 9.6+
- SQLite 3.8.8+
- SQL Server 2017+
Other databases are supported using extension packages of the framework such as:
- Sybase ASE / SQLAnywhere, with the package developed by the State University of Ponta Grossa - UEPG, available at: https://github.com/uepg/laravel-sybase
- MongoDB, with the package developed by Jens Segers, available at: https://github.com/jenssegers/laravel-mongodb
Query Builder
The Database Query Builder is a Laravel component that provides a convenient and fluent interface for creating and executing SQL queries to the database.
It can be used to perform most database operations in your application and works seamlessly with all database systems supported by Laravel or extended with packages.
The Laravel Query Builder uses parameter binding through PDO (PHP Data Objects) to protect your application against SQL injection attacks. Therefore, you don’t need to worry about cleaning or sanitizing user inputs with strings passed to the query builder as query bindings.
Eloquent ORM
Laravel includes Eloquent, an Object-Relational Mapping (ORM) that makes using and interacting with your database a simple and flexible task.
When using the Laravel Eloquent component, each database table has a corresponding “Model” (from the MVC - Model View Controller) that is used to interact with that table.
Eloquent is an ORM that applies the Active Record design pattern.
In addition to retrieving records from the database table, Eloquent models also allow for direct and highly productive insertion, updating, and deletion of records in the table.
Advanced components of Laravel
In addition to the most common and essential components for any Laravel application, described earlier, the framework delivers a rich architecture of more advanced elements, allowing you as a developer to build large-scale web applications with high productivity and reduced complexity.
The following are some of the advanced components that you can use with Laravel and are natively delivered by the framework:
Console Artisan
Artisan is the command-line interface included in Laravel.
Artisan exists at the root of your application as the artisan
script and provides various useful commands that can help you as you build your application.
To see a list of all available Artisan commands, you can use the list
command at the root of the project:
php artisan list
In addition to delivering a series of useful commands with Artisan, you can build your own commands in your application, making administrative tasks easier to run via command line.
Tinker (REPL)
Laravel Tinker is a powerful REPL for the framework, developed with the PsySH package.
All Laravel applications include Tinker by default.
Tinker allows you to interact with your entire Laravel application on the command line, including your Eloquent models, Jobs, events, and much more.
To enter the Tinker environment, run the tinker
command of Artisan:
php artisan tinker
Broadcasting
In many modern web applications, WebSockets are used to implement real-time updated user interfaces.
Their common use is for when some data is updated on the server, a message is sent over a WebSocket connection to be received and handled by the client - web browser or mobile application.
WebSockets provide a more efficient alternative to continuously querying your application’s server for data changes that need to be reflected in its UI - user interface.
For example, imagine that your application is capable of exporting a user’s data to a CSV file and sending it via email.
However, creating this CSV file takes several minutes, so you opt to create and send the CSV in a queue job.
After the job runs and the CSV is created and sent to the user, we can use event broadcasting to dispatch an App\Events\UserDataExported
event that is received by our application’s JavaScript.
As soon as the event is received, we can display a message to the user that their CSV has been sent via email without them having to constantly refresh the browser page or implement timed Ajax calls asking the server if the export has completed.
To help you build features of this nature in your application, Laravel makes it easy to “broadcast” your server-side events over a WebSocket connection.
Broadcasting your Laravel events allows you to share the same event names and data between your server-side Laravel application and your client-side JavaScript application.
The basic concepts behind broadcasting are simple: clients connect to named channels on the frontend, while your Laravel application broadcasts events to these channels on the backend. These events can contain any additional data you want to make available to the front-end.
Cache
Some data retrieval or processing tasks performed by your application may require a lot of CPU or take several seconds to complete.
For these cases, it is common to cache the data retrieved for a certain amount of time so that they can be quickly retrieved in subsequent requests for the same data contexts.
Cached data is usually persisted in a very fast data store, such as Memcached or Redis.
Fortunately, Laravel provides an expressive and unified API for various cache back-ends, allowing you to take advantage of extremely fast data retrieval and speed up your web application.
Collections
The Illuminate\Support\Collection
class provides a convenient and fluent wrapper for working with arrays and data vectors.
For example, consider the following code. We will use the collect helper to create a new collection instance from an array, execute the strtoupper function on each element, and then remove all empty elements:
$collection = collect(['ademir', 'alexsandra', null])->map(function ($name) {
return strtoupper($name);
})->reject(function ($name) {
return empty($name);
});
As you can see, the Collection
class allows you to chain your methods for fluent mapping and reduction of the underlying array. In general, collections are immutable, which means that each Collection
method returns an entirely new Collection
instance.
Events
Laravel events provide an implementation of the Observer design pattern, allowing you to subscribe and listen to various events that occur within your application.
Event classes are usually stored in the app/Events
directory, while their listeners are stored in app/Listeners
.
Events serve as a great way to decouple various aspects of your application since a single event can have multiple listeners that don’t depend on each other.
For example, you can send a Slack notification to your user whenever an order is placed. Instead of coupling your order processing code with the Slack notification code, you can generate an App\Events\OrderShipped
event that a listener can receive and use to perform the logic for sending a Slack notification.
File Storage
Laravel provides a powerful file system abstraction component, thanks to Frank de Jonge’s PHP package Flysystem.
Laravel Flysystem integration provides simple drivers to work with local file systems, SFTP, and Amazon S3.
It is incredibly easy to switch between these storage options between the local development machine and the production server, as the API remains the same call for each system.
Inside the component configuration file, you can configure all of your file system’s “disks”. Each disk represents a specific storage driver and storage location.
Example settings for each supported driver are included in the configuration file so that you can modify the configuration to reflect your storage preferences and credentials.
For example, the local driver interacts with files stored locally on the server that runs the Laravel application, while the s3 driver is used to write to Amazon’s S3 cloud storage service.
HTTP Client
Laravel provides a minimal and expressive API around the Guzzle HTTP client, allowing you to make HTTP requests to communicate with other web applications.
Laravel’s wrapper around Guzzle focuses on its most common use cases and on an easy-to-use developer experience.
Localization
The localization features of Laravel provide a convenient way to retrieve strings in multiple languages, allowing you to easily support multiple languages in your application.
It offers two ways to manage translation strings.
Firstly, language strings can be stored in files in the resources/lang directory.
In this directory, there may be subdirectories for each language supported by the application. This is the approach that Laravel uses to manage translation strings for Laravel built-in resources, such as validation error messages.
The other way is translation strings that can be defined in JSON files that are placed in the resources/lang directory.
By adopting this approach, each language supported by your application would have a corresponding JSON file in this directory. This approach is recommended for applications that have a large number of translatable strings.
Sending emails doesn’t have to be complicated, so Laravel provides a clean and simple email API developed by the popular SwiftMailer library.
Laravel and SwiftMailer provide drivers for sending emails via SMTP, Mailgun, Postmark, Amazon SES, and sendmail, allowing you to quickly start sending emails through a local or cloud-based service of your choice.
Notifications
In addition to support for email sending, Laravel offers support for sending notifications through a variety of delivery channels, including email, SMS (via Vonage, previously known as Nexmo), and Slack.
In addition, a variety of community-created notification channels are available as packages and can provide notification deliveries for dozens of different channels.
Notifications can also be stored in a database so that they can be displayed in your web interface.
Notifications should typically be short and informative messages that notify users about something that has occurred in your application. For example, if you are writing a billing application, you might send a “Invoice Paid” notification to your users through email and SMS channels.
Package Development
Packages are the primary way to add functionality to Laravel by extending its native functions.
Packages can solve any software problem, from a great way to work with dates like Carbon to a package that allows you to associate files with Eloquent models like the Spatie Laravel Media Library.
There are different types of packages. Some packages are independent, meaning they work with any PHP framework. Carbon and PHPUnit are examples of independent packages. Any of these packages can be used with Laravel, just include them in your composer.json file’s requires.
On the other hand, other packages are specifically planned for use with Laravel. These can have routes, controllers, views, and configurations specifically aimed at enhancing a Laravel application.
All of this means that you can write packages with reusable logics or modules within your company, or even distribute them for this within the community.
Queues
When building your web application, you may have some tasks that take a long time to execute during HTTP requests, such as parsing and storing a CSV file.
Laravel enables you to create “delayed” execution queues, allowing you to create queued jobs that can be processed in the background.
By moving time-consuming tasks to a queue, your application can respond to web HTTP requests at high speed and provide a better user experience to your customers.
Laravel’s queues provide a unified queuing API across a variety of different queue back-ends, such as Amazon SQS, Redis, or even a relational database.
The Laravel queue configuration options are stored in your application’s config/queue.php
configuration file.
In this file, you will find connection settings for each of the queue drivers included in the framework, such as database, Amazon SQS drivers, Redis, and Beanstalkd, as well as a synchronous driver that will execute jobs immediately (for use during local development).
A null queue driver is also included, which can be used in testing and discards queued jobs.
Task Scheduling You may have written a cron configuration script for every task that needed to be scheduled on your server. However, this can quickly become complex to manage because your task scheduling isn’t in the same source control location as your system, so you have to use SSH on your server to view your existing cron entries or add additional entries.
The Laravel command scheduler offers a new approach to managing scheduled tasks on your server.
The scheduler allows you to fluently and expressively define your command schedule within your own Laravel application.
By using Laravel’s scheduler, only a single cron entry is required on your server.
This way, your schedule of periodic execution tasks is defined in the scheduling method of the app/Console/Kernel.php
file.
Automated testing
Laravel was built with testing in mind.
In fact, support for testing with PHPUnit is included “out of the box” in the phpunit.xml
file, and is already configured for your application.
The framework also provides convenient helper methods that allow you to expressively test your applications.
By default, your application’s test directory contains two subdirectories: Feature and Unit.
Unit tests are tests that focus on a very small and isolated part of your code. In fact, most unit tests probably focus on a single method. Tests within your “Unit” test directory do not initialize your Laravel application and therefore cannot access your application’s database or other framework services.
Resource tests - Feature - can test a larger part of your code, including how various objects interact with each other or even a complete HTTP request to a JSON endpoint.
Generally, most of your tests should be resource or system functionality tests. These types of tests provide the greatest confidence that the system as a whole is working as expected.
Final considerations
The Laravel framework is an excellent addition to any PHP-based web application development stack.
In this article, I presented the most common components in the use of applications developed with Laravel, as well as some of the advanced components that can facilitate the scalability of your systems without necessarily requiring you as a developer to implement all the necessary complexity of logic for this.
Comments