Hello World
•   Ricard Clau Pintado

•   Trabajo en SocialPoint

•   Antes en Emagister, Ulabox y Privalia

•   Fundador Symfony-Barcelona

•   Blogger http://www.ricardclau.com

•   Twitter @ricardclau
¿Qué vamos a ver?
•   Arquitectura orientada a servicios (SOA)

•   La capa de modelo en Symfony2

•   Servicios en Symfony2

•   Componente Configuration

•   Inyección de dependencias

•   Experiencias en el desarrollo de Ulabox.com
Arquitectura SOA
        Teoría y filosofía
El concepto SOA
•   Arquitectura Orientada a Servicios

•   Los Servicios son clases creadas para desarrollar una
    función específica y se pueden utilizar en cualquier punto
    de nuestra aplicación.

•   Encapsulando la lógica de negocio en servicios podemos
    desacoplar las clases de nuestra aplicación, que podrá
    crecer “sin problemas”

•   Todas las plataformas grandes lo usan (o deberían)
No todo es tan fácil
•   Es una filosofía entorno al patrón de diseño Service Layer

•   Parece que estamos trabajando más

•   Es muy importante delimitar la responsabilidad de cada
    servicio y no acoplarlos

•   Hay que concienciar a todo el equipo, formar a los juniors
    y convencer a la gente con malos hábitos

•   Puede ser complicado de aplicar en código legado

•   Pero... ¡se puede hacer gradualmente!
Servicios acoplados
Servicios desacoplados :)
El modelo en Symfony2
        Introducción a los servicios
La evolución del MVC
•   Symfony2 no es un framework MVC estrictamente

•   De hecho, la carpeta “Model” no existe por defecto!

•   Es tan flexible que nos da la libertad de construir la capa
    de Modelo como convenga a nuestra aplicación

•   Y eso puede ser peligroso...
Y entonces... ¿Doctrine2?
•   Doctrine2 abstrae el acceso al sistema de
    almacenamiento, tanto SQL como algunos No-SQL

•   Las “Entities” mapean tablas (ORM) / documentos (ODM)

•   Los “Repositories” permiten encapsular operaciones y
    realizar consultas algo más complejas

•   Pero ahí no debería ir la lógica de negocio!
El modelo en Symfony2
•   En Symfony2, más que hablar del modelo, podemos
    hablar de la capa de servicios

•   Hay que evitar los controllers de 2000 líneas

•   En los repositories no deberíamos poner lógica de
    negocio, son para querys complejas

•   Las vistas deben tener la mínima lógica posible

•   Cada servicio debe recibir sólo lo que necesita y exponer
    unas interficies claras para su uso. Nunca usar el Request
    ni modificar la Response.
Servicios en Symfony2
            Ejemplos prácticos
Servicios en Symfony2
•   Muchos de los componentes de Symfony2 están
    disponibles como servicios

•   Algunos: Doctrine2 Entity Manager, Swiftmailer,
    Validator, Translator, Templating, Routing, ...

•   Muchos bundles añaden nuevos servicios y podemos
    crear nuestros propios servicios!

•   Acceso mediante el “Dependency Injection Container”
    desde las clases con interface “ContainerAware”
Listado de servicios
•   php app/console container:debug
¿Qué tengo en el container?
•   https://github.com/Elao/WebProfilerExtraBundle
Debug del container (I)
•   https://github.com/schmittjoh/JMSDebuggingBundle
Debug del container (II)
•   https://github.com/schmittjoh/JMSDebuggingBundle
Validator Service
Mailer Service
Configurando la aplicación
      Carga de nodos y inyección al container
Configuraciones en Symfony2
•   app/config -> aplicación Resources/config -> Bundles

•   Configuración base que extendemos para el resto de
    entornos



•   Conveniente separarlo en varios archivos
[parameters]
•   Se suelen definir constantes de configuración

•   Permite que cada usuario tenga el setup como quiera

•   Los valores bajo la clave [parameters] se inyectan en el
    container directamente. Podemos usarlos en otras
    secciones con %valor%

•   Podemos crear nuestras propias claves para configurar
    nuestros bundles, que deberán ser leídas en los archivos
    de la carpeta DependencyInjection
Configuración compleja
•   Se inyecta bien pero no tenemos validación!
Bundle complejo -> a validar!
•   Creamos los parámetros bajo la clave de nuestro bundle
TreeBuilder
•   Creamos un TreeBuilder en una clase Configuration
    dentro de la carpeta DependencyInjection
