symfony in microservice architecture

90
SYMFONY SYMFONY COMPONENTS IN COMPONENTS IN MICROSERVICES MICROSERVICES ARCHITECTURE ARCHITECTURE

Upload: daniele-dangeli

Post on 07-Jan-2017

10.316 views

Category:

Software


5 download

TRANSCRIPT

Page 1: Symfony in microservice architecture

SYMFONYSYMFONYCOMPONENTS INCOMPONENTS INMICROSERVICESMICROSERVICESARCHITECTUREARCHITECTURE

Page 2: Symfony in microservice architecture

ABOUT MEABOUT ME

Daniele D'Angeli@dangelidanielehttp://danieledangeli.com

http://www.sainsburys.co.uk/London

Born and raised in Rome

Page 3: Symfony in microservice architecture

WHAT WE'RE DOINGWHAT WE'RE DOING

A "brownfield" project 8 "micro" service so farAPI gateway written in GoLangPython, PHP, Symfony, Django, GoLang

Page 4: Symfony in microservice architecture

TECHNOLOGIESTECHNOLOGIES

Page 5: Symfony in microservice architecture

... LET ME START... LET ME STARTFROMFROM

CONCLUSIONSCONCLUSIONS

Page 6: Symfony in microservice architecture

IS SYMFONY SUITABLE FORA MICROSERVICESARCHITECTURE?

Page 7: Symfony in microservice architecture

UNDER CERTAINUNDER CERTAIN

CONDITIONSCONDITIONS

YESYES

Page 8: Symfony in microservice architecture

.What they are

.Drawbacks

.When Symfony can fail?

.When Symfony can success?

MICROSERVICESMICROSERVICES

Page 9: Symfony in microservice architecture

WHAT THEY AREWHAT THEY ARE

Page 10: Symfony in microservice architecture

BUZZWORD WINNINGBUZZWORD WINNINGAWARD 2015AWARD 2015

Page 11: Symfony in microservice architecture

...EMERGED FROM...EMERGED FROM

#CONTINUOS#CONTINUOSDELIVERYDELIVERY

#DOMAIN DRIVEN#DOMAIN DRIVENDESIGNDESIGN

#ON DEMAND#ON DEMANDVIRTUALIZATIONVIRTUALIZATION

#INFRASTRACTURE#INFRASTRACTUREAUTOMATIONAUTOMATION

Page 12: Symfony in microservice architecture

SMALL, AUTONOMOUSSMALL, AUTONOMOUSSERVICES THAT WORKSERVICES THAT WORK

TOGETHERTOGETHER

Page 13: Symfony in microservice architecture

small and focused on doing one thing well

"Gather together those things that change for the same reason,

and separate those things that change for different reasons"

Robert C. Martin

HOW SMALL IS SMALL?HOW SMALL IS SMALL?

Page 14: Symfony in microservice architecture

AUTONOMOUSAUTONOMOUS

Each microservice can be able to change independentlywithout requiring consumer to change

IDEALLY!!!IDEALLY!!!

Page 15: Symfony in microservice architecture

DRAWBACKSDRAWBACKS

Page 16: Symfony in microservice architecture

TESTINGTESTING

Page 17: Symfony in microservice architecture

REPRODUCE THE ENTIREREPRODUCE THE ENTIRESTACK ON A LOCAL ENVSTACK ON A LOCAL ENV

Page 18: Symfony in microservice architecture

WHEN SYMFONY CANWHEN SYMFONY CANFAILFAIL

Page 19: Symfony in microservice architecture

SYMFONY IS NOT ASYMFONY IS NOT AMICROMICRO FRAMEWORK FRAMEWORK

IT CAN BEIT CAN BECONSIDERED MORECONSIDERED MORE

A A "FULL-STACK""FULL-STACK"FRAMEWORKFRAMEWORK

Page 20: Symfony in microservice architecture

...IF THEY ARE SO...IF THEY ARE SOSMALLSMALL

Page 21: Symfony in microservice architecture

TOO MANY TOOLS INTOO MANY TOOLS INOUR "FRAMEWORK" OUR "FRAMEWORK"

Page 22: Symfony in microservice architecture

SYMFONY IS HARDSYMFONY IS HARDTO LEARNTO LEARN

Page 23: Symfony in microservice architecture

MICROSERVICESMICROSERVICES

====

ETEREGENOUS TEAMETEREGENOUS TEAM

Page 24: Symfony in microservice architecture

WHAT ABOUT IFWHAT ABOUT IFYOU ASK TO AYOU ASK TO APYTHONIST TOPYTHONIST TO

