Construction du site elleXX
elleXX est un site web destinĂ© Ă aider les femmes Ă joindre les deux bouts. Il a Ă©tĂ© crĂ©Ă© par des journalistes qui Ă©crivent de nombreux contenus utiles sur le sujet. En tant que femme en Suisse, je suis particuliĂšrement sensible Ă cette problĂ©matique, dâautant quâelle est trĂšs proche des valeurs de Liip. La principale tĂąche du site elleXX Ă©tait de permettre la publication rapide et simple de contenus. Il a aussi fallu prĂ©voir lâintĂ©gration de certains produits conçus pour faciliter la gestion financiĂšre, ainsi que le suivi des membres.
Pour la gestion de contenu, nous avons choisi de travailler avec le CMS Ghost. Une dĂ©cision qui nâest pas le fruit du hasard, car Ghost est vraiment trĂšs adaptĂ© Ă ce dont nous avions le plus besoin : le contenu. Dâautre part, Ghost est entiĂšrement financĂ© par ses utilisateursârices, câest un CMS open source !
Pour assurer le suivi des leads et des contacts, nous avons optĂ© pour Friendly Automatic. Pour une simple et bonne raison : câest une entreprise suisse locale, reposant qui plus est sur Mautic, un framework bien connu pour les solutions marketing.
Il nous a aussi fallu intĂ©grer des outils propres au client, Ă savoir Vontobel, MigrosBank et Cap Rechtsschutz. Pour cela, nous avons conçu notre propre API Ă lâaide du framework JS Nest.js. Avec Nest.js, la crĂ©ation dâune API est simple et rapide. Nous autres dĂ©veloppeurâeuses pouvons ainsi nous concentrer davantage sur la logique de lâAPI que sur la conception du routing etc. Nous avons ensuite utilisĂ© notre API depuis notre instance Ghost.
Lorsquâest venu le temps de personnaliser les fonctionnalitĂ©s du site, Ghost nâa pas Ă©tĂ© aussi flexible que nous lâaurions souhaitĂ©. Nous avons donc dĂ» forker Ghost et peaufiner notre propre version. Le client voulait par exemple simplifier et uniformiser lâaffichage de certains contenus. En gĂ©nĂ©ral, on essaie plutĂŽt dâĂ©viter dâavoir Ă crĂ©er un fork dâun code source, mais cette opĂ©ration nous a permis de gagner Ă©normĂ©ment en flexibilitĂ©.
Conception de lâAPI REST avec Nest.JS
Nest est un framework Node.js qui permet de crĂ©er facilement des applications serveur Ă©volutives. Personnellement, je suis une dĂ©veloppeuse PHP, mais jâai choisi Nest plutĂŽt que PHP car lâĂ©quipe avec laquelle jâallais travailler Ă©tait plus familiĂšre de JavaScript. Lorsque je choisis une technologie, je cherche dâabord celle qui sera la plus simple dâutilisation pour les personnes qui seront chargĂ©es de travailler avec. ET nous sommes trĂšs heureuxâeuses dâavoir optĂ© pour ce framework ! GrĂące Ă lui, la crĂ©ation de lâAPI a Ă©tĂ© une vraie partie de plaisir.
Nest est divisĂ© en modules. Chaque module dispose de sa propre configuration mais aussi de ses propres contrĂŽleurs et services / fournisseurs. Dans le cadre de notre projet, nous avons dĂ©cidĂ© de crĂ©er un module pour chaque intĂ©gration, câest-Ă -dire un module Vontobel, un module MigrosBank et un module Cap Rechtsschutz. Nous avons Ă©galement ajoutĂ© certains autres modules dont nous avions besoin, tels que « Auth », « Mail », « Ghost », « Customer »...
Voici un contrÎleur entier que nous avons construit dans Nest pour créer un nouveau membre Ghost:
import { Controller, Post, Body, Get } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { GhostService } from './ghost.service';
@Controller('ghost')
@ApiTags('ghost')
export class GhostController {
constructor(private readonly ghostService: GhostService) {}
@Post('new')
async newMember(@Body() body): Promise<any> {
return this.ghostService.getGhostMemberUuidFromEmailCreateNewMemberIfNotExists(
body.firstname,
body.email,
);
}
}
Dans Nest, on utilise de nombreuses annotations qui facilitent la programmation. Ă noter lâutilisation de @Controller, qui est un contrĂŽleur @ApiTags, pour la documentation Open API, et de @Post pour le routage !
Lâinjection de code fonctionne grĂące Ă la configuration dans le module :
import { Module } from '@nestjs/common';
import { HttpModule } from '@nestjs/axios';
import { GhostController } from './ghost.controller';
import { GhostService } from './ghost.service';
@Module({
imports: [HttpModule],
controllers: [GhostController],
providers: [GhostService],
})
export class GhostModule {}
On remarquera ici que nous avons le « GhostService » en tant que fournisseur. Câest un service que nous avons crĂ©Ă© nous-mĂȘmes. Le Ghost Service contient des mĂ©thodes pour communiquer avec Ghost. Nous nous en servons pour connecter les membres Ghost aux membres de lâAPI pour nos intĂ©grations, et pour ajouter des membres Ă Friendly Automatic dĂšs leur inscription.
TypeScript est un langage de programmation entiĂšrement typĂ© qui permet en outre une superbe documentation avec Open API grĂące Ă lâutilisation dâobjets pour les rĂ©ponses API. Dans les objets, il suffit dâannoter les propriĂ©tĂ©s quâOpen API doit faire figurer dans la documentation :
@ApiProperty({
required: true,
description:
'The id that the frontend calling the ellexx api is using to identify their user, is usually a unique identifier',
example: 'sdfsd-23432-sfdfsd-2323',
})
public frontendId: string;
Setting up open api this way takes little effort but gives an invaluable documentation for API consumers.
Infrastructure
Pour lâhĂ©bergement, nous voulions une solution suisse et avons dĂ©cidĂ© dâutiliser Managed Kubernetes dâexoscale. Nous utilisons aussi Longhorn pour MySQL. Le recours Ă Kubernetes pour notre projet est rĂ©solument exagĂ©rĂ© mais cela fonctionne Ă la perfection. Nous utilisons Gitlab pour hĂ©berger notre code et Gitlab CI pour automatiser notre workflow. LâentrĂ©e dâun code gĂ©nĂšre la crĂ©ation et le dĂ©ploiement dâune image, pour le staging dâabord, puis pour la production. Notre solution Kubernetes prĂ©sente lâavantage dâĂȘtre Ă©volutive. CEPENDANT, Ghost ne lâest pas. Pour un site Ghost Ă trafic Ă©levĂ©, il faut rĂ©soudre le problĂšme en utilisant le cache http. Nous avons mis au point un cache Varnish tout simple, juste au cas oĂč. LâAPI en revanche est extensible. En raison de la nature dynamique des endpoints, nous nâavons pas vraiment pu tirer profit dâun cache ici.
Post Mortem
Ghost, Nest, Friendly Analytics, Gitlab, Gitlab CI, Kubernetes, MySQL avec Longhorn... avec le recul, changerions-nous quelque chose ? Non, pas vraiment ! Nous sommes rĂ©ellement satisfaitâeâs de notre configuration. La seule chose que nous aurions Ă©ventuellement pu faire autrement, câest dâutiliser Ghost en tant que headless CMS. Mais au bout du compte, tout a bien fonctionnĂ© et nous sommes tousâtes trĂšs satisfaitâeâs et fiersâĂšres du travail accompli.