+ All Categories
Home > Engineering > Backward Compatibility Developer's Guide in Magento 2

Backward Compatibility Developer's Guide in Magento 2

Date post: 21-Jan-2018
Category:
Upload: igor-miniailo
View: 422 times
Download: 2 times
Share this document with a friend
31
© 2016 Magento, Inc. Page | 1 Backward Compatibility Developer’s guide Miniailo Igor, Magento 2 Architect
Transcript
Page 1: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 1

Backward Compatibility

Developer’s guide

Miniailo Igor,

Magento 2 Architect

Page 2: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 2

Page 3: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 3

Backward Compatibility

Backward compatibility is a property of a system,

product, or technology that allows for interoperability

with an older legacy system (c) - Wiki

Page 4: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 4

Why does BC matter?

Merchants and developers want the process of upgrading

between revisions of Magento 2 to be as easy as possible.

For merchants, the process must be cost-effective, while

developers want their extensions to be forward-

compatible for as long as possible.

Page 5: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 5

Does Magento have a lot of bugs?

Are these bugs annoying for Magento

developers?

Page 6: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 6

Keep Magento backwards compatible vs.

fixing its flaws?

Page 7: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 7

We MUST do BOTH

Page 8: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 8

Backward Compatible Fix

*it works (most of the time), but code quality

is far from good enough

Page 9: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 9

Backward compatibility (BC)

policy for Magento code

Page 10: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 10

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

The backward compatibility policy applies to PHP code

annotated with @api

Page 11: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 11

Public and Private code

Page 12: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 12

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.

Page 13: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 13

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

Page 14: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 14

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. An interface is called by PHP code.

• As a Service Provider Interface (SPI). An interface can be

implemented, allowing code to provide functionality to the platform.

• As both. For example, in a service contract, we expect all calls to a

module to be done through the Interface (API), but we also have

support for third parties to provide alternate implementations (SPI).

APIs and SPIs are not mutually exclusive. Therefore, we do not

distinguish them separately. SPIs are annotated the same as APIs.

Page 15: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 15

Who decides whether interface/class belong to API or SPI?

YOU

Page 16: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 16

Dependency Rules API

If a module uses (calls) an API, it should be dependent on the MAJOR

version and the system provides backward compatibility in scope of

current major version.

API dependency example

{

...

"require": {

"magento/module-customer": "~100.0", // (>=100.0 <101.0.0)

},

...

}

Page 17: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 17

Dependency Rules SPI

If a module implements an API/SPI, it should be dependent on the

MAJOR+MINOR version, and the system provides backward

compatibility in scope of the current minor version.

SPI dependency example

{

...

"require": {

"magento/module-customer": "~100.0.0", // (>=100.0.0 <100.1.0)

},

...

}

Page 18: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 18

http://devdocs.magento.com/guides/v2.1/release-notes/backward-incompatible-changes-2.1.html

Page 19: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 19

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.

Page 20: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 20

Prohibited Code Changes

Page 21: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 21

• Interface/class removal Mark with @deprecated tag instead of removing it. Mark also all its methods

as deprecated, so IDE highlights them as deprecated.

• Public & protected method removal

Mark with @deprecated tag instead.

Continue returning the same results from the method if possible, so the old

functionality is preserved.

• Introduction of a method to a class or interface

Create a new interface with a new method. New interface may take over some existing methods from the class if it makes sense to group them

together. In this case, corresponding methods in the old interface/class must be deprecated with

@see annotation referencing the new interface/method. The old methods should proxy the calls to

the new interface instead of duplicating the logic.

PHP

Page 22: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 22

PHP

• static function removal

• parameter addition in public methods

Add a new method with necessary parameters to new interface.

Deprecate old method. Reference the new method in a @see tag as a

recommended replacement. Include an explanation of why the old

method was replaced with the new one (e.g., there is a bug in the old

method).

• parameter addition in protected methods

Preserve the method as is. Create a new method with the new

signature, and deprecate the old method. If possible declare the new

method as private.

Page 23: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 23

PHP

• method argument type modification

• modification of types of thrown exceptions (unless a new

exception is a subtype of the old one)

• constructor modification

Add the new optional parameter to the constructor at the end of

arguments list.

In the constructor body, if new dependency is not provided (value of

introduced argument is null) fetch the dependency using

Magento\Framework\App\ObjectionManager::getInstance().

Page 24: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 24

class ExistingClass

{

/**

* @var \New\Dependency\Interface $newDependency

*/

private $newDependency;

public function __construct(

\Old\Dependency\Intreface $oldDependency,

$oldRequiredConstructorParameter,

$oldOptinalConstructorParameter = null,

\New\Dependency\Interface $newDependency = null

) {

...

$this>newDependency = $newDependency ?: \Magento\Framework\App\ObjectManager::getInstance()

->get(\New\Dependency\Interface::class);

...

}

public function existingFunction() {

// Existing functionality

...

// Use $this->newDependency wherever the new dependency is needed

...

}

}

Page 25: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 25

The main rule is that backwards compatibility

is more important than niceness and effort of

the implementation.

Page 26: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 26

Do all backward

compatible fixes look

ugly because we are not

allowed to make

refactoring?

Page 27: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 27

Coupling Between Objects Reaches Its Limit with

a New Dependency

Page 28: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 28

Coupling Between Objects - Refactoring• For preserving backwards compatibility, public and protected

interface of the class must be preserved. But the class

should be reviewed and refactored so that parts of the logic

go into smaller specialized classes.

• The existing class then should be functioning as a facade to

preserve backwards compatibility, so existing usages of the

refactored methods were not broken

• The old public/protected methods should be marked as

deprecated with @see tag suggesting the new

implementation for new usages

• All unused private properties/methods can be removed now

Page 29: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 29

Coupling Between Objects - Refactoring

• All unused protected properties must be marked as

deprecated.

• Type of the variable can be removed from the DocBlock, so

it's not calculated as one of the dependencies

To preserve constructor signature:

• Remove type hinting for unused parameters. This will remove

dependency on their type

• Add @SuppressWarnings(PHPMD.UnusedFormalParameter)

for unused parameters

Page 30: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 30

This is how Backward

Compatible fix should

look like

Page 31: Backward Compatibility Developer's Guide in Magento 2

© 2016 Magento, Inc. Page | 31

Q & A

@iminyaylo


Recommended