SlideShare a Scribd company logo
A SOA Approximation using Symfony
Joseluis Laso & Carlos Agudo
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)
Where?
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.
Long journey
From monolithic sf1 (legacy , 8 years of development)
to a SOA in sf2-3:
Requirements
• API Rest
• Auto Scalable (can be a huge huge demanding
platform)
• Symfony 2
• Easy to deploy
So?
Do not try this at home
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.”
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)
Our motto
Let’s split it later
And let’s start!!
Backend Services View
Bundles
Yes, services bundles
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
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
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!
Cooking Process 3
In our AppKernel.php. We have the LocateBundles (utility
class) in a CoreBundle
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
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:
Models 2
We want to use our own folders:
Base?? We will explain it later, we have an
autogenerator of code.
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:ThirdPartyData
Geo:City
ServiceName:Model
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..)
Others Compilers Passes II
Load the routes per each bundle!
Controller Services
GeoBundle/Resources/config/services.yml
imports:
- resource: ServicesControllers/alpha.yml
We load versionable controllers (alpha, v1..) as services:
Right now: alpha (Remember WIP?)
Routes:
/alpha/creative/*
/current/creative/*
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!
2nd part
And now ….
The funny part :)
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 ...
Code generator (AKA mwb-import)
But … it worked
MWB file
it’s a ZIP
xml
sqlite
etc ..
unzip
generate
code with twig
generate
fixtures
Code generator (AKA mwb-import)
ApiDoc documentation generator
document !
document !
document !
document !
document !
document !
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.
ApiDoc documentation generator
/**
* @ApiDocDescription("Create an Account")
* @ApiDocMethod("post")
* @ApiDocRoute("/account")
* @ApiDocVersion("~")
* @ApiDocSubdomain("account")
* @ApiDocParam(name="maxBudgetValue",type="decimal",nullable=false,description="Account
maxBudgetValue")
* @ApiDocHeader(name="Authorization", placeholder="Authorization: Bearer {token}", type="string",
nullable=false, description="mandatory token obtained in login check call")
* @ApiDocReturnHeader("
* HTTP 200 OK
* Cache-Control: no-cache
* Content-Type: application/json
* ")
* @ApiDocReturnData(type="json", sample="{'id':'integer'}")
*/
public function createAction(Request $request)
Documentator
Features:
automatic creation of documentation in html format,
including a sandbox to test API endpoints
Documentator
Documentator
Features:
automatic creation of documentation in html format,
including a sandbox to test API endpoints
- export to
POSTMAN
collection
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
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.
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());
}
A soa approximation on symfony
A soa approximation on symfony

More Related Content

PPTX
Graphql + Symfony | Александр Демченко | CODEiD
PDF
Symfony + GraphQL
PDF
Functional Programming in JavaScript
PDF
Reddirt2011
PDF
Jit builder status and directions 2018 03-28
PPTX
Ruby on Rails : First Mile
PDF
Camel Day Italia 2021 - Camel K
Graphql + Symfony | Александр Демченко | CODEiD
Symfony + GraphQL
Functional Programming in JavaScript
Reddirt2011
Jit builder status and directions 2018 03-28
Ruby on Rails : First Mile
Camel Day Italia 2021 - Camel K

Viewers also liked (13)

PDF
Behavioral driven development with Behat
PDF
Microservice Teststrategie mit Symfony2
PDF
Tips and Tricks for your Service Oriented Architecture @ CakeFest 2013 in San...
PPTX
What mom never told you about bundle configurations - Symfony Live Paris 2012
 
PPTX
A SOA approximation on symfony
PDF
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
PDF
Microservice architecture
PDF
Symfony in microservice architecture
PDF
High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014
PPTX
SOA with PHP and Symfony
PDF
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
PDF
Screaming Architecture with Symfony
PPTX
Fracaso renal agudo
Behavioral driven development with Behat
Microservice Teststrategie mit Symfony2
Tips and Tricks for your Service Oriented Architecture @ CakeFest 2013 in San...
What mom never told you about bundle configurations - Symfony Live Paris 2012
 
