Javier Jerónimo


Implementación Varnish paywall para revista digital con suscripción (WordPress)

22 Jan 2015 » arquitectura

EDITADO: corregida errata. Gracias a @JesLopCru{.anti-aede-checked}

Genexies Mobile{.anti-aede-checked} ofrece desde hace pocas semanas un nuevo servicio de suscripción bajo el paraguas de Movistar España. Fashion BIP{.anti-aede-checked} es una revista digital en forma de portal web, diseñada específicamente para móviles y tabletas, de suscripción semanal, y con contenidos relacionados con la moda, la belleza y las noticias de actualidad del sector.

En este artículo voy a detallar como hemos creado el servicio usando una implementación propia de Varnish{.anti-aede-checked} Paywall{.anti-aede-checked}, WordPress{.anti-aede-checked} (y algunos plugins propios), y los servicios propios de Genexies que nos permiten integrarnos con los operadores de telefonía móvil, en este caso Movistar España.

Objetivos de la arquitectura del servicio

El desarrollo de este servicio tenía unos objetivos principales desde el punto de vista técnico:

  1. Integrarse con los servicios de Genexies a través de su API privada, con el fin de evitar los detalles de la integración con los sistemas de identificación y cobro de Movistar España.
  2. Proporcionar al visitante y suscriptor una excelente experiencia de uso en tiempo de acceso al contenido.
  3. Evitar en la medida de lo posible el desarrollo de soluciones a medida sobre la plataforma WordPress, usando una distribución estándar con los mínimos plugins necesarios.

El primer objetivo es claro: no reinventar la rueda. Genexies Mobile ofrece servicios de descarga de contenido multimedia bajo la marca de operadores de telefonía móvil, por lo que está integrado con sus sistemas de identificación y cobro. Además, dispone de un API privada donde expone estos servicios, y evidentemente en este nuevo proyecto debíamos usar este API para la integración con Movistar España.

El segundo objetivo no tendría ni que mencionarlo. Un sistema de cache, acelerador web, o como se quiera llamar, es obligado en todo proyecto web que espera un crecimiento y un gran número de visitas. El punto clave aquí es que la solución está construida alrededor de la cache (cache frontal la hemos llamado).

Todo gira entorno a la cache frontal, y me refiero a que los requisitos del resto de componentes dependen directamente de lo siguiente: la cache frontal existe en este servicio, va a existir siempre en este servicio, y son el resto de componentes los que se deben adaptar a esta situación. Podríamos llamarlo “cache driven development“.

El tercer objetivo es fruto de (malas) experiencias pasadas haciendo desarrollos a medida, sin control (todo hay que decirlo), sobre otros CMS (Drupal, etc, etc). En concreto, queríamos evitar a toda costa la implementación de cualquier lógica de cobro o identificación dentro de WordPress.

Arquitectura del servicio

Son cuatro los componentes involucrados en este servicio:

  • Cache frontal: solución basada en Varnish Cache que implementa:
    • Cache web: típica cache Varnish de recursos estáticos (imágenes, scripts, hojas de estilo, etc) y de los propios recursos del contenido (páginas y artículos de WordPress)
    • Barrera de cobros (pay-wall): dado que el contenido de suscripción se puede encontrar en la cache, esta incorpora una lógica de barrera de cobros, permitiendo el acceso solo a los suscriptores.
  • CMS: contiene el portal de contenidos y la interfaz de autoría de los mismos (WordPress).
  • API Genexies: intermediaria en la identificación y cobro a los visitantes clientes de Movistar.
  • Servicios de Movistar de identificación y cobro.

Caso de uso típico del servicio

Para explicar como se integran los componentes de la arquitectura, y sin entrar en detalles, muestro aquí el típico caso de uso: un cliente de Movistar accede al portal usando una conexión wifi, se identifica en Movistar-ID, se suscribe a la revista digital y finalmente accede al contenido.

