Switch Your Lumen Application to Laravel

Ahmad Masabni
Insider Engineering
6 min readApr 3, 2023

In this blog post, we will explain why and how to switch our lumen applications to Laravel.

Lumen is a perfect candidate for building scalable and high-performance APIs in PHP. Until it isn’t!!

Lumen came out back in 2015 as a lighter, faster version of Laravel. The goal was to be able to use it when speed was super important on a project or API. Since that release, Laravel itself has been getting faster and faster, and new things such as Laravel Octane have come out which actually makes it faster than Lumen.

Another reason to not use Lumen, in Feb 2022, it was removed from the Laravel homepage as a part of Ecosystem links. So it’s *officially* not part of the ecosystem anymore.

Based on those facts we can say that: Lumen is NOT Recommended for New Projects.

Just to be clear here, continuing to use lumen in your current projects will still be fine. One of our lumen projects in Architect product has ~35 million transactions/hour and millions of users within async jobs. But given the facts mentioned above, we took the decision to make the switch and save ourselves from a potential incompatibility along the way.

There are two available options to switch Lumen-based applications to Laravel, Laravel Shift & Manual Switch.

Laravel Shift

Laravel Shift is an automated Laravel upgrade that is handled by bots, they open pull requests against the target project to shift it to the specified version, and they can also convert from Lumen to a Laravel project. For only $5, they can do the following:

  • Updating the folder structure.
  • Adding the Laravel configuration files.
  • Bumping project dependencies for Laravel.
  • Converting Lumen framework code to its Laravel equivalent.
  • Adopting Laravel facades.
  • Detecting Lumen-specific references.

There are some conversions the Lumen to Laravel Converter can not perform automatically. Most notably converting database queries to use Eloquent.

When Shift detects any additional conversions it adds a detailed comment on the Pull Request to help guide any manual steps.

But if you are like us, and have trust issues with bots and security concerns, you might wanna consider the other option.

Manual Switch

Photo by Museums Victoria on Unsplash

This way we’ll handle switching to the Laravel structure by ourselves, the best way here is to switch your lumen project to the same version of Laravel (i.e lumen 8 => laravel 8) so that you don’t have to worry about changing PHP version. Then if you want to update the Laravel version it will be easier after the switch where you can follow the upgrade guide in Laravel documents.

Let’s check out the steps that you can tackle to make this switch (Approximate time to make the switch is ~20 minutes):

  • Copy the missing configuration files from a fresh Laravel project to yours. (note in the Laravel app configuration there is the providers and aliases array, you can remove the providers that you don’t use in your project).
  • Replace the Laravel\Lumen imports with Illuminate\Foundation in app/Console/Kernel.php , app/Exceptions/Handler.php , app/Http/Controllers/Controller.php files, and basically, anywhere else you have this import.
Kernel.php file example
Controller.php file example
Response and ResponseFactory imports example
  • The app/Http/Kernel.php file is not included in lumen projects but it’s required in Laravel, so you can create one and take an example from a new Laravel project.
  • When it comes to the Providers you have, each one should reflect the correct imports in the Laravel providers directory, so for the ones you are using don’t forget to replace the imports and take the RouteServiceProvider since it is not included in the lumen project.
  • Copy the artisan, public/index.php, and bootstrap/app.php files from the Laravel project and replace their content in the lumen one.
  • Create an empty cache folder under the bootstrap folder (don’t forget the .gitignore file).
  • Replace the $route-> calls in your routes file to be from the Route facade (Route::post(….)).
  • composer.json file is the most important part, since we chose the same versions from those frameworks, we won’t make so many changes to the package’s version compatibility. First, you can remove any packages that start with illuminate since they will be already included in the Laravel package. Second, replace the lumen package with the Laravel.
composer.json packages

We pumped other packages to be compatible with the Laravel version that we’re switching to, like carbon and phpunit.

And some extra things that you can do to this file are adding the missing scripts and change the lumen keywords to Laravel, for example from the Laravel composer.json file.

  • Now you can do composer install to your project so that all Laravel-related packages are installed (It is recommended to delete the vendor directory and composer.lock file).

And that’s it for the switch steps, easy right? :)

PHP Unit

All of our projects have %100 code coverage with unit and feature tests, also there are automation and smoke tests that run against them before each deployment. If your projects are also covered then you are in luck, because they give you more confidence to make such changes and alert the developers in the case of something missing or not configured properly.

To run those suites you can follow these steps:

  • Replace the Laravel\Lumen imports with Illuminate\Foundation just like what we did above for the tests/TestCase.php file.
  • You might have some old deprecated syntax in the test file like using $this->at() instead of $this->exactly().
  • We changed the bootstrap attribute in phpunit tag inside phpunit.xml to vendor/autoload.php instead of bootstrap/app.php. Not that it’s gonna make a difference but since Laravel projects are like this then it’s better to follow their best practices.
  • Run those tests and make sure that everything is green.

Extras

The lumen projects that we have dispatch thousands of jobs in separate queues each day, so we needed to be sure that the newly dispatched jobs or the ones that were waiting in the queue by the time we merge the new changes are processed without any issues.

So, we simulated it via opening a test elasticache and triggering two machines with two different branches(the main and the switch branch) and triggering jobs from the main to be consumed from the other branch. Luckily, everything was working and jobs were processed successfully without any issues or extra changes.

Are you considering deploying your Laravel project to K8s in simple and easy steps? Read this article from our Insider Engineering Blog and stay tuned for more.

Hope this article was helpful for you and made your switch process smooth and bug-free 🤞

--

--