Validando parámetros texto
Validando estructura array
Jugueteando con el array
Exprimiendo el componente!
BundleExtension
•   Inyectamos la configuración en la Extension:
Creación de servicios
       Inyección de dependencias
Hello world Servicios
•   Servicio para recuperar información de Sensio Connect!
Config y uso del servicio
•   En el config de la aplicación



•   Modificamos services.yml en Resources/config




•   Y desde el controller
Dependencias de un servicio
•   Un servicio puede depender de parámetros de
    configuración y/o de otros servicios

•   Nos referimos a los parámetros con %param% y los
    servicios con @nombre_servicio

•   Constructor Injection -> arguments:
Dependencias opcionales
•   Setter Injection y otras inicializaciones -> calls

•   Podemos combinarlo todo en servicios complejos
Antipattern: setContainer
Aplicaciones complejas
      Servicios parent, factories y tags
Servicios abstract / parent
Service Factories
•   El mejor ejemplo son los repositories




•   Pero si hacemos esto




•   Los controllers quedan así de limpios!
Service Tags (I)
•   Agrupación de servicios

•   El tag en sí no significa nada pero puede ser útil para
    extender componentes con nuevos loaders / adapters.
    Suelen procesarse en las CompilerPass

•   Lo usamos en Twig para cargar extensiones
Service Tags (II)
•   El componente Translator lo usa para los loaders




•   O cuando necesitamos crear un Event Listener
E-commerce con servicios
    Web                Backoffice              API (Iphone, ...)

KernelController Listeners / Before hooks (autenticaciones, ...)

   Controllers ligeros que traducen Request a parámetros

       Servicios de primer nivel / unidades de negocio             M
             (Customer, Cart, Order, Catalogue)
                                                                   O
            Servicios auxiliares a modo de Helpers
          (Logger, Translator, Validator, Mailer, ...)
                                                                   D
               Interacción Storage / 3rd party
                                                                   E
  (Entities, Repositories, Solarium, PRedis, OpenInviter...)       L
   BBDD            No-SQL / Caches            3rd Party APIs
Agradecimientos
•   A los Ulaboxers PHPeros: Sergi, Albert, Marc

•   Al equipo #rigor de @EmagisterTech

•   A la organización y sponsors de DeSymfony

•   A todos vosotros :)
¿Preguntas?
•   E-mail: ricard.clau@gmail.com

•   Twitter: @ricardclau

•   Github: https://github.com/ricardclau




•   O si os da corte ahora... en otro momento :)

