A soa approximation on symfony

40
A SOA Approximation using Symfony Joseluis Laso & Carlos Agudo

Transcript of A soa approximation on symfony

Page 1: A soa approximation on symfony

A SOA Approximation using Symfony

Joseluis Laso & Carlos Agudo

Page 2: A soa approximation on symfony

Who we are

•Carlos Agudo (@karloslupus)•Joseluis Laso (@jl_laso)

And Others.. (Spanish team)• Petar Georgiev (@pgkirilov)• Daniel Abad (@ruudy_es)• Noel García (@wolfwolker)• Joaquín Fernández Campo

(@xocas__)• Miguel Vilata

(@miguelvilata)

Page 3: A soa approximation on symfony

Where?

Page 4: A soa approximation on symfony

What is Digilant

DSP: Demand Side Platform => programmatic advertising.

We have a backend to configure ours RTB bidder(s) architecture.• A programmatic campaign can have thousands of

parameters.

Page 5: A soa approximation on symfony

Long journey

From monolithic sf1 (legacy , 8 years of development) to a SOA in sf2-3:

Page 6: A soa approximation on symfony

Requirements

• API Rest• Auto Scalable (can be a huge huge demanding

platform)• Symfony 2• Easy to deploy

Page 7: A soa approximation on symfony

So?

Page 8: A soa approximation on symfony

Do not try this at home

Page 9: A soa approximation on symfony

Yes Symfony 2-3

Bundle: “A bundle is simply a structured set of files within a directory that implement a single feature. “

-- We can split services as bundles, and start here.This sounds weird??Uncle Bob: “Don't leap into microservices just because it sounds cool. Segregate the system into jars using a plugin architecture first. If that's not sufficient, then consider introducing service boundaries at strategic points.”

Page 10: A soa approximation on symfony

Some Questions arose

• One repo? One per service orchestrated with composer? • One repo, let’s split it later, and coordinate with composer

later. (easier to develop)• One Db per service? One db for the whole project, with

soft-relations between services?• One Db for the whole project, let’s split it later. (easier to

develop??, careful with soft-relations, lost of referential integrity)

Page 11: A soa approximation on symfony

Our motto

Let’s split it later

And let’s start!!

Page 12: A soa approximation on symfony

Backend Services View

Bundles

Page 13: A soa approximation on symfony

Yes, services bundles

Page 14: A soa approximation on symfony

Service- Machine

We can create as many services-machine as we want. Depending on demand. We can cook them!!

Fully elastic scalability.LineItem Service - Machine

LineItem Core

LineItem- Campaign - Machine

LineItem

Campaign

Core

Page 15: A soa approximation on symfony

Cooking Process 1

Using ansistrano (ansible), in each deploy, we can select how many bundles a machine have.

Machine A- Geo and Creatives Machine B- All services but Pixel

Page 16: A soa approximation on symfony

Cooking Process 2

We need to dynamically load, our “bundles-service” on deploy, our models, our routings, etc..

A lot of magic happens here!

Compiler pass to the rescue!

Page 17: A soa approximation on symfony

Cooking Process 3

In our AppKernel.php. We have the LocateBundles (utility class) in a CoreBundle

Page 18: A soa approximation on symfony

Core Bundle

We have a CoreBundle, that act as a glue, (Compiler passes)• Communication between services (Can be http-

external, http-internal, process) We have a call Router. API-REST, that’s why http-internal or external

• Some bussines event listeners (a filter for accounts, softdelete, audit db listener)

• User-Permission Model

Page 19: A soa approximation on symfony

Models 1

In order to don’t get coupled to the persistence implementation (Doctrine), don’t use annotations for defining the model, map in an xml:

Page 20: A soa approximation on symfony

Models 2

We want to use our own folders:

Base?? We will explain it later, we have an autogenerator of code.

Page 21: A soa approximation on symfony

Models 3

Compiler Pass to Load Models in our own folders.

We pass through our bundles, and load models, in our folders.

