Managing monolithic repositories with composer’s path repository
Composer now have a new repository type in addition to, among others, the well known vcs
for instance: the path
repository. The goal if this repository is to be able to manage dependencies between applications and packages in a monolithic repository.
A monolithic repository?
The first question can be: why a monolithic repository? There are many blog posts and videos around about why such a code repository can be extremely useful for your project and your team, but we can quickly summarise that in some cases you’ll find at least these advantages:
- Reduced bootstrap cost as new starters just need this repository
- Easier to have cross-applications patches (via a single pull-request for instance)
- You don’t need to download dependencies as they are here ;-)
Obviously there are also some potential problems such as the ease of BC breaks between your libraries/applications and also shared responsibility, but that’s more related to the developers than the tooling.
Now, with Composer
Benjamin created a tool called Fiddler that aims to solve this management of PHP dependencies in a monolithic repository. I believe there’s few issues and that probably the purpose is different so that’s why I wanted to introduce this path repository into Composer itself, the de-facto dependency management tool for PHP.
You are probably already using vcs
repositories to use your own forks are private dependencies without using a Satis for instance: the idea is exactly the same, you have to define your repository in your composer.json
file and then simply require the package.
Let’s say you have a micro-services-based architecture with many services and you are using a monolithic repository. In this example, you’ll have 1 “sales” API and 2 other services using it via the same client library. You’ll probably end with a repository structure like that:
apps/
sales-api/
accounts-api/
composer.json
reporting-worker/
composer.json
packages/
sales-client/
composer.json
The composer.json
file of the sales client (in packages/sales-client/composer.json
) will be normal with just a name property:
{
"name": "acme/sales-client"
}
Then, in the accounts-api and reporting-worker applications we need this library, so we can simply require it by having a composer.json
file that uses the path repository like in the following example:
{
"require": {
"acme/sales-client": "*"
},
"repositories": [
{
"type": "path",
"url": "../../packages/sales-client"
}
]
}
And that’s all. Now you can easily deal with monolithic repositories!