A SOA approximation on symfony
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
Microservice architecture
Symfony in microservice architecture
High Quality Symfony Bundles tutorial - Dutch PHP Conference 2014
SOA with PHP and Symfony
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Screaming Architecture with Symfony
Fracaso renal agudo
Ad

Similar to A soa approximation on symfony (20)

PDF
2025-03-20 - How to use AI to your advantage - AI-Driven Development.pdf
PDF
AOMEI Backupper Crack 2025 FREE Download
PDF
Wondershare PDFelement Pro Crack FREE Download
PDF
Wondershare Filmora 14.3.2 Crack + License Key Free Download
PPTX
VisualWeb - Building a NodeJS Server Meshwork and Full-Javascript Stack Frame...
PPTX
Kubernetes - State of the Union (Q1-2016)
PPTX
Enterprise Integration Patterns and Apache Camel
PDF
Build your own discovery index of scholary e-resources
PPTX
IoT Service Bus - High availability with Internet of Things (IoT)/ API Rest/ ...
PPTX
Building a scalable API with Grails
PDF
Toward Hybrid Cloud Serverless Transparency with Lithops Framework
PDF
OCCIware Project at EclipseCon France 2016, by Marc Dutoo, Open Wide
PDF
EclipseCon 2016 - OCCIware : one Cloud API to rule them all
PDF
Has serverless adoption hit a roadblock?
PDF
Microservices, Kubernetes and Istio - A Great Fit!
PDF
Apache Kafka® Delivers a Single Source of Truth for The New York Times
PPTX
OpenDaylight Developer Experience 2.0
PDF
Microservices in Golang
PDF
Robust MLOps with Open-Source: ModelDB, Docker, Jenkins, and Prometheus
PDF
Writing Rust Command Line Applications
2025-03-20 - How to use AI to your advantage - AI-Driven Development.pdf
AOMEI Backupper Crack 2025 FREE Download
Wondershare PDFelement Pro Crack FREE Download
Wondershare Filmora 14.3.2 Crack + License Key Free Download
VisualWeb - Building a NodeJS Server Meshwork and Full-Javascript Stack Frame...
Kubernetes - State of the Union (Q1-2016)
Enterprise Integration Patterns and Apache Camel
Build your own discovery index of scholary e-resources
IoT Service Bus - High availability with Internet of Things (IoT)/ API Rest/ ...
Building a scalable API with Grails
Toward Hybrid Cloud Serverless Transparency with Lithops Framework
OCCIware Project at EclipseCon France 2016, by Marc Dutoo, Open Wide
EclipseCon 2016 - OCCIware : one Cloud API to rule them all
Has serverless adoption hit a roadblock?
Microservices, Kubernetes and Istio - A Great Fit!
Apache Kafka® Delivers a Single Source of Truth for The New York Times
OpenDaylight Developer Experience 2.0
Microservices in Golang
Robust MLOps with Open-Source: ModelDB, Docker, Jenkins, and Prometheus
Writing Rust Command Line Applications
Ad

Recently uploaded (20)

