May Sale! All accounts are 40% off this week.

Bozboz's avatar

Package Development

I'm totally down with external packages that offer generic utility/library-style functionality, and using Composer to bring these in, but I'm curious where "mini-app" style functionality belongs?

The kind of functionality that defines its own routes and controllers and slots into your app; a blog being a good example, a generic e-commerce platform being another.

Defining routes and controllers in packages is quite inflexible in Laravel, as you can't "undefine" routes, or change how controllers works. They're also very difficult to test in isolation. This leads me to think perhaps controllers and routes is an anti-pattern and that they should be reserved for just apps.

However, there doesn't seem to be an elegant way to encapsulate and reuse functionality across multiple apps in Laravel without using packages.

Am I missing something?

0 likes
4 replies
ionutbajescu's avatar

I think is good something like

Route::group(['prefix' => 'blog'], function(){
    MyBlog::init();
});
Bozboz's avatar

Thanks for your reply. This would give me a little flexibility over the loading and name-spacing of URLs, but the bigger question still remains. What if a site that required a blog didn't require categories? Or needed alternate pagination options? Would it be the responsibility of the blog package to be as flexible as its needs might require?

Also, @ionutbajescu, could you explain briefly what would happen when calling MyBlog::init()?

thepsion5's avatar

Routes and Controllers are kind of specific to the framework, but there's nothing inherently wrong with that. The way to make that work with a package that should mesh with multiple frameworks is to build an adapter for each.

For example your package would have a Support/Laravel namespace with a service provider and facade to integrate with Laravel. Next, you can create a Support/Symfony namespace with a Bundle class for integration with Symfony. Then, a Support/Slim namespace with middleware classes for Slim, etc.

Example: https://github.com/itsgoingd/clockwork/tree/master/Clockwork/Support

Alternatively, you could create your "core" package with just the business logic and some helpers/factories for bootstrapping, then a different package (with your core package as the first requirement) for each framework integration.

Example: https://github.com/bugsnag/bugsnag-laravel

JoshWilley's avatar

While you can't "undefine" routes, you could make the routes a publishable configuration option. This way, you can choose whether you want to load the default routes or not. Also, if you have routes in a package, defining the same routes in your application's routes file will essentially "overwrite" them as your application's routes get loaded last.

Please or to participate in this conversation.