Raul Jimenez
Experto en Drupal
Drupal – ¿Qué son los servicios?
Como ya hemos hablado en otros artículos, drupal 8 se actualizo integrándose con symfony, haciendo que pudiéramos reutilizar gran parte de las funcionalidades de este framework. Pues bien hoy vamos a hablar de una de ellas, «los servicios».
La definición de un servicio es relativamente sencilla, se considera un servicio a una funcionalidad concreta, la cual podemos reutilizar en cualquier parte de nuestra app.
Aunque esta definición, explica exactamente lo que hace un servicio, en este artículo, vamos a tratar de expandir y entender que es un servicio y para qué sirven.
¿Como se crea un servicio de calidad?
Como vimos antes, la finalidad de un servicio no es más que proveer una funcionalidad concreta en un momento determinado de nuestra app y para eso symfony nos proporciona un contenedor «container» en el cual almacena todos los servicios definidos en nuestra app.
El hecho de symfony almacene todos los servicios dentro de un contenedor no es más que una forma de centralizar y agilizar nuestra app. haciendo que con una simple consulta al contenedor podamos obtener cualquier tipo de funcionalidad que necesitemos.
Antes de empezar a crear un servicio, hemos de tener claro un par de puntos que nos ayudarán a crear servicios de calidad:
- Funcionalidades concretas: Uno de los errores más comunes a la hora de crear un servicio es la de poner muchas funcionalidades juntas, por ejemplo juntar la lógica de negocio con la plantilla.
Para crear un servicio de calidad, la idea es que el servicio se encargue solamente de lo que se tiene que encargar, por ejemplo si tenemos un servicio que obtiene datos de la base de datos, lo que devolverá será un array o objeto con la información obtenida, permitiendo que tu app u otro servicio manipule esta información en base a la lógica de negocio. - Definición del servicio: Aunque en esencia los servicios son clases repartidas por nuestros plugins, estos se han de definir en un archivo, por lo general el archivo sera asi: mi_modulo.services.yml
- Inyección de dependencias: Una de las cosas que hacen poderoso a este sistema basado en servicios es, que a los mismos servicios les podemos inyectar otros servicios. Haciendo que nuestro servicio puede reutilizar funcionalidades ya hechas en otros servicios. Parece un poco lio pero veamos un ejemplo.
Imaginaos, un servicio que obtiene datos desde una base de datos, en lugar de nosotros crear una nueva conexión a la base de datos, podríamos usar el servicio «database» para realizar todas nuestras consultas. - Tamaño del servicios: Aunque no existe un tamaño máximo definido, el hecho de que nuestro servicio sea muy concreto y pequeño, hace que sea más reutilizable a lo largo de la aplicación.
Si te encuentras en el caso de que tu servicio se hace muy grande, trata de pensar como puede dividirlo en servicios más pequeños.
Creando un servicio en drupal.
Crear un servicio en drupal es extremadamente sencillo, tendremos dos opciones, usando drupal-console, es decir, por línea de comando o de forma manual. Vamos a hacerlo fácil y lo haremos con drupal-console ya que además nos lo autocompleta con comentarios y quedará más profesional.
Vayamos a la línea de comandos y ejecutemos la siguiente línea:
drupal gs
El comando anterior nos dará paso a un pequeño formulario que nos ayudará a generar nuestro servicio, en el siguiente ejemplo añadirle un servicio a un módulo ya creado por mi llamado «miservicio».
// Welcome to the Drupal service generator
Enter the module name [lockcapsula]:
> miservicio
Enter the service name [miservicio.default]:
> miservicio.primer_servicio
Enter the Class name [DefaultService]:
> PrimerServicioService
Create an interface (yes/no) [yes]:
> no
Create a logger channel (yes/no) [yes]:
> no
Do you want to load services from the container? (yes/no) [no]:
> yes
Type the service name or use keyup or keydown.
This is optional, press enter to continue
Enter your service []:
> logger.factory
Enter your service []:
>
Enter the path for the services [/modules/custom/miservicio/src/]:
>
Do you want proceed with the operation? (yes/no) [yes]:
>
// cache:rebuild
Rebuilding cache(s), wait a moment please.
[OK] Done clearing cache(s).
Generated or updated files
Generation path: /var/www/html/web
1 - modules/custom/miservicio/miservicio.services.yml
2 - modules/custom/miservicio/src/PrimerServicioService.php
Generated lines: 32
Detenemos un min a leer y entender bien la construcción del servicio anterior, lo que he hecho básicamente es, añadir un servicio llamado «miservicio.primer_servicio» dentro del módulo «miservicio» y ademas le he inyectado otro servicio llamado «logger.factory» para poder guardar un registro en el log de drupal.
Esto me ha creado dos archivos el primero es la definición del servicio:
modules/custom/miservicio/miservicio.services.yml
services:
miservicio.primer_servicio:
class: Drupal\miservicio\PrimerServicioService
arguments: ['@logger.factory']
modules/custom/miservicio/src/PrimerServicioService.php
namespace Drupal\miservicio;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
/**
* Class PrimerServicioService.
*/
class PrimerServicioService {
/**
* Drupal\Core\Logger\LoggerChannelFactoryInterface definition.
*
* @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
*/
protected $loggerFactory;
/**
* Constructs a new PrimerServicioService object.
*/
public function __construct(LoggerChannelFactoryInterface $logger_factory) {
$this->loggerFactory = $logger_factory;
}
}
Como podemos ver, en los archivos generados, en el .yml tenemos la definición del servicio donde le decimos además, que nos inyecte el servicio «@logger.factory» y en el «PrimerServicioService.php» tenemos ya creado la base de nuestro servicio con el «@logger.factory» ya declarado, inyectado e iniciado.
Como veis usando la línea de comandos es extremadamente útil para generar de forma rápida y sencilla un servicio complejo.
¿Como usar nuestro servicio?
Ahora que ya tenemos nuestro servicio vamos a crear un método que lo que hara sera unicamente registrar un log en drupal para eso a nuestra clase PrimerServicioService le añadiremos lo siguiente.
/**
* Log $string on drupal log system
*
* @param String $string
* @return void
*/
public function log($string){
$this->loggerFactory->get('miservicio')->error('Log: @string', [
'@string' => $string,
]);
}
Ahora ya solo nos falta llamar a nuestro servicio y ejecutarlo y para eso solamente tendremos que recuperar nuestro servicio desde el «contenedor de servicios».
\Drupal::service('miservicio.primer_servicio')->log('Este es mi registro');
Conclusión
Como habéis visto el uso de servicios hace que nuestra aplicación sea más fuerte y sencilla de usar, en este ejemplo hemos visto cómo podemos reutilizar toda una funcionalidad de otro servicio integrarlo en el nuestro y ejecutar una acción concreta con solamente una línea de llamada.
Es importante que si trabajáis con drupal empecéis a trabajar con este sistema y veréis como a la larga os facilitara la vida.
Espero que te haya servido y sobretodo cuentame cual fue tu experiencia y comparte este conocimiento!