Arquitectura de acceso a un recurso del portal Fashion BIP (moda.genexies.net){.anti-aede-checked}

NOTA: este diagrama lo he creado con la herramienta online http://plantuml.sourceforge.net/{.anti-aede-checked} que me ha parecido muy útil (me ha dejado de funcionar VisualParadigm for UML en el MacBook desde que actualicé a Mavericks…). Si sientes curiosidad, el código que genera el diagrama es:

title Arquitectura de acceso a un recurso del portal Fashion BIP (moda.genexies.net)
hide footbox
autonumber

actor Visitante as V <<Navegador móvil>>
participant CacheFrontal as C <<Servidor www>>
participant WordPress as W <<Servidor www>>
participant ApiGenexies as A <<Servidor www>>
participant MovistarID as M <<Servidor www>>
participant "Servicio web cobros Movistar" as SPG <<WS>>

activate V
V->C: Accede a recurso en http://moda.genexies.net/...
activate C
C->C: Obtención de cache e identificación del visitante
activate C
C->W: [no en cache] Obtener recurso desde servidor
activate W
deactivate W
C-->V: HTTP 302 redirección a WEB-SSO
note right
El visitante es anónimo, ej:
 - sin cookie de sesión
 - sin navegación por red datos de Movistar
 - etc
end note
deactivate C
deactivate C

== Inicio del proceso de identificación WEB-SSO ==

V->A: Inicia proceso WEB-SSO
activate A
deactivate A

V->M: Identificación en sistemas de Movistar
activate M
note right
Dependiendo del entorno:
 - formulario
 - recordatorio contraseña por SMS
 - etc.
end note
deactivate M

V->A: Termina proceso WEB-SSO
activate A
deactivate A
== Fin del proceso de identificación WEB-SSO ==

V->C: Accede a recurso en http://moda.genexies.net/...
activate C
C->C: Obtención de cache e identificación del visitante
activate C
C->W: [no en cache] Obtener recurso desde servidor
activate W
deactivate W
deactivate C
C->C: ¿Es el visitante suscriptor?
activate C
C->V: HTTP 302 Redirección a carta de pago
note right
Visitante es cliente de Movistar identificado pero no es suscriptor
end note
deactivate C
deactivate C

== Carta de pago y cobro online ==

V->C: Accede a carta de pago
activate C
deactivate C

V->A: Confirma pago usando enlace de API Genexies cobros
activate A
A->SPG: Cobro síncrono
activate SPG
deactivate SPG
A-->V: Redirección a recurso original
deactivate A

== Acceso definitivo a recurso protegido ==

V->C: Accede a recurso en http://moda.genexies.net/...
activate C
C->C: Obtención de cache e identificación del visitante
activate C
C->W: [no en cache] Obtener recurso desde servidor
activate W
deactivate W
deactivate C
C->C: Comprobación suscripción
activate C
deactivate C
C-->V: HTTP 200 OK + recurso original bajo suscripción
deactivate C

Cuestiones que se plantean en la arquitectura

Estas son unas cuestiones interesantes que se plantean al diseñar el servicio con la arquitectura y restricciones explicadas anteriormente.

Barrera de cobros VS acelerador web

Si la cache frontal contiene la lógica correspondiente a la “barrera de cobros”, y por tanto debe acceder a cierta información de cada visitante (¿es el visitante un cliente de Movistar?, ¿tiene una suscripción activa en el servicio?)…¿cómo es esto compatible con una cache web? ¿y cómo se implementa con Varnish?

El punto clave aquí es el siguiente: de cada visitante, que está identificado por una cookie de sesión (y otros mecanismos que no entro a detallar), la cache frontal sólo conoce el ID de sesión, pero mediante llamadas a un API puede obtener toda la información que necesita.

De esta forma, la cache frontal tiene toda la información necesaria para permitir o no a cada visitante el acceso al contenido, sin producir este acceso a dicha información demasiado tiempo extra en la entrega del contenido al visitante, ya que las llamadas a esta API REST también se cachean en la propia cache frontal.

