Service contracts (defined using PHP interfaces) are currently included in same module that implements the interfaces and are versioned with the rest of Magento. One strategy under consideration is to separate into two modules the PHP interfaces that define service contracts and their implementation. The version number of the modules holding the service contracts would then only change if the contract changes. This provides more stability for extension developers.
What Are Service Contracts?
Service contracts are PHP interfaces that define the API for interacting with a given module. By using PHP interfaces, this allows different implementations to be swapped in more easily. For example, see the Customer module Api directory on GitHub.
The concept of contracts in this blog post is restricted to PHP interfaces. The definition needs to be expanded to whatever one module may need to depend on in another module, such as block ids in layout files and events, but that is beyond the scope of this blog post.
Why is Versioning So Hard?
The source code for Magento Community Edition is currently all in one git repo. This may change in the future, but that is how the code is today. Git only supports branching at the git repo level – you cannot branch different subdirectories independently. Magento creates a repository branch each minor release of Community Edition (2.0, 2.1, 2.2 etc). Patches for that release level are then created on that release branch (2.0.1 is created on the 2.0 release branch, 2.2.5 is created on the 2.2 release branch, etc).
To avoid the same version number of a module existing on two branches, each minor release (e.g. going from 2.1 to 2.2) always increments the minor or major number (first or second digit) of every module in the repository; on the release branch, only patch number increments are allowed (third digit), never the major or minor number (first or second digit). This strategy guarantees you can never get two branches in the git repository having different code with the same version number. It also guarantees that all patches are cumulative on release branches. The problem is it sometimes forces the minor version number change for a module even if the module is unchanged. This is unfortunate.
If each module was in a separate git repo, a different strategy could be used. When moving from 2.1 to 2.2 a decision could be made per module whether the same minor version of that module can be shared between the two release levels. For example, 2.1 and 2.2 could both point to 100.1.* of the Magento Customer module. If it is shared, any patch to that module would be shared by both releases. That also avoids back-porting bug fixes to as many releases.
The only reason this is not done today is all the modules are in the one git repo and share the same branching strategy. This may change in the future, but has not been done to date for two pragmatic reasons:
This blog post is a first step in the direction of splitting the Magento code base into independent git repos.
Proposal
The proposal is as follows:
Considerations
There are some considerations with this proposal.
Conclusions
The goal of separating contracts from implementation modules is for contracts to capture all the touch points needed by extensions. If an extension can 100% depend on a contract module and not on an implementation module, this provides Magento the flexibility and freedom to refactor and improve the implementation module with the stability that extension developers crave. As a result, extensions could support multiple Magento releases without change. To be effective, this will require Magento and extension developers coming together to work out what each contract should be.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.