WORK WITHWORK WITHSYMFONY?SYMFONY?

Page 25: Symfony in microservice architecture
Page 26: Symfony in microservice architecture

TOO MANY CONFIGURATIONTOO MANY CONFIGURATIONFILESFILES

Page 27: Symfony in microservice architecture

WHEN SYMFONY CANWHEN SYMFONY CANSUCCESS?SUCCESS?

Page 28: Symfony in microservice architecture

...THEY ARE SO...THEY ARE SOSMALL?SMALL?

Page 29: Symfony in microservice architecture

THERE ARE A LOT OFTHERE ARE A LOT OFEXAMPLES WHEREEXAMPLES WHERE

COMPANIES FAILEDCOMPANIES FAILEDWITH MICROSERVICESWITH MICROSERVICES

Page 30: Symfony in microservice architecture

IT'S NOT ABOUTIT'S NOT ABOUTSYMFONY, OR OTHERSYMFONY, OR OTHERMVC FRAMEWORKS...MVC FRAMEWORKS...

Page 31: Symfony in microservice architecture

IT'S ABOUTIT'S ABOUTPREMATUREPREMATURE

DECOMPOSITIONDECOMPOSITION

Page 32: Symfony in microservice architecture

HTTPS://RCLAYTON.SILVRBACK.COM/FAILING-HTTPS://RCLAYTON.SILVRBACK.COM/FAILING-AT-MICROSERVICESAT-MICROSERVICES

Page 33: Symfony in microservice architecture

"... ANOTHER LESSON I LEARNED WAS"... ANOTHER LESSON I LEARNED WAS

TO NOT GET TOO GRANULAR WITHTO NOT GET TOO GRANULAR WITH

MICROSERVICES AT THE BEGINNINGMICROSERVICES AT THE BEGINNING

OF A PROJECT"OF A PROJECT"

Page 34: Symfony in microservice architecture

"... INSTEAD OF DOING WHAT WE DID"... INSTEAD OF DOING WHAT WE DID

(STARTING WITH 8 SERVICES), TRY(STARTING WITH 8 SERVICES), TRY

STARTING WITH TWO OR THREESTARTING WITH TWO OR THREE

SERVICES OF LOGICALLY RELATEDSERVICES OF LOGICALLY RELATED

FUNCTIONALITY (THEY WON'T BEFUNCTIONALITY (THEY WON'T BE

MICRO, HOWEVER)"MICRO, HOWEVER)"

Page 35: Symfony in microservice architecture

HOW FACINGHOW FACINGPREMATUREPREMATURE

DECOMPOSITION?DECOMPOSITION?

Page 36: Symfony in microservice architecture

FIRST APPROACHFIRST APPROACHMONOLITH FIRSTMONOLITH FIRST

http://martinfowler.com/bliki/MonolithFirst.html

Page 37: Symfony in microservice architecture

RealityHope vs.

http://martinfowler.com/articles/dont-start-monolith.html

Page 38: Symfony in microservice architecture

DOMAIN DRIVENDOMAIN DRIVENDESIGN PRINCIPLESDESIGN PRINCIPLES

ARE USEFULARE USEFUL

Page 39: Symfony in microservice architecture

ERIC EVANS ERIC EVANS

He talked about how microservices boundary enable DDDhttps://skillsmatter.com/skillscasts/6259-ddd-and-microservices-at-last-some-

bounderies

DDD eXchange 2015

THOUGHWORKSTHOUGHWORKS https://www.thoughtworks.com/insights/blog/domain-driven-design-services-

architecture

Domain Driven Design for Services ArchitectureBounded Contexts Designed as Service Applications

Page 40: Symfony in microservice architecture

ONEONE"MICRO"SERVICE"MICRO"SERVICE

FOR EACH BOUNDEDFOR EACH BOUNDEDCONTEXTCONTEXT

Page 41: Symfony in microservice architecture

https://flic.kr/p/3p16o1

IN A NUTSHELLIN A NUTSHELL

Page 42: Symfony in microservice architecture

LESS MICRO, MORELESS MICRO, MORE"MACRO""MACRO"

Page 43: Symfony in microservice architecture

WE NEED TO DESIGNWE NEED TO DESIGNOUR APPLICATIONS OUR APPLICATIONS

PROPERLYPROPERLY

Page 44: Symfony in microservice architecture

IN SUCHIN SUCHSCENARIOS SCENARIOS

SYMFONY CAN HELPSYMFONY CAN HELP...BUT PROBABLY WE...BUT PROBABLY WE

