Laravel 5.5 Package Development

Tutorial how to create a Laravel 5.5 package using the new package auto-discovery feature.

Markus Tripp
Aug 11, 2017 · 4 min read

Packages are the primary way of adding functionality to Laravel. In this tutorial I create a MongoDB composer package based on my “Getting Started with Laravel 5.4 and MongoDB” guide. I also use the new package auto-discovery feature introduced in Laravel 5.5.

First let’s see how the final package is used in a new Laravel project after submission to Packagist.

Usage of Published Package

If not already available please install MongoDB first. Then create a new Laravel project.

composer create-project laravel/laravel myproject dev-develop
cd myproject

After Laravel 5.5 is finally released you can also use laravel new myproject Now please use the current development branch (dev-develop).

Add the composer package markustripp/mongo which includes MongoDB:

composer require markustripp/mongo

Copy the configuration from the package to your project (optional):

php artisan vendor:publish

Please select the provider: Markustripp\Mongo\MongoServiceProvider

Now you are ready to use the Mongo facade. For testing just modify the routes/web.php:

<?phpRoute::get('mongo', function(Request $request) {
$collection = Mongo::get()->mydatabase->mycollection;
return $collection->find()->toArray();
});
Route::get('/', function () {
return view('welcome');
});

To test the setup open the terminal, connect to MongoDB, create a database and collection and insert a document:

mongo
> use mydatabase
> db.mycollection.insert( { "hello": "world" } )

If you use Valet then http://myproject.dev/mongo returns the JSON document just added.

Now that you understand how to use the package let’s dive into creating this package from scratch.

Create New Package

A package is often created together with a Laravel project or test project. I recommend to keep both directories separated but if a team collaborates on the package development you must agree on a common relative path structure.

E.g. flat directory structure:

./package-1
./package-2
./package-3
./project-1
./project-2

E.g. subdirectories:

./packages/package-1
./packages/package-2
./packages/package-3
./projects/project-1
./projects/project-2

For this demo I use the flat directory structure and store the packages in the same relative directory as the projects.

Create Package Directory

The name of the package will be markustripp/mongo (same name is used as Github repository). Therefore I create a package directory with the name “mongo”.

mkdir mongo

Create Composer File

The composer file describes the package and lists all dependencies. The composer init command helps you to create this file.

cd mongo
composer init
composer init for markustripp/mongo project

Now that we created our basic composer file let’s add the PSR-4 autoload namespace mapping.

"autoload": {
"psr-4": {
"Markustripp\\Mongo\\": "src/"
}
},

Laravel 5.5 introduced the package auto-discovery feature so let’s add the configuration for our MongoServiceProvider and MongoFacade:

"extra": {
"laravel": {
"providers": [
"Markustripp\\Mongo\\MongoServiceProvider"
],
"aliases": {
"Mongo": "Markustripp\\Mongo\\MongoFacade"
}
}
}

Here the final composer.json file:

{
"name": "markustripp/mongo",
"description": "MongoDB driver, auth, passport for Laravel",
"license": "MIT",
"authors": [
{
"name": "Markus Tripp",
"email": "markus@mext.at"
}
],
"require": {
"mongodb/mongodb": "^1.1"
},
"autoload": {
"psr-4": {
"Markustripp\\Mongo\\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"Markustripp\\Mongo\\MongoServiceProvider"
],
"aliases": {
"Mongo": "Markustripp\\Mongo\\MongoFacade"
}
}
}
}

Implementation of the Package

See the Github repository for the implementation of the package.

Atom view of package implementation

Create an App that Uses the Package

Create a new Laravel 5.5 app:

composer create-project laravel/laravel mongo-app dev-develop
cd mongo-app

If you use Valet then open http://mongo-app.dev/ in your browser and verify that the app was installed successfully.

Open mongo-app/composer.json in you favorite editor and add the package as path-type repository and require it:

"repositories": [
{
"type": "path",
"url": "../mongo",
"options": {
"symlink": true
}
}
],
"require": {
"php": ">=7.0.0",
"fideloper/proxy": "~3.3",
"laravel/framework": "5.5.*",
"laravel/tinker": "~1.0",
"markustripp/mongo": "dev-master"
},

Finally run composer update.

composer update

In the console output you see that composer installed the mongodb/mongodb dependency and added a symlink to ../mongo.

Package operations: 2 installs, 0 updates, 0 removals
- Installing mongodb/mongodb (1.1.2): Loading from cache
- Installing markustripp/mongo (dev-master): Symlinking from ../mongo
Writing lock file

Now you are ready to use the Mongo facade. For testing just modify the routes/web.php:

<?phpRoute::get('mongo', function(Request $request) {
$collection = Mongo::get()->mydatabase->mycollection;
return $collection->find()->toArray();
});
Route::get('/', function () {
return view('welcome');
});

If you added a document to mycollection in mydatabase you can access the document in the browser via http://mongo-app.dev/mongo

Now the setup is completed and you can start implementing the package and Laravel project.

Final Thoughts

In my last project I used Laravel passport for auth, oAuth and MongoDB for the application in a hybrid database setup (MySQL and MongoDB). Not perfect but was OK for the limited time I had.

Then I came across an article about the new package auto-discovery feature. This was the trigger to start with an own package. I plan to start with simple MongoDB support (version 1.0.x), add auth (version 1.1.x) and finally implement passport. Let’s see if my plan comes true.

Markus Tripp

Written by

Head of IT @ eattheball.com; love coding (JavaScript, Laravel, MongoDB, Shopify); interested in startups and new products.