Laravel: 3 ways to separate your “big service”

When you want to organize your application code, but also your other codebase for something complicated.

Sometimes I need to create a Service in my application. Think something like a very complicated repository for Users, and API implementation with underlying drivers, a Factory to create some complicated information, whatever you can imagine that can’t be contained in just one file.

Eventually, this code will land inside the namespace. But wouldn’t be nice to use a custom Namespace, or rather a folder where it could live separated from the rest of the application code? Here are my top three ways to separate that from your application, starting from the simpler.

1. Using a Service Provider

Put your code into . Then create a Service Provider where you register and boot your service. This will allow your main class (or classes) to live in the Service Container, and only be instantiated when your application needs it.

/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->singleton(\App\Services\YourService\Stuff::class);
}

Once you’re done, there are two options:

/**
* Register any application services.
*
* @return void
*/
public function register()
{
// ...
$this->app->register(
\App\Services\YourService\ServiceProvider::class
);
}
  • Or add it manually inside the key of your config file:
'providers' => [    // ...    \App\Services\YourService\ServiceProvider::class,]

I use this when I need order, and also my “Service” consists on just a few files that do complicated stuff. Keep calm and nobody dies.

2. Using a separated PSR-4 Namespace

The same as the above, we create a Service Provider and register it in your .

The difference is in the namespace and directory. Instead of using a folder inside the directory, create a folder in the root of your project called (or anything you want), and use a custom namespace for everything under it matching the path, like .

After that, you will need to instruct composer to autoload your files. I personally like the approach to add a new key in the array called pointing to the folder, so if I create a new “Service” inside it Composer will autoload it automatically.

{
// ...
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/",
"Services\\": "services/"
}
}
}

Then, in your PHP files, you can use your Class following the namespace you have set:

<?phpnamespace Services\MyPackage;class SuperService  {
// ...
}

3. Go hardcore with your own Composer package

I use this when I’m doing multiple applications which are totally unrelated but I need the same private codebase available to them.

Most of this it already panned out in my article about Composer: Using your own local package.

Instead of copy-pasting the files, or making a symlink, I just instruct Composer to treat a folder like a Composer package, which I will require inside every project that needs it.

First, I make a full fledged Composer package. Personally I use the Laravel Package Boilerplate for a quick start, and delete the tools used for internet-hosted repositories (, , etc.) since I don’t use them. A easy namespace can be , but you can use whatever you want, like or .

Assuming you finished your package, all test passed, and configuring correctly the schema, put it inside a folder where all your shared packages will be, like .

Now, in each of your projects files you will add your own package as a local private repository:

{
// ...

"require": {
// Bunch of packages required...
"services/my-service": "@dev"
},
"repositories": [
{
"type": "path",
"url": "/Users/AwesomeDev/Composer/MyService"
}
],
}

Note here that your package name required in your project must match what your package says. If your package is called , then you must put the same name inside the the array.

The version will depend on the package itself. If you’re using a VCS like Git, you can safely omit the version key since it’s inferred from the tagging, but if not, or you don’t have any 100% immutable stable version, just use .

If you want the advantages of the Internet, you can use Github private repository, or Gitlab, to name a few. Form more tight control, use Private Packagist or mount your own Satis.

Graphic Designer graduate. Full Stack Web Developer. Retired Tech & Gaming Editor.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store