Top 8 best practices in Laravel and one extra tip

Developing great applications must be a common goal we should work together for!

Felix Gomez
5 min readOct 15, 2022
Photo by Martin Shreder on Unsplash

Part of coding is knowing what are the best concepts and practices out there in the technologies we are using. In this article, you will find some good practices that can improve your code’s readability, maintainability, and speed. All of the following concepts come from what I have learned by reading Laravel’s documentation and following different experts in the framework and the area, which have helped me to build good and efficient applications, for which I want to share with you these tricks.

1. 🥇 Single responsibility principle

The first SOLID principle proposes that classes and methods should only have one responsibility, otherwise we could risk the code being highly coupled. In Laravel, we can use IoC in classes or accessors in Eloquent to efficiently handle it.

Bad:

Request validation inside store function in UserController

Good:

Request validation inside a StoreUserRequest, used in store function in UserController

2. 🆘 Controllers for routes & Services for business logic

Controllers should be directly correlated to the response/request flow, and each one of the methods inside a controller class should be accessed only by a route. Moreover, controllers should have only one responsibility, hence, the general business logic is better located inside Services.

Bad:

Every function is inside UserController

Good:

The function for routes is inside UserController, and the function to store a profile photo goes into MediaService

3. 🥠 Fat models, skinny controllers, & fat services

Models should have all the DB-related logic, which you can achieve simply by using scopes, relationships, casting, and accessors. Controllers should have the request/response flow, like validations, conversions, and resources (which you should move out to specific classes too). And Services should have whatever is left; however, not everything should be inside one Service but split logic into different services as per SRP.

Bad:

Query logic inside the UserController

Good:

Query logic inside the User model, and use of scopes for DRY

4. 🫙 The Laravel service container is here for us

Laravel has a service container built-in to manage all the class dependencies and efficiently perform dependency injection. It’s really useful when you use Services, inject a Model in the request, or want to use the repository pattern for better scalability and testability.

Bad:

UserController is using Eloquent to find a user

Good:

UserController uses UserRepository, which probably uses Eloquent to find a user

5. 🏗️ Eloquent over raw SQL

Eloquent is a powerful object-relational mapper (ORM), that helps developers to write beautiful, readable, and maintainable code with ease. It has multiple built-in features such as scopes, relationships, soft deletes, events, etc. Whenever you have to access the DB, try to use Eloquent, and only if it’s needed for a particular case, use raw SQL, but most of the time you will find a way to do it with Eloquent.

Bad:

Raw query

Good:

Eloquent query

Small note here: Eloquent can be slower than Raw SQL, however, the readability and maintainability that you can get with Eloquent surpass the response time. Moreover, you can always increase your application speed by using Cache, so in reality, Eloquent won’t speed won’t matter.

6. 🕵️‍♀️ Constants and language files instead of hardcoded text

Moving the hardcoded text into centralized places increases the maintainability, readability, and scalability of the code. For example, if you use built-in localization from the project’s beginning, you are guaranteed to be able to move to a different language in the future.

Bad:

Hardcoded text in a model and a controller

Good:

Use of constants and localization in a model and a controller

7. 🎣 Get .env data from config instead of .env

Using config files allows you to have a better-centralized control over .env, which you can extend further by splitting concerns into different files (that’s how Laravel does it). Moreover, you would usually cache your files in production which causes using env() to be useless as it will return null instead of the actual value, however, config() will still return the right value.

Bad:

Access env directly from a controller

Good:

Access env in config and then config directly from a controller

8. 🥋 Use Jobs to handle heavy tasks

Heavy tasks block the code execution and reduce the response times for your server. Moving those CPU-consuming tasks to Queues and dispatching them through Jobs can improve the user experience and increase your server's usability.

Bad:

Heavy tasks are done synchronously once the request is received by the controller

Good:

Heavy tasks are dispatched to queues once the request is received by the controller

Extra — Use Inertia + Vue instead of Blade

I recommend using Vue instead of Blade as you have more powerful control over your templates, and if you ever want to migrate from a monolithic approach to a different architecture it will be easier than having everything on Blade.

Inertia is a powerful bridge between Laravel and Vue, that allows you to have a monolithic architecture by rendering Inertia Responses (Vue Pages) instead of Blades views. Moreover, Inertia has multiple built-in features that can help you develop your application faster such as SSR, share data, form helpers, etc.

At last, as Laravel itself recommends, if you want to start a project with the boilerplate already done for you, take a look at Jetstream, you can select between Livewire + Blade and Inertia + Vue, and it has cool features for teams management, API support, 2FA, registration, sessions, and more.

Stay tuned for more articles like this one. If you would like me to write about something, in particular, let me know in the comments.

I am a lover of learning, so I would love to read your opinions and any feedback to continue my learning path, please go and leave a comment!

Thanks for reading this article and let’s create a better world together! ❤

Follow for more and share it if you liked it 😊

--

--

Felix Gomez

Mechatronics Engineer | 12+ years programming | Pianist | Scientist | I know one or two things about everything, and I like to share my knowledge with everyone