Lógica de negocio en Varnish VS lógica de negocio en WordPress

Si al final tienes que implementar la lógica de negocio, es decir, las restricciones de acceso al contenido de suscripción, la lógica de identificación, la de cobro, etc, ¿qué más da implementarla en WordPress que en Varnish?, además, WordPress es PHP y Varnish pseudo-C{.anti-aede-checked}… ¿no será mejor hacer todo en WordPress directamente?

Vamos a repasar punto por punto:

  • Tenemos un API que sabe cómo identificar y cobrar a clientes de Movistar España. Simplemente redirigimos al visitante a ese API web (escenarios (web-sso y web-billing los hemos llamado), y cuando vuelve ya es un cliente de Movistar conocido y/o suscrito al servicio. Delegamos en el API de Genexies para esa lógica de identificación y cobro. Ni a favor, ni en contra: +1 Varnish, +1 WordPress
  • Tenemos un API REST para llamadas servidor-servidor, cacheable, y que por tanto no supone prácticamente ninguna sobrecarga en el tiempo de procesamiento de cada visita. Varnish o WordPress obtendrían de ese API la información de estado de suscripción de cada visitante cliente de Movistar. Ni a favor, ni en contra: +1 Varnish, +1 WordPress.
  • Cache-driven-development. Lo voy a justificar al revés. Si WordPress y sólo WordPress tiene la lógica de la barrera de cobros, todo el tráfico debe llegar a WordPress. Si todo el tráfico debe llegar a WordPress, no se puede tener una cache externa a WordPress para el contenido de suscripción. Ahora habría que entrar a valorar los sistemas de cache integrados en WordPress y los externos (Varnish, CDN, etc).
  • En Genexies ya tenemos una instalación base de Varnish, sirviendo cada vez más portales de los distintos servicios que ofrece la empresa, con bastante código propio de las integraciones que tenemos con cada uno de los operadores, con un porcentaje altísimo de cobertura del código VCL de Varnish en las pruebas, con el ciclo de vida del proyecto automatizado al completo (infraestructura, pruebas, despliegue), con un foco importantísimo puesto en esta herramienta para crear la cache frontal de los servicios de Genexies… Esto son razones muy personales de nuestra empresa, pero justifican claramente un +1 para Varnish.

Las decisiones de diseño, y la arquitectura es diseño, dependen mucho de cada circunstancia. Quizá en una empresa donde WordPress sea el centro de los desarrollos, se podría haber implementado la misma arquitectura pero centrada en WordPress, usando sus mecanismos de cache para los contenidos de suscripción (artículos), y dejando a caches externas (CDNs) los demás recursos. Hubiera sido una solución igualmente válida.

Conclusiones

El servicio está en funcionamiento desde hace varias semanas, y salvo el “ruido” inicial de la puesta en producción, los sistemas parecen estar funcionando correctamente, la suscripción está funcionando, y ya estamos pensando en las siguientes mejoras del servicio (mejoras para aumentar la conversión, las altas.. que es de lo que al final va esto, de vender).

Es importante tener en consideración que tanto el API de Genexies y sus integraciones con los servicios de Movistar, como la propia cache frontal ya estaban en producción usándose en otros servicios de Genexies. No obstante, en esos casos hemos tenido que realizar alguna adaptación y pruebas de integración con los nuevos componentes.

En cuanto al desarrollo de la solución propia de pay-wall en Varnish, y aunque se ha hecho desde cero para este servicio, se puede usar como base para otros que tengan este modelo de suscripción all-you-can-eat (AUCE).

De hecho, en los próximos meses el servicio de suscripción evolucionará, y la solución pay-wall que hemos implementado en Varnish se refinará para adaptarse y permitir otros modelos de negocio distintos al actual AUCE. En cualquier caso, la arquitectura básica de este servicio pay-wall seguirá siendo la misma.