Why Laravel apps don’t scale well (I)
People use to say Laravel apps do not scale well, but after working with Laravel for some time are reviewing a lot of projects, I think is not totally Laravel fault. Indeed, you can do great apps with Laravel the same as with Symonfy, but is more easier to succeed with Symonfy than using Laravel. The problem? Laravel “magic”.
I’m not going to talk about the need for DDD or Hexagonal architecture to build scalable apps. Although I prefer DDD, there is a lot of controversy about this topic and I just want to center on classic MVC.
I will try to put some examples of what I have found.
Let’s say we have a Product Entity.
class Product extends Model
{
protected $fillable = [
'id',
'title',
'price'
];
And we have a Controller with this code:
public function updateOrCreate($ean, $title, $price)
{
$product = Product::query()->where(['ean' => $ean])->first();
if (null === $product) {
Product::make(['ean' => $ean, 'title' => $title, 'price' => $price]);
} else {
$product->ean = $ean;
$product->title = $title;
$product->price = $price;
$product->save();
}
}
Later on, we found that in the DataBase there are products without price, and we want to find what is the cause of the problem.
With this kind of code, we can not ask the IDE (Phpstorm or VS) to find where Products are created and where the price is set.
You may say this is not a Laravel problem, as you may have the same problem in every framework… not so.
Let’s fix this do it safer:
/**
* @property string $ean
* @property string $title
* @property float $price
* @method static self make(array $data)
*/
class Product extends Model
First, we will indicate the properties of the model. In Laravel is optional, in Symfony and Yii2 mandatory.
The next thing is to indicate that method make exists.
With this, the IDE knows where ::make is used, and where the price is set and read.
Let’s continue:
/** @var Product|null $product */
$product = Product::query()->where(['ean' => $ean])->first();
We need to tell the IDE that $product is a Product or null, because first() did not specify the return type.
We can create a custom QueryBuilder for each model, so we don’t have to comment every time we use it.
What is the main problem when developing large apps?
The real problem with large apps is that they have more chance to have a lot of changes in the future and of course more issues.
So, developing a large app is not complex, the real problem is maintaining it over time.
Imagine having 100 models, tons of controllers, and discovering that your $price attribute is changed in 20 places, where the IDE can not find. You can spend days solving the problem.
And what about adding a new feature?
How do you know the impact of what you are doing, if you don’t know where the model is used.
Summary
Laravel is not bad for scaling apps, but it makes it much easier for a bad dev, to continue being a bad dev.