I recently attended Laracon in New York City for the 4th year in a row. This year the conference was held at New World Stages in Hell’s Kitchen, with 500 people in attendance (and a waiting list of over 1000!) making it the biggest one yet.
While the conference focuses on the Laravel PHP framework, the talks were diverse and covered topics like database segregation for multi-tenant applications, aesthetic and design tips for developers, advice on growing and scaling a side project into a business, and the importance of deep-focus work. My job keeps me firmly planted in PHP-land, so my key takeaways came from the PHP-focused talks by Adam Wathan, Matt Stauffer, Jeffrey Way and Taylor Otwell.
CRUDDY by Design
Adam talked about CRUD in controllers, noting that many MVC web apps suffer from increasing controller bloat as we tack on custom actions — meaning, that EpisodeController@publishEpisode
method needs to disappear. Instead, he recommends returning to the CRUD basics and restricting yourself to only the 7 standard REST/CRUD actions in your controllers: index
, show
, create
, store
, edit
, update
, and destroy
.
He proposed 4 primary ways to accomplish this “refactor to CRUD”:
- Give nested resources a dedicated controller.
- Treat properties edited independently as separate resources.
- Treat pivot models as their own resource.
- Think of different states as different resources.
Here’s the example code, with explanations, in pull request form.
Custom Laravel
Matt’s talk focused on customizing Laravel. He encouraged everyone to make better (but always judicious) use of native and easily-overridable components of Laravel before reinventing the wheel with a fully custom solution. As always, the caveat is to not take it too far and keep discoverability in mind. Some of his suggestions:
- Lean on Laravel’s built-in config manager by defining custom config keys and custom config files. Make your own .env variables and import them into your config (but
env()
calls are really slow, so only use them in your config files!) - Customize the built-in classes (everything that ships in app/) by using/overriding the provided hooks. For example, the auth controllers expose
LoginController@$redirectTo
,LoginController@authenticated()
,LoginController@username()
, and a whole lot more. - Create and use custom PHPUnit assertions. You can add them easily to the base TestCase.
- Re-bind custom and internal Laravel classes into the container in your tests for easy mocking.
- Create custom Facades if you like that sort of thing. They’re easy to mock in your tests using
Facade::shouldReceive()
. - Write your own custom validation rules in a service provider using
Validator::extend()
(in Laravel 5.5+ this becomes even easier by implementing the Rule interface). - Create your own Blade directives using
Blade::directive
in a service provider.
Matt is a fast talker and covered a lot of ground in 40 minutes, so take a look at his slides, notes, and code samples here for a ton of other great customization tips.
Slay the Beast
Jeffrey’s talk on refactoring, “Slay the Beast”, was perhaps the most relevant to me as I’m the software architect on a sizable project and frequently feel like I’m drowning in technical debt. The primary message was to “let the grossness guide you” toward a refactor, specifically:
- Don’t ask objects to do something, tell them.
- Use single-use traits as a stepping-stone if you’re not sure what a better refactor is yet. Grouping related logic together and giving it a name is frequently the first step to something better.
- Learn to spot repeated words, prefixes, and suffixes, then upgrade them to a first-class object.
- Use decorators to wrap extra behavior around existing classes.
- Use query objects for those large, nasty queries.
Laravel 5.5 and Horizon
Taylor clued us in to new features coming in Laravel 5.5 and announced Laravel Horizon, a free/open source admin panel and monitoring dashboard for your queues. If you’re just curious about Horizon, check out Taylor’s blog post which has all the details straight from the horse’s mouth. As for the new features coming in 5.5:
- Returning a Mailable from a route will render it in the browser
- Returning an Exception from a route will render it in the browser (as long as it implements a
render
method) - Custom Exception reporting by defining a
report
method on any Exception class, providing a maintainable alternative toApp\Exceptions\Handler@report
- New
Responsable
interface (not a typo!) defining atoResponse
method. Implementing it will allow any class to be returned directly from a route. - Support for one-off notifications to an email address (instead of a User) using
Notification::route('mail', 'foo@example.com')->notify(YourNotification::class)
- Custom validation Rule objects by implementing
Illuminate\Contracts\Validation\Rule
- Native integration of Chris Fidao’s TrustedProxies middleware to help secure applications behind a load balancer
- New trait for database testing,
RefreshDatabase
which combines the best ofDatabaseTransactions
andDatabaseMigrations
- Chain-able queued jobs, and automatic retry improvement (jobs failing due to missing models will no longer retry up to 50 times)
- New
Blade::if
combining conditionals with custom Blade directives - Artisan commands will register automatically
- New artisan command
php artisan migrate:fresh
which replacesphp artisan migrate:refresh --seed
- New artisan command
artisan package:discover
will automatically register all third-party Service Providers in config/app.php. To support discovery in your Laravel package, add the"laravel"
key to composer.json — see the Nexmo Laravel package as an example - Laravel Dusk 2.0+ will use the Chrome headless option for faster browser testing
- Optional React scaffolding as an alternative to Vue
All in all, Laracon 2017 was an amazing, educational experience and I’m already looking forward to the next one.