Desymfony - Servicios

  • 3.
    Hello World • Ricard Clau Pintado • Trabajo en SocialPoint • Antes en Emagister, Ulabox y Privalia • Fundador Symfony-Barcelona • Blogger http://www.ricardclau.com • Twitter @ricardclau
  • 4.
    ¿Qué vamos aver? • Arquitectura orientada a servicios (SOA) • La capa de modelo en Symfony2 • Servicios en Symfony2 • Componente Configuration • Inyección de dependencias • Experiencias en el desarrollo de Ulabox.com
  • 5.
    Arquitectura SOA Teoría y filosofía
  • 6.
    El concepto SOA • Arquitectura Orientada a Servicios • Los Servicios son clases creadas para desarrollar una función específica y se pueden utilizar en cualquier punto de nuestra aplicación. • Encapsulando la lógica de negocio en servicios podemos desacoplar las clases de nuestra aplicación, que podrá crecer “sin problemas” • Todas las plataformas grandes lo usan (o deberían)
  • 7.
    No todo estan fácil • Es una filosofía entorno al patrón de diseño Service Layer • Parece que estamos trabajando más • Es muy importante delimitar la responsabilidad de cada servicio y no acoplarlos • Hay que concienciar a todo el equipo, formar a los juniors y convencer a la gente con malos hábitos • Puede ser complicado de aplicar en código legado • Pero... ¡se puede hacer gradualmente!
  • 8.
  • 9.
  • 10.
    El modelo enSymfony2 Introducción a los servicios
  • 11.
    La evolución delMVC • Symfony2 no es un framework MVC estrictamente • De hecho, la carpeta “Model” no existe por defecto! • Es tan flexible que nos da la libertad de construir la capa de Modelo como convenga a nuestra aplicación • Y eso puede ser peligroso...
  • 12.
    Y entonces... ¿Doctrine2? • Doctrine2 abstrae el acceso al sistema de almacenamiento, tanto SQL como algunos No-SQL • Las “Entities” mapean tablas (ORM) / documentos (ODM) • Los “Repositories” permiten encapsular operaciones y realizar consultas algo más complejas • Pero ahí no debería ir la lógica de negocio!
  • 13.
    El modelo enSymfony2 • En Symfony2, más que hablar del modelo, podemos hablar de la capa de servicios • Hay que evitar los controllers de 2000 líneas • En los repositories no deberíamos poner lógica de negocio, son para querys complejas • Las vistas deben tener la mínima lógica posible • Cada servicio debe recibir sólo lo que necesita y exponer unas interficies claras para su uso. Nunca usar el Request ni modificar la Response.
  • 14.
    Servicios en Symfony2 Ejemplos prácticos
  • 15.
    Servicios en Symfony2 • Muchos de los componentes de Symfony2 están disponibles como servicios • Algunos: Doctrine2 Entity Manager, Swiftmailer, Validator, Translator, Templating, Routing, ... • Muchos bundles añaden nuevos servicios y podemos crear nuestros propios servicios! • Acceso mediante el “Dependency Injection Container” desde las clases con interface “ContainerAware”
  • 16.
    Listado de servicios • php app/console container:debug
  • 17.
    ¿Qué tengo enel container? • https://github.com/Elao/WebProfilerExtraBundle
  • 18.
    Debug del container(I) • https://github.com/schmittjoh/JMSDebuggingBundle
  • 19.
    Debug del container(II) • https://github.com/schmittjoh/JMSDebuggingBundle
  • 20.
  • 21.
  • 22.
    Configurando la aplicación Carga de nodos y inyección al container
  • 23.
    Configuraciones en Symfony2 • app/config -> aplicación Resources/config -> Bundles • Configuración base que extendemos para el resto de entornos • Conveniente separarlo en varios archivos
  • 24.
    [parameters] • Se suelen definir constantes de configuración • Permite que cada usuario tenga el setup como quiera • Los valores bajo la clave [parameters] se inyectan en el container directamente. Podemos usarlos en otras secciones con %valor% • Podemos crear nuestras propias claves para configurar nuestros bundles, que deberán ser leídas en los archivos de la carpeta DependencyInjection
  • 25.
    Configuración compleja • Se inyecta bien pero no tenemos validación!
  • 26.
    Bundle complejo ->a validar! • Creamos los parámetros bajo la clave de nuestro bundle
  • 27.
    TreeBuilder • Creamos un TreeBuilder en una clase Configuration dentro de la carpeta DependencyInjection
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
    BundleExtension • Inyectamos la configuración en la Extension:
  • 33.
    Creación de servicios Inyección de dependencias
  • 34.
    Hello world Servicios • Servicio para recuperar información de Sensio Connect!
  • 35.
    Config y usodel servicio • En el config de la aplicación • Modificamos services.yml en Resources/config • Y desde el controller
  • 36.
    Dependencias de unservicio • Un servicio puede depender de parámetros de configuración y/o de otros servicios • Nos referimos a los parámetros con %param% y los servicios con @nombre_servicio • Constructor Injection -> arguments:
  • 37.
    Dependencias opcionales • Setter Injection y otras inicializaciones -> calls • Podemos combinarlo todo en servicios complejos
  • 38.
  • 39.
    Aplicaciones complejas Servicios parent, factories y tags
  • 40.
  • 41.
    Service Factories • El mejor ejemplo son los repositories • Pero si hacemos esto • Los controllers quedan así de limpios!
  • 42.
    Service Tags (I) • Agrupación de servicios • El tag en sí no significa nada pero puede ser útil para extender componentes con nuevos loaders / adapters. Suelen procesarse en las CompilerPass • Lo usamos en Twig para cargar extensiones
  • 43.
    Service Tags (II) • El componente Translator lo usa para los loaders • O cuando necesitamos crear un Event Listener
  • 44.
    E-commerce con servicios Web Backoffice API (Iphone, ...) KernelController Listeners / Before hooks (autenticaciones, ...) Controllers ligeros que traducen Request a parámetros Servicios de primer nivel / unidades de negocio M (Customer, Cart, Order, Catalogue) O Servicios auxiliares a modo de Helpers (Logger, Translator, Validator, Mailer, ...) D Interacción Storage / 3rd party E (Entities, Repositories, Solarium, PRedis, OpenInviter...) L BBDD No-SQL / Caches 3rd Party APIs
  • 45.
    Agradecimientos • A los Ulaboxers PHPeros: Sergi, Albert, Marc • Al equipo #rigor de @EmagisterTech • A la organización y sponsors de DeSymfony • A todos vosotros :)
  • 46.
    ¿Preguntas? • E-mail: ricard.clau@gmail.com • Twitter: @ricardclau • Github: https://github.com/ricardclau • O si os da corte ahora... en otro momento :)