Introduction
Ce document présente le fonctionnement des API « data-create » et « data-mutate » de DAZZM, conçues pour interagir avec les données dans la base de données DAZZM.
Contrairement à une approche REST classique, qui permet de modifier une ressource en fournissant une nouvelle version complète de celle-ci, l’API DAZZM repose sur des commandes nommées spécifiques. Par exemple, un aggregate peut offrir des commandes telles que « create », « updateIdentification », « updateAddress », « deactivate » et « delete ». Cette architecture, inspirée du Domain Driven Design, de CQRS et de l'Event Sourcing, favorise une gestion granulaire des opérations, permettant de modifier des aspects ciblés d’une ressource. Chaque commande génère un événement de domaine parlant, assurant une traçabilité détaillée des modifications et un suivi précis des actions dans le système.
Cette approche renforce également l’intégrité du système en imposant des commandes et des paramètres strictement définis, réduisant ainsi les erreurs et les incohérences dans les données. Chaque aggregate peut donc être perçu comme un microservice disposant de ses propres API spécifiques.
Pour modifier un champ particulier, il est nécessaire d’identifier la commande correspondant à ce champ, puis de fournir les paramètres requis par cette commande.
Note sur les exemples
Les exemples dans ce document utilisent le modèle de « User », un aggregate présent dans toutes les applications DAZZM.
Création d’un aggregate avec « data-create »
Pour créer un aggregate, on doit invoquer le service « data-create » en passant en paramètre le nom exact de la commande de création, l’identifiant du type de la donnée, ainsi que les paramètres que cette commande demande.
Requêtes et réponses
Structure d’une requête avec fetch
Voici un exemple pour créer un utilisateur avec la commande nommée « create »:
fetch('https://votre_environement.api.octopus-esm.com/prod/data-create', {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'api-key': 'votre_token'
},
body: JSON.stringify({
"typeId":"776e839a-6e1c-42b9-8efd-8b6db21b4797",
"commandName":"create",
"commandArgs":{
"firstName":"Michel",
"lastName":"Roberge",
"email":"mr@ici.com",
"language":"fr"}
})
})
.then(response => response.json())
.then(body => console.log(body))
.catch(error => console.error(error));
Notez le mot « create » à deux endroits. Le premier est « data-create » dans l’URL. Celui-ci est statique et ne change jamais, c’est le nom du endpoint de création. Le second est dans le body de la requête ("commandName":"create") et celui-là peut changer, par exemple dans une application dont le modèle de données est en français, on pourrait indiquer « créer ». Chaque application à un modèle de données et des noms de commandes différents.
Structure de la réponse du serveur
Remarquez que la valeur de retour est au format JSON et contient toujours deux éléments. Le premier, nommé « event » contient la transaction elle-même, alors que « data » contient la donnée nouvellement crée, incluant les valeurs par défaut qui ont été appliquées par le système. On voit dans cet exemple que isActive a été initialisé à « true » par la commande « create ».
{
"event": {
"type": "USER_CREATED",
"aggregateTypename": "User",
"data": {
"firstName": "Michel",
"lastName": "Roberge",
"email": "mr@ici.com",
"isActive": true,
"language": "fr",
"id": "88f1525c-d105-47b9-a5e4-5e54ac3562b4"
},
"aggregateId": "88f1525c-d105-47b9-a5e4-5e54ac3562b4",
"aggregateVersion": 1,
"created": 1730757148637,
"requestId": "ad22d17c-f92e-447d-912b-ad9eb6b28e01",
"dbId": "999999999",
"appId": "999999999",
"appVersion": "dev",
"userId": "user"
},
"data": {
"_typename": "User",
"_version": 1,
"firstName": "Michel",
"lastName": "Roberge",
"email": "mr@ici.com",
"isActive": true,
"language": "fr",
"id": "88f1525c-d105-47b9-a5e4-5e54ac3562b4"
}
}
Modification d’un aggregate avec « data-mutate»
Pour modifier un aggregate existant, on doit invoquer le service « data-mutate » en passant en paramètre le nom exact de la commande de modification, l’identifiant de l’enregistrement à modifier, ainsi que les paramètre que cette commande demande.
Requêtes et réponses
Structure d’une requête avec fetch
Voici un exemple pour modifier un utilisateur avec la commande nommée « updateIdentification ».
fetch('https://votre_environement.api.octopus-esm.com/prod/data-mutate, {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'api-key': 'votre_token'
},
body: JSON.stringify({
"typeId":"776e839a-6e1c-42b9-8efd-8b6db21b4797",
"commandName":"updateIdentification",
"id": "88f1525c-d105-47b9-a5e4-5e54ac3562b4",
"commandArgs":{
"firstName":"Michel",
"lastName":"Roberge",
"email":"mr@ici.com"}
})
})
.then(response => response.json())
.then(body => console.log(body))
.catch(error => console.error(error));
Structure de la réponse du serveur
Remarquez que la valeur de retour est au format JSON et contient toujours deux éléments. Le premier, nommé « event » contient la transaction elle-même, alors que « data » contient la donnée modifiée.
{
"event": {
"type": "USER_IDENTIFICATION_UPDATED",
"data": {
"firstName": "Michel",
"lastName": "Dupuis",
"email": "mr@ici.com"
},
"aggregateId": "88f1525c-d105-47b9-a5e4-5e54ac3562b4",
"aggregateTypename": "User",
"aggregateVersion": 2,
"created": 1730757965432,
"requestId": "e1618d64-6c6b-4e27-8ef5-f18a57505191",
"previousData": {
"lastName": "Roberge"
},
"dbId": "99999999",
"appId": "99999999",
"appVersion": "dev",
"userId": "user"
},
"data": {
"isActive": true,
"_version": 2,
"lastName": "Dupuis",
"_typename": "User",
"email": "mr@ici.com",
"id": "88f1525c-d105-47b9-a5e4-5e54ac3562b4",
"firstName": "Michel",
"language": "fr"
}
}