Pour mettre en place les premières « vraies » interactions dans notre API Rest de pokémons, quoi de mieux que de commencer par l’ajout d’un nouveau pokémon, et ainsi agrandir la liste des pokémons disponibles ?
Le seul petit bémol, c’est que nous n’avons aucune idée de comment réaliser cela avec Express pour le moment…
Alors, reprenons les choses dans l’ordre. Nous devons construire un point de terminaison qui acceptera la requête HTTP suivante :
On va donc mettre en place ce nouveau point de terminaison dans le point d’entrée app.js :
//...
app.post('/api/pokemons', (req, res) => {
const id = 123
const pokemonCreated = { ...req.body, ...{id: id, created: new Date()}}
pokemons.push(pokemonCreated)
const message = `Le pokémon ${pokemonCreated.name} a bien été crée.`
res.json(success(message, pokemonCreated))
})
// ...
On va détailler ce code ensemble ligne par ligne, car il recèle une petite subtilité et certaines parties de la syntaxe ne sont pas évidentes non plus !
Voici donc les explications :
Et le tour est joué !
Oulà, tu t’emballes là ! C’est quoi cet identifiant « unique ». Et si on ajoute deux pokémons à la suite ? Ils auront le même identifiant !
Ah oui, c’est vrai qu’on est allé un peu vite en besogne.
En fait, on doit générer un identifiant unique, c’est-à-dire différent de tous les identifiants déjà existants. Pour cela, je vous propose une solution simple et fiable.
On va récupérer l’identifiant le plus grand parmi la liste existante et l’incrémenter de la valeur 1. Ainsi, on est sûr de récupérer un identifiant unique pour chaque nouveau pokémon que l’on ajoute dans notre API Rest.
Nous allons ajouter cette méthode de génération d’identifiant dans le fichier helper.js, car il s’agit d’une méthode « outil » :
exports.success = (message, data) => {
return { message, data }
}
exports.getUniqueId = (pokemons) => {
const pokemonsIds = pokemons.map(pokemon => pokemon.id)
const maxId = pokemonsIds.reduce((a,b) => Math.max(a, b))
const uniqueId = maxId + 1
return uniqueId
}
Dans ce code, on commence par transformer le tableau des pokémons en un tableau d’identifiant des pokémons, contenu dans la constante pokemonsIds. Cela est possible grâce à la méthode JavaScript map, qui fonctionne comme une boucle for, mais en retournant un nouveau tableau.
Ensuite, on calcule l’identifiant existant le plus grand parmi la liste des identifiants de pokémons. Ce prodige est possible grâce à la méthode JavaScript native reduce, qui permet de comparer les éléments deux à deux dans un tableau. Bref, retenez que cette méthode nous retourne la constante maxId, qui est ce qui nous intéresse principalement.
Pour finir proprement, il ne nous reste plus qu’à retourner l’identifiant unique du nouveau pokémon, en incrémentant la valeur de la constante précédente maxId de 1.
Il nous reste ensuite à utiliser cette nouvelle méthode outil pour générer un identifiant unique lors de l’ajout d’un nouveau pokémon, plutôt que d’écrire « 123 » en dur, dans le point d’entrée app.js :
// ...
const { success, getUniqueId } = require('./helper.js');
//...
app.post('/api/pokemons', (req, res) => {
const id = getUniqueId(pokemons)
const pokemonCreated = { ...req.body, ...{id: id, created: new Date()}};
pokemons.push(pokemonCreated)
const message = `Le pokémon ${pokemonCreated.name} a bien été crée.`
res.json(success(message, pokemonCreated))
})
// ...
Nous voilà désormais avec un point de terminaison permettant d’ajouter un nouveau pokémon… prêt à l’emploi !
Le léger problème que nous avons encore, c’est que nous avons aucune idée de comment tester ce point de terminaison. On ne peut pas utiliser notre navigateur pour effectuer des requêtes de type POST. Nous allons donc devoir trouver un autre moyen.
Mais rassurez-vous, on va bien trouver une solution. 😇
Idéalement, seul la base de données est responsable d’attribuer un identifiant unique. Pour le moment on le garantira à la main depuis notre API Rest, mais plus tard c’est bien MySQL qui s’en chargera.