PDF
Perfecting Gamer’s Experiences with Performance Testing for Gaming Applicatio...
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PPTX
Save Business Costs with CRM Software for Insurance Agents
PDF
How to Choose the Most Effective Social Media Agency in Bangalore.pdf
PPTX
Hire Expert Blazor Developers | Scalable Solutions by OnestopDA
PDF
IEEE-CS Tech Predictions, SWEBOK and Quantum Software: Towards Q-SWEBOK
PDF
Micromaid: A simple Mermaid-like chart generator for Pharo
PDF
The Role of Automation and AI in EHS Management for Data Centers.pdf
PDF
Become an Agentblazer Champion Challenge Kickoff
PPTX
Materi-Enum-and-Record-Data-Type (1).pptx
PPTX
10 Hidden App Development Costs That Can Sink Your Startup.pptx
PDF
Comprehensive Salesforce Implementation Services.pdf
PDF
Community & News Update Q2 Meet Up 2025
PPTX
Odoo Consulting Services by CandidRoot Solutions
PDF
Jenkins: An open-source automation server powering CI/CD Automation
PDF
How to Confidently Manage Project Budgets
PDF
QAware_Mario-Leander_Reimer_Architecting and Building a K8s-based AI Platform...
PDF
Exploring AI Agents in Process Industries
PDF
Convert Thunderbird to Outlook into bulk
PDF
Build Multi-agent using Agent Development Kit
Perfecting Gamer’s Experiences with Performance Testing for Gaming Applicatio...
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Save Business Costs with CRM Software for Insurance Agents
How to Choose the Most Effective Social Media Agency in Bangalore.pdf
Hire Expert Blazor Developers | Scalable Solutions by OnestopDA
IEEE-CS Tech Predictions, SWEBOK and Quantum Software: Towards Q-SWEBOK
Micromaid: A simple Mermaid-like chart generator for Pharo
The Role of Automation and AI in EHS Management for Data Centers.pdf
Become an Agentblazer Champion Challenge Kickoff
Materi-Enum-and-Record-Data-Type (1).pptx
10 Hidden App Development Costs That Can Sink Your Startup.pptx
Comprehensive Salesforce Implementation Services.pdf
Community & News Update Q2 Meet Up 2025
Odoo Consulting Services by CandidRoot Solutions
Jenkins: An open-source automation server powering CI/CD Automation
How to Confidently Manage Project Budgets
QAware_Mario-Leander_Reimer_Architecting and Building a K8s-based AI Platform...
Exploring AI Agents in Process Industries
Convert Thunderbird to Outlook into bulk
Build Multi-agent using Agent Development Kit

A soa approximation on symfony

  • 1. A SOA Approximation using Symfony Joseluis Laso & Carlos Agudo
  • 2. 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)
  • 4. 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.
  • 5. Long journey From monolithic sf1 (legacy , 8 years of development) to a SOA in sf2-3:
  • 6. Requirements • API Rest • Auto Scalable (can be a huge huge demanding platform) • Symfony 2 • Easy to deploy
  • 7. So?
  • 8. Do not try this at home
  • 9. 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.”
  • 10. 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)
  • 11. Our motto Let’s split it later And let’s start!!
  • 14. 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
  • 15. 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
  • 16. 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!
  • 17. Cooking Process 3 In our AppKernel.php. We have the LocateBundles (utility class) in a CoreBundle
  • 18. 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
  • 19. 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:
  • 20. Models 2 We want to use our own folders: Base?? We will explain it later, we have an autogenerator of code.
  • 21. 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:ThirdPartyData Geo:City ServiceName:Model
  • 22. 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..)
  • 23. Others Compilers Passes II Load the routes per each bundle!
  • 24. Controller Services GeoBundle/Resources/config/services.yml imports: - resource: ServicesControllers/alpha.yml We load versionable controllers (alpha, v1..) as services: Right now: alpha (Remember WIP?) Routes: /alpha/creative/* /current/creative/*
  • 25. 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!
  • 26. 2nd part And now …. The funny part :)
  • 27. 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 ...
  • 28. Code generator (AKA mwb-import) But … it worked MWB file it’s a ZIP xml sqlite etc .. unzip generate code with twig generate fixtures
  • 29. Code generator (AKA mwb-import)
  • 30. ApiDoc documentation generator document ! document ! document ! document ! document ! document !
  • 31. 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.
  • 32. ApiDoc documentation generator /** * @ApiDocDescription("Create an Account") * @ApiDocMethod("post") * @ApiDocRoute("/account") * @ApiDocVersion("~") * @ApiDocSubdomain("account") * @ApiDocParam(name="maxBudgetValue",type="decimal",nullable=false,description="Account maxBudgetValue") * @ApiDocHeader(name="Authorization", placeholder="Authorization: Bearer {token}", type="string", nullable=false, description="mandatory token obtained in login check call") * @ApiDocReturnHeader(" * HTTP 200 OK * Cache-Control: no-cache * Content-Type: application/json * ") * @ApiDocReturnData(type="json", sample="{'id':'integer'}") */ public function createAction(Request $request)
  • 33. Documentator Features: automatic creation of documentation in html format, including a sandbox to test API endpoints
  • 35. Documentator Features: automatic creation of documentation in html format, including a sandbox to test API endpoints - export to POSTMAN collection
  • 36. 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
  • 37. 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.
  • 38. 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()); }