NEED SOMENEED SOMEEXPEDIENTSEXPEDIENTS

Page 45: Symfony in microservice architecture

A PRATICAL EXAMPLEA PRATICAL EXAMPLE

.Symfony scaffolding

&minimal configuration

.Testing

.How develop the integrations

Page 46: Symfony in microservice architecture

LET'SLET'SCONSIDER ANCONSIDER ANAPPLICATIONAPPLICATIONLIKE SLACKLIKE SLACK

Page 47: Symfony in microservice architecture

DISCOVERDISCOVERBOUNDED CONTEXT (HARD)BOUNDED CONTEXT (HARD)

ChannelContext

MessageContext

AuthorizationContext

AuthenticationContext

User management

Context

Page 48: Symfony in microservice architecture

MESSAGE CONTEXTMESSAGE CONTEXT

MessagesContext

ALLOWS AALLOWS A PUBLISHER PUBLISHERTO PUBLISH AND DELETETO PUBLISH AND DELETEMESSAGGES ON MESSAGGES ON OPENOPEN

CHANNELSCHANNELS

A A PUBLISHERPUBLISHER MUST BE MUST BEAUTHORIZEDAUTHORIZED TO TO

PUBLISH A MESSAGE ONPUBLISH A MESSAGE ONA CHANNELA CHANNEL

Page 49: Symfony in microservice architecture

SYMFONYSYMFONYSCAFFOLDINGSCAFFOLDINGAND MINIMALAND MINIMAL

CONFIGURATIONCONFIGURATION

Page 50: Symfony in microservice architecture

AVOID A CLASSICAVOID A CLASSICSYMFONYSYMFONY

SCAFFOLDINGSCAFFOLDING

Page 51: Symfony in microservice architecture

USE A MINIMALUSE A MINIMALSYMFONYSYMFONY

CONFIGURATIONCONFIGURATION PLUSPLUS

DDD DIRECTORYDDD DIRECTORYSTRUCTURE STRUCTURE

Page 52: Symfony in microservice architecture

https://github.com/danieledangeli/symfony-microservice-bounded-context-example

Github repository

Page 53: Symfony in microservice architecture

MINIMAL SYMFONY CONFMINIMAL SYMFONY CONF

Inspired by:

http://www.whitewashing.de/2014/10/26/symfony_all_the_things_web.html

environment variables.env files

only one config.ymlonly one entry point (index.php)

DotEnv

https://github.com/vlucas/phpdotenv

Page 54: Symfony in microservice architecture

require_once __DIR__ . "/../vendor/autoload.php";require_once __DIR__ . "/../app/AppKernel.php";

use Symfony\Component\HttpFoundation\Request;use Dotenv\Dotenv;

//load environment variables. It doesn't overwrite existing ones$dotenv = new Dotenv(__DIR__ . '/../');$dotenv->load();

$request = Request::createFromGlobals();

$kernel = new AppKernel( $_SERVER['SYMFONY_ENV'], (bool)$_SERVER['SYMFONY_DEBUG']);

$response = $kernel->handle($request);

$response->send();$kernel->terminate($request, $response);

Only one index.php

Page 55: Symfony in microservice architecture

Only 1 config.yml

public function registerBundles(){ ...}

public function registerContainerConfiguration(LoaderInterface $loader){ $loader->load(__DIR__ . '/config/config.yml');

if (in_array($this->getEnvironment(), array('dev', 'test'))) { $loader->load(function ($container) { $container->loadFromExtension('web_profiler', array( 'toolbar' => true, )); $container->loadFromExtension('framework', array( 'test' => true, )); }); }}

Page 56: Symfony in microservice architecture

The result:

Page 57: Symfony in microservice architecture

START TOSTART TOCODINGCODING

TESTINGTESTING

Page 58: Symfony in microservice architecture

TEST BEHAVIOURTEST BEHAVIOURFIRSTFIRST

Page 59: Symfony in microservice architecture

MAKE THE VALUE EXPLICITMAKE THE VALUE EXPLICIT(It's important also for other developers)

Page 60: Symfony in microservice architecture

Feature: message publisher As a Publisher I need to be able to publish a message on a channel ... Scenario: A publisher, if not authorized is not able to publish a new message on a channel Given I am publisher And exists an "open" channel And I'm not authorized to publish messages on that channel When I write the message "Hi guys" Then I'm informed that I'm not authorized And no new messages will be published on that channel

Page 61: Symfony in microservice architecture

FUNCTIONAL TESTSFUNCTIONAL TESTS

Stub dependencies

http://martinfowler.com/articles/microservice-testing/

Page 62: Symfony in microservice architecture

PHPUNIT/PHPSPECPHPUNIT/PHPSPECwith or without

MOCKERYMOCKERY

UNIT TESTSUNIT TESTS

Page 63: Symfony in microservice architecture

MAKE CLEAR THE TESTMAKE CLEAR THE TESTTYPE: TYPE: FUNCTIONAL,FUNCTIONAL, UNIT,UNIT, INTEGRATIONINTEGRATION

PHPUNIT @GROUPSPHPUNIT @GROUPS

Page 64: Symfony in microservice architecture
Page 65: Symfony in microservice architecture

HOW TO HOW TO

DEVELOP THEDEVELOP THEINTEGRATIONSINTEGRATIONS

Page 66: Symfony in microservice architecture

final class Publisher { public function publishOnChannel( Channel $channel, ChannelAuthorization $channelAuthorization, BodyMessage $body ) { if($channelAuthorization->canPublisherPublishOnChannel()) { if (!$channel->isClosed()) { //create message }

throw new ChannelClosedException( sprintf("The channel %s is closed", $channel ); }

throw new PublisherNotAuthorizedException; }}

Page 67: Symfony in microservice architecture

Channel { id ChannelId isOpen boolean}

ChannelAuthorization { publisherId PublisherId channelId ChannelId isAuthorized boolean}

MESSAGE CONTEXT MODELSMESSAGE CONTEXT MODELS

Publisher { id PublisherId}

sent within theauthenticatedrequest

taken from services integrations (Channel Context, Channel Authorization Context)

Page 68: Symfony in microservice architecture

namespace MessageContext\Domain\Service\Gateway;

interface ChannelGatewayInterface{ /** * @param ChannelId $channelId * * @return Channel */ public function getChannel(ChannelId $channelId);}

Page 69: Symfony in microservice architecture

<?php

namespace MessageContext\InfrastructureBundle\Service\Channel;

class ChannelGateway implements ChannelGatewayInterface{ private $channelAdapter;

...

/** * @param ChannelId $channelId * * @return Channel */ public function getChannel(ChannelId $channelId) { return $this->channelAdapter ->toChannel($channelId); }}

Page 70: Symfony in microservice architecture

namespace MessageContext\InfrastructureBundle\Service\ChannelAuthorization

class ChannelAdapter{ ...

public function toChannel(ChannelId $channelId) { $request = new Request("GET", sprintf("%s/api/channels/%s", $this->channelContextUri, $channelId ));

$request->addHeader("Accept", "application/json"); $response = $this->requestHandler->handle($request);

return $this->channelTranslator->toChannelFromResponse( $response ); }}

Page 71: Symfony in microservice architecture

class ChannelTranslator{ public function toChannelFromResponse(Response $response) { if (200 === $response->getStatusCode()) { $contentArray = $this->validateAndGetResponseBodyArray($response); return new Channel(new ChannelId($contentArray["id"]), $contentArray["isOpen"]); } .... }

private function validateAndGetResponseBodyArray(Response $response) { $contentArray = $response->getBody();

if (isset($contentArray["id"]) && isset($contentArray["isOpen"])) { return $contentArray; }

.... }}

Only what we need

{ "id": "456t-889-4444", "isOpen": false, "createAt": "26/05/2015", "publisherId": "11111-5555-3333-5555", "name": "a channel name", "spot": "a channel spot", "messagges_count": 450

... ...} The original response

Page 72: Symfony in microservice architecture

ARE WE MISSINGARE WE MISSINGSOMETHINGSOMETHING

??

Page 73: Symfony in microservice architecture
Page 74: Symfony in microservice architecture

<?php

interface ServiceIntegrationInterface{ /** * @param $message * * @throws ServiceNotAvailableException */ public function onServiceNotAvailable($message);

/** * @param $message * * @throws ServiceFailureException */ public function onServiceFailure($message);}

Page 75: Symfony in microservice architecture

namespace MessageContext\Domain\Service\Gateway;

interface ChannelGatewayInterface extends ServiceIntegrationInterface{ /** * @param ChannelId $channelId * * @throws MicroServiceIntegrationException * @return Channel */ public function getChannel(ChannelId $channelId);}

Page 76: Symfony in microservice architecture

class ChannelGateway implements ChannelGatewayInterface { ... /** * @param $message * @throws ServiceNotAvailableException */ public function onServiceNotAvailable($message) { throw new ServiceNotAvailableException($message); }

/** * @param $message * @throws ServiceFailureException */ public function onServiceFailure($message) { throw new ServiceFailureException($message); }

Page 77: Symfony in microservice architecture

ARE WE STILLARE WE STILLMISSINGMISSING

SOMETHINGSOMETHING

??

Page 78: Symfony in microservice architecture

IF AN INTEGRATIONIF AN INTEGRATIONIS NOT AVAILABLE,IS NOT AVAILABLE,WHY CONTINUINGWHY CONTINUING

TO SEND REQUESTSTO SEND REQUESTSTO IT?TO IT?

Page 79: Symfony in microservice architecture

CIRCUIT BREAKERCIRCUIT BREAKER

Page 80: Symfony in microservice architecture

"A CIRCUIT BREAKER IS"A CIRCUIT BREAKER ISUSED TO DETECT FAILURESUSED TO DETECT FAILURESAND ENCAPSULATES LOGICAND ENCAPSULATES LOGICOF PREVENTING A FAILUREOF PREVENTING A FAILURE

TO REOCCURTO REOCCURCONSTANTLY"CONSTANTLY"

Page 81: Symfony in microservice architecture

HTTPS://GITHUB.COM/EJSMONT-ARTUR/PHP-HTTPS://GITHUB.COM/EJSMONT-ARTUR/PHP-CIRCUIT-BREAKERCIRCUIT-BREAKER

Page 82: Symfony in microservice architecture

namespace MessageContext\InfrastructureBundle\CircuitBreaker;

class CircuitBreaker implements PostContextCircuitBreakerInterface{ private $circuitBreaker; ...

public function isAvailable($serviceName) { return $this->circuitBreaker->isAvailable($serviceName); }

public function reportSuccess($serviceName) { $this->circuitBreaker->reportSuccess($serviceName); }

public function reportFailure($serviceName) { $this->circuitBreaker->reportFailure($serviceName); }}

Page 83: Symfony in microservice architecture

public function getChannel(ChannelId $channelId){ if ($this->circuitBreaker->isAvailable($this->serviceName)) { try { $channel = $this->channelAdapter->toChannel($channelId); $this->circuitBreaker->reportSuccess($this->serviceName);

return $channel; } catch (UnableToProcessResponseFromService $e) { $this->handleNotExpectedResponse($e->getResponse()); } }

$this->onServiceNotAvailable("Service not available");}

private function handleNotExpectedResponse(Response $response){ $this->circuitBreaker->reportFailure($this->serviceName);

...}

Page 84: Symfony in microservice architecture

CONCLUSIONCONCLUSION(AGAIN)(AGAIN)

Page 85: Symfony in microservice architecture

SYMFONY CAN BE USED INSYMFONY CAN BE USED INSOME MICROSERVICESOME MICROSERVICE

ARCHITECTURES,ARCHITECTURES,ESPECIALLY IF WE STARTESPECIALLY IF WE STARTWITH A MONOLITH FIRSTWITH A MONOLITH FIRST

APPROACHAPPROACH

Page 86: Symfony in microservice architecture

HOWEVER WE MAY NEED TOHOWEVER WE MAY NEED TOCONSIDER SOMECONSIDER SOME

EXPEDIENTS EXPEDIENTS (env variables, avoid complex tools)

(IT DEPENDS ON THE TEAM!!)(IT DEPENDS ON THE TEAM!!)

Page 87: Symfony in microservice architecture

MINIMAL INTEGRATIONSMINIMAL INTEGRATIONS&

HANDLING FAILURESHANDLING FAILURES

ARE A GOOD STARTING POINTARE A GOOD STARTING POINTTO FACE THE OVERCOMPLEXITYTO FACE THE OVERCOMPLEXITY

INTRODUCED BYINTRODUCED BYTHIS ARCHITECTURETHIS ARCHITECTURE

Page 88: Symfony in microservice architecture

WHAT WE HAVEWHAT WE HAVEMISSEDMISSED

Page 89: Symfony in microservice architecture

OTHER INTEGRATION WAYS:OTHER INTEGRATION WAYS:

SERVICE CHOREOGRAPHY SERVICE CHOREOGRAPHY

OTHER TESTING WAYS:OTHER TESTING WAYS:

CONSUMER DRIVEN CONTRACTCONSUMER DRIVEN CONTRACTTESTSTESTS

Page 90: Symfony in microservice architecture

QUESTIONS?QUESTIONS?https://www.slideshare.net/danieledangeli10/symfony-in-

microservice-architecture