The key:DoctrineOrmMappingPass

We also use an alias:

LineItem:ThirdPartyDataGeo:City

ServiceName:Model

Page 22: A soa approximation on symfony

Others Compilers Passes

Here we load our services (symfony) in each Bundle.

Also Lists calls (api-rest list call, defaults limit per model, orderby etc..)

Page 23: A soa approximation on symfony

Others Compilers Passes II

Load the routes per each bundle!

Page 24: A soa approximation on symfony

Controller Services

GeoBundle/Resources/config/services.ymlimports: - resource: ServicesControllers/alpha.yml

We load versionable controllers (alpha, v1..) as services:Right now: alpha (Remember WIP?)

Routes:/alpha/creative/*/current/creative/*

Page 25: A soa approximation on symfony

A lot of CRUD tables-controllers

We have a lot of master- admin tables.

We have a RestController for this purpose.

Controversy:- We have a lot of

classes child of this one.

- Needs refactor in services!

Page 26: A soa approximation on symfony

2nd part

And now ….

The funny part :)

Page 27: A soa approximation on symfony

Generator of code

Once upon a time …We had time and we were youngs :) and we decide to invest time creating a code generator to make our life easier … you know ? developers ... this lazy race

With a lot of database schemas per create we thought that was a good idea to convert this MWB files directly in code … and was a really nightmare ...

Page 28: A soa approximation on symfony

Code generator (AKA mwb-import)

But … it worked

MWB file

it’s a ZIP

xmlsqliteetc ..

unzip

generate code with twig

generate fixtures

Page 29: A soa approximation on symfony

Code generator (AKA mwb-import)

Page 30: A soa approximation on symfony

ApiDoc documentation generator

document !document !document !document !document !document !

Page 31: A soa approximation on symfony

ApiDoc documentation generator

But not only generates documentation.Why don’t use annotations to generate automatic documentation of API routes ?

There are a couple of bundles in the market that do this.

Again … we thought that we can do better.

Page 32: A soa approximation on symfony

ApiDoc documentation generator/*** @ApiDoc\Description("Create an Account")* @ApiDoc\Method("post")* @ApiDoc\Route("/account")* @ApiDoc\Version("~")* @ApiDoc\Subdomain("account")* @ApiDoc\Param(name="maxBudgetValue",type="decimal",nullable=false,description="Account maxBudgetValue")

* @ApiDoc\Header(name="Authorization", placeholder="Authorization: Bearer {token}", type="string", nullable=false, description="mandatory token obtained in login check call")

* @ApiDoc\ReturnHeader("* HTTP 200 OK* Cache-Control: no-cache* Content-Type: application/json* ")* @ApiDoc\ReturnData(type="json", sample="{'id':'integer'}")*/public function createAction(Request $request)

Page 33: A soa approximation on symfony

DocumentatorFeatures:automatic creation of documentation in html format, including a sandbox to test API endpoints

Page 35: A soa approximation on symfony

DocumentatorFeatures:automatic creation of documentation in html format, including a sandbox to test API endpoints

- export to POSTMAN collection

Page 36: A soa approximation on symfony

Call Router

How to make a call to a service that you even know where is ?

LineItem Service - Machine

LineItem Core

LineItem- Campaign - Machine

LineItem

Campaign

Core

Page 37: A soa approximation on symfony

Call Router

How to call a controller method if you don’t know where exactly is ?

Remember, we can deploy to n-servers …To solve that we created a CallRouter that makes the call internally (if the server has the service required) or makes the call external (guzzle) if the service is in another server.

Page 38: A soa approximation on symfony

Call Router

try { // ... $route = $this->router->match($pathInfo);

return $this->makeInternalCall($route['_controller'], $request);

} catch (ResourceNotFoundException $e) {

return $this->makeExternalCall($request->getMethod(), $subdomain, $pathInfo, $request->getContent());

}

Page 39: A soa approximation on symfony
Page 40: A soa approximation on symfony