Contenu connexe Similaire à Backward Compatibility Developer's Guide Webinar (20) Plus de Igor Miniailo (8) Backward Compatibility Developer's Guide Webinar1. © 2016 Magento, Inc. Page | 1
Backward Compatibility
Developer’s guide
Igor Miniailo
Magento 2 Architect
3. © 2016 Magento, Inc. Page | 3
The main reason we reject a community Pull
Request (PR) or request additional changes is
that the code is not compliant with our Technical
Vision and/or Backward Compatibility Policy.
7. © 2016 Magento, Inc. Page | 7
• Magento 2 Technical Guidelines
• Versioning
• Backward Compatibility Development
Guide
8. © 2016 Magento, Inc. Page | 8
Why does BC matter?
For merchants, the process
must be cost-effective, while
developers want their
extensions to be forward-
compatible for as long as
possible.
9. © 2016 Magento, Inc. Page | 9
Does Magento have to evolve?
Does every change in code bring backward
incompatibility?
10. © 2016 Magento, Inc. Page | 10
Keep Magento backwards compatible vs.
improving it?
12. © 2016 Magento, Inc. Page | 12
Backward Compatible Fix
*it works (most of the time), but code quality
is far from good enough
13. © 2016 Magento, Inc. Page | 13
Backward Compatibility
policy for Magento code
14. © 2016 Magento, Inc. Page | 14
Semantic Versioning
Version numbers are in the format
MAJOR.MINOR.PATCH, where:
– MAJOR indicates incompatible API changes
– MINOR indicates backward-compatible
functionality has been added
– PATCH indicates backward-compatible bug
fixes
15. © 2016 Magento, Inc. Page | 15
The backward compatibility policy
applies to PHP code annotated with
@api
17. © 2016 Magento, Inc. Page | 17
Public vs Private code
Private code is not supposed to
be used by third party modules,
so, in most cases, its
modifications will only trigger
PATCH version bumps.
Changes in public code always
trigger MINOR or MAJOR
version bumps.
18. © 2016 Magento, Inc. Page | 18
What examples of Public code Magento has?
• PHP Interface (marked with @api)
• PHP Class (marked with @api)
• Javascript Interface (marked with @api)
• Javascript Class (marked with @api)
• Virtual Type (marked with @api)
• URL paths
• Console commands and their arguments
• Less Variables & Mixins
• Message queue topics and their data types
• UI component declarations
• Layout handles declared by modules
• Events triggered by component (both static dynamic)
• Schema of configuration types introduced by module
• Structure of System Configuration fields used by module
19. © 2016 Magento, Inc. Page | 19
API vs SPI (Extension Points)
A PHP Interface in Magento can be used several ways by the core
product and extension developers.
• As an API. is a set of interfaces and their
implementations that a module provides to other
modules
• As a Service Provider Interface (SPI). is a set of
interfaces that a module uses internally and allows their
implementation by other modules.
• As both. APIs and SPIs are not mutually exclusive.
20. © 2016 Magento, Inc. Page | 20
After the code is released, both API and SPI can
be evolved in a backwards-compatible way. But
both have their specific limitations.
26. © 2016 Magento, Inc. Page | 26
We do not distinguish them separately.
SPIs are annotated the same as APIs.
27. © 2016 Magento, Inc. Page | 27
Who decides whether interface/class belong to API or SPI?
YOU
28. © 2016 Magento, Inc. Page | 28
Dependency Rules API
If a module uses (calls) an API, it should be dependent on the MAJOR
version.
API dependency example
{
...
"require": {
"magento/module-customer": "~100.0", // (>=100.0 <101.0.0)
},
...
}
29. © 2016 Magento, Inc. Page | 29
Dependency Rules SPI
If a module implements an API/SPI, it should be dependent on the
MAJOR+MINOR version.
SPI dependency example
{
...
"require": {
"magento/module-customer": "~100.0.0", // (>=100.0.0 <100.1.0)
},
...
}
30. © 2016 Magento, Inc. Page | 30
http://devdocs.magento.com/guides/v2.1/release-notes/backward-
incompatible-changes-2.1.html
31. © 2016 Magento, Inc. Page | 31
What keeps us from making mistakes?
To minimize this risk we have developed a tool Semantic
Version Checker Tool that analyzes two code bases and
determines what part of the version need updating
(MAJOR, MINOR, PATCH). As part of the delivery process,
we must run this tool and use the results for input to the
Version Setter tool.
33. © 2016 Magento, Inc. Page | 33
• Interface/class removal
• Public & protected method removal
• Introduction of a method to a class or
interface
PHP - Prohibited Code Changes
34. © 2016 Magento, Inc. Page | 34
MagentoCatalogApiCategoryRepositoryInterface
36. © 2016 Magento, Inc. Page | 36
PHP - Prohibited Code Changes
• Static function removal
• Parameter addition in public methods
• Parameter addition in protected
methods
38. © 2016 Magento, Inc. Page | 38
PHP - Prohibited Code Changes
• Method argument type modification
• Modification of types of thrown
exceptions (unless a new exception is
a subtype of the old one)
• Constructor modification
39. © 2016 Magento, Inc. Page | 39
class ExistingClass
{
/**
* @var NewDependencyInterface $newDependency
*/
private $newDependency;
public function __construct(
OldDependencyIntreface $oldDependency,
$oldRequiredConstructorParameter,
$oldOptinalConstructorParameter = null,
NewDependencyInterface $newDependency = null
) {
...
$this>newDependency = $newDependency ?: MagentoFrameworkAppObjectManager::getInstance()
->get(NewDependencyInterface::class);
...
}
public function existingFunction() {
// Existing functionality
...
// Use $this->newDependency wherever the new dependency is needed
...
}
}
40. © 2016 Magento, Inc. Page | 40
PHP - Prohibited Code Changes
• Modifying the default values of
optional arguments in public and
protected methods
• Removing or renaming constants
41. © 2016 Magento, Inc. Page | 41
The main rule is that backwards compatibility
is more important than niceness and effort of
the implementation.
42. © 2016 Magento, Inc. Page | 42
Do all backward
compatible fixes look
ugly because we are not
allowed to make
refactoring?
43. © 2016 Magento, Inc. Page | 43
Coupling Between Objects Reaches Its Limit with
a New Dependency
44. © 2016 Magento, Inc. Page | 44
We MUST do continuous Refactoring!
Backward Compatibility should not be an excuse
for not doing refactoring!
45. © 2016 Magento, Inc. Page | 45
Refactoring objects that
reach their dependency limit
48. © 2016 Magento, Inc. Page | 48
Preserve public and protected class
interfaces to maintain backwards
compatibility.
50. © 2016 Magento, Inc. Page | 50
Turn the existing class into a facade to
prevent existing usages of the
refactored methods from breaking.
52. © 2016 Magento, Inc. Page | 52
The old public/protected methods
should be marked as deprecated
with the @see tag to suggest the new
implementation for new usages.
53. © 2016 Magento, Inc. Page | 53
Remove all unused private properties
and methods.
54. © 2016 Magento, Inc. Page | 54
Mark as deprecated unused protected
properties. Remove the variable type
indicated in the DocBlock to remove
the dependency.
57. © 2016 Magento, Inc. Page | 57
To preserve the constructor signature:
• Remove type hinting for unused parameters to
remove dependency on their type.
• Add @SuppressWarnings(PHPMD.UnusedForm
alParameter) for unused parameters.
59. © 2016 Magento, Inc. Page | 59
This is how Backward
Compatible fix should
look like
Notes de l'éditeur Backward compatibility is a property of a system, product, or technology that allows for interoperability with an older legacy system We promise to be backward compatible for classes and methods annotated with @api within MINOR and PATCH updates to our components. As changes are introduced, we annotate methods with @deprecated. The methods are removed only with the next MAJOR component version.
Let’s recap what we had with Magento 1 – where everything is an extension points. All the protected mess and so on.
We can’t make changes in contract – all changes suppose to extend existing contract. Tilde = Significant Release Operator