Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
© 2016 Magento, Inc. Page | 1
API Design
Best practices
Igor Miniailo
Magento 2 Architect
© 2016 Magento, Inc. Page | 2
© 2016 Magento, Inc. Page | 3
© 2016 Magento, Inc. Page | 4
Why is API so crucial?
© 2016 Magento, Inc. Page | 5
© 2016 Magento, Inc. Page | 6
© 2016 Magento, Inc. Page | 7
© 2016 Magento, Inc. Page | 8
Semantic Versioning
Version numbers are in the format
MAJOR.MINOR.PATCH, where:
– MAJOR indi...
© 2016 Magento, Inc. Page | 9
The backward compatibility policy
applies to PHP code annotated with
@api
© 2016 Magento, Inc. Page | 10
Public and Private code
© 2016 Magento, Inc. Page | 11
Public vs Private code
Private code is not supposed to
be used by third party modules,
so, ...
© 2016 Magento, Inc. Page | 12
What examples of Public code Magento has?
• PHP Interface (marked with @api)
• PHP Class (m...
© 2016 Magento, Inc. Page | 13
API vs SPI (Extension Points)
A PHP Interface in Magento can be used several ways by the co...
© 2016 Magento, Inc. Page | 14
After the code is released, both API and SPI can
be evolved in a backwards-compatible way. ...
© 2016 Magento, Inc. Page | 15
© 2016 Magento, Inc. Page | 16
© 2016 Magento, Inc. Page | 17
© 2016 Magento, Inc. Page | 18
© 2016 Magento, Inc. Page | 19
© 2016 Magento, Inc. Page | 20
We do not distinguish them separately.
SPIs are annotated the same as APIs.
© 2016 Magento, Inc. Page | 21
Who decides whether interface/class belong to API or SPI?
YOU
© 2016 Magento, Inc. Page | 22
Dependency Rules API
If a module uses (calls) an API, it should be dependent on the MAJOR
v...
© 2016 Magento, Inc. Page | 23
Dependency Rules SPI
If a module implements an API/SPI, it should be dependent on the
MAJOR...
© 2016 Magento, Inc. Page | 24
http://devdocs.magento.com/guides/v2.1/release-notes/backward-
incompatible-changes-2.1.html
© 2016 Magento, Inc. Page | 25
Prohibited Code Changes
© 2016 Magento, Inc. Page | 26
• Interface/class removal
• Public & protected method removal
• Introduction of a method to...
© 2016 Magento, Inc. Page | 27
MagentoCatalogApiCategoryRepositoryInterface
© 2016 Magento, Inc. Page | 28
MagentoCatalogApiCategoryListInterface
© 2016 Magento, Inc. Page | 29
PHP - Prohibited Code Changes
• Static function removal
• Parameter addition in public meth...
© 2016 Magento, Inc. Page | 30
© 2016 Magento, Inc. Page | 31
PHP - Prohibited Code Changes
• Method argument type modification
• Modification of types o...
© 2016 Magento, Inc. Page | 32
class ExistingClass
{
/**
* @var NewDependencyInterface $newDependency
*/
private $newDepen...
© 2016 Magento, Inc. Page | 33
PHP - Prohibited Code Changes
• Modifying the default values of
optional arguments in publi...
© 2016 Magento, Inc. Page | 34
The main rule is that backwards compatibility
is more important than niceness and effort of...
© 2016 Magento, Inc. Page | 35
Coupling Between Objects Reaches Its Limit with
a New Dependency
© 2016 Magento, Inc. Page | 36
We MUST do continuous Refactoring!
Backward Compatibility should not be an excuse
for not d...
© 2016 Magento, Inc. Page | 37
Backward Compatible Fix
*it works (most of the time), but code quality
is far from good eno...
© 2016 Magento, Inc. Page | 38
Good object oriented programming in the service layer is basically
functional programming:
...
© 2016 Magento, Inc. Page | 39
© 2016 Magento, Inc. Page | 40
Why execute but not __invoke?
© 2016 Magento, Inc. Page | 41
PHP 7
• Return Types
• Scalar Type hinting
© 2016 Magento, Inc. Page | 42
Repositories
In Magento 2 Repositories are considered as an implementation
of Facade patter...
© 2016 Magento, Inc. Page | 43
Repositories
© 2016 Magento, Inc. Page | 44
© 2016 Magento, Inc. Page | 45
© 2016 Magento, Inc. Page | 46
Good API design
Don't make your client do anything you can do
for them (this reduces the am...
© 2016 Magento, Inc. Page | 47
© 2016 Magento, Inc. Page | 48
Q & A
@iminyaylo
engcom@magent.com
Upcoming SlideShare
Loading in …5
×

API design best practices

126 views

Published on

- Magento MSI Service Layer
- Public and Private code
- API vs SPI (Service Provider Interface)
- Backward Compatibility requirements and prohibited code changes
- Refactoring
- Functional programming and functors
- Single-method immutable objects
- Examples of Good Interfaces
- Why Execute but not __invoke
- Magento Repositories

Published in: Software
  • Be the first to comment

  • Be the first to like this

API design best practices

  1. 1. © 2016 Magento, Inc. Page | 1 API Design Best practices Igor Miniailo Magento 2 Architect
  2. 2. © 2016 Magento, Inc. Page | 2
  3. 3. © 2016 Magento, Inc. Page | 3
  4. 4. © 2016 Magento, Inc. Page | 4 Why is API so crucial?
  5. 5. © 2016 Magento, Inc. Page | 5
  6. 6. © 2016 Magento, Inc. Page | 6
  7. 7. © 2016 Magento, Inc. Page | 7
  8. 8. © 2016 Magento, Inc. Page | 8 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
  9. 9. © 2016 Magento, Inc. Page | 9 The backward compatibility policy applies to PHP code annotated with @api
  10. 10. © 2016 Magento, Inc. Page | 10 Public and Private code
  11. 11. © 2016 Magento, Inc. Page | 11 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.
  12. 12. © 2016 Magento, Inc. Page | 12 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
  13. 13. © 2016 Magento, Inc. Page | 13 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.
  14. 14. © 2016 Magento, Inc. Page | 14 After the code is released, both API and SPI can be evolved in a backwards-compatible way. But both have their specific limitations.
  15. 15. © 2016 Magento, Inc. Page | 15
  16. 16. © 2016 Magento, Inc. Page | 16
  17. 17. © 2016 Magento, Inc. Page | 17
  18. 18. © 2016 Magento, Inc. Page | 18
  19. 19. © 2016 Magento, Inc. Page | 19
  20. 20. © 2016 Magento, Inc. Page | 20 We do not distinguish them separately. SPIs are annotated the same as APIs.
  21. 21. © 2016 Magento, Inc. Page | 21 Who decides whether interface/class belong to API or SPI? YOU
  22. 22. © 2016 Magento, Inc. Page | 22 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) }, ... }
  23. 23. © 2016 Magento, Inc. Page | 23 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) }, ... }
  24. 24. © 2016 Magento, Inc. Page | 24 http://devdocs.magento.com/guides/v2.1/release-notes/backward- incompatible-changes-2.1.html
  25. 25. © 2016 Magento, Inc. Page | 25 Prohibited Code Changes
  26. 26. © 2016 Magento, Inc. Page | 26 • Interface/class removal • Public & protected method removal • Introduction of a method to a class or interface PHP - Prohibited Code Changes
  27. 27. © 2016 Magento, Inc. Page | 27 MagentoCatalogApiCategoryRepositoryInterface
  28. 28. © 2016 Magento, Inc. Page | 28 MagentoCatalogApiCategoryListInterface
  29. 29. © 2016 Magento, Inc. Page | 29 PHP - Prohibited Code Changes • Static function removal • Parameter addition in public methods • Parameter addition in protected methods
  30. 30. © 2016 Magento, Inc. Page | 30
  31. 31. © 2016 Magento, Inc. Page | 31 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
  32. 32. © 2016 Magento, Inc. Page | 32 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 ... } }
  33. 33. © 2016 Magento, Inc. Page | 33 PHP - Prohibited Code Changes • Modifying the default values of optional arguments in public and protected methods • Removing or renaming constants
  34. 34. © 2016 Magento, Inc. Page | 34 The main rule is that backwards compatibility is more important than niceness and effort of the implementation.
  35. 35. © 2016 Magento, Inc. Page | 35 Coupling Between Objects Reaches Its Limit with a New Dependency
  36. 36. © 2016 Magento, Inc. Page | 36 We MUST do continuous Refactoring! Backward Compatibility should not be an excuse for not doing refactoring!
  37. 37. © 2016 Magento, Inc. Page | 37 Backward Compatible Fix *it works (most of the time), but code quality is far from good enough
  38. 38. © 2016 Magento, Inc. Page | 38 Good object oriented programming in the service layer is basically functional programming: • constructor injection • immutable state • single responsibility principle • uniform interfaces • value objects passed across services Bringing these concepts to an extreme leads to single-method, immutable objects.
  39. 39. © 2016 Magento, Inc. Page | 39
  40. 40. © 2016 Magento, Inc. Page | 40 Why execute but not __invoke?
  41. 41. © 2016 Magento, Inc. Page | 41 PHP 7 • Return Types • Scalar Type hinting
  42. 42. © 2016 Magento, Inc. Page | 42 Repositories In Magento 2 Repositories are considered as an implementation of Facade pattern which provides a simplified interface to a larger body of code responsible for Domain Entity management. The main intention is to make API more readable and reduce dependencies of business logic code on the inner workings of a module, since most code uses the facade, thus allowing more flexibility in developing the system.
  43. 43. © 2016 Magento, Inc. Page | 43 Repositories
  44. 44. © 2016 Magento, Inc. Page | 44
  45. 45. © 2016 Magento, Inc. Page | 45
  46. 46. © 2016 Magento, Inc. Page | 46 Good API design Don't make your client do anything you can do for them (this reduces the amount of boilerplate code your client will have)
  47. 47. © 2016 Magento, Inc. Page | 47
  48. 48. © 2016 Magento, Inc. Page | 48 Q & A @iminyaylo engcom@magent.com

×