Advanced Guides
Mise à niveau vers Parse Server 3.1 avec async/await
25 min
plus de puissance pour votre application avec parse server 3 1 introduction la communauté parse a récemment publié la version 3 1 de parse server https //docs parseplatform org/parse server/guide/ cette mise à jour a nettoyé la syntaxe du cloud code elle est beaucoup plus propice à l'utilisation des constructions async et await de l'es6 de plus, certaines particularités associées à l'utilisation de parse ont été supprimées, par exemple, les fonctions cloud retournent simplement une promesse plutôt que d'utiliser les erreur erreur ou succès succès messages sur l'objet response vous pouvez facilement mettre à jour vos applications sur back4app depuis votre tableau de bord ce guide montrera comment mettre à jour votre code pour tirer parti des nouvelles fonctionnalités de 3 1 pour suivre ce guide, vous êtes invités à jeter un œil au projet exemple fourni ceci est un tutoriel invité écrit par john considine https //github com/considine , développeur principal chez k optional https //koptional com/ objectifs mettre à jour votre parse server back4app vers 3 1 et migrer votre cloud code en conséquence prérequis pour compléter ce tutoriel, vous avez besoin de ° une application back4app existante utilisant parse server 2 x ° suivez le tutoriel créer une nouvelle application pour apprendre à créer une application sur back4app résumé des changements les changements les plus notables sont les suivants 1\ le code cloud fonctionne avec parse sdk 2 x auparavant, le code cloud fonctionnait avec parse sdk 1 x avec parse server 3 1, il fonctionne avec parse sdk 2 x regardez les versions de parse sdk pour mieux comprendre ce que cela implique cette mise à jour majeure concerne principalement des corrections de bogues elle ajoute également des méthodes de requête containedby et includeall , ainsi que la possibilité de récupérer un objet avec des inclusions 2 mise à jour agrégée depuis parse 2 7 1, vous pouvez utiliser la méthode agrégée sur une requête cela vous permet de tirer un peu plus parti de la base de données sous jacente maintenant, la syntaxe pour la méthode agrégée sur parse query parse query a été mise à jour vous pouvez exécuter une requête en utilisant deux étapes l'étape match match et l'étape group group auparavant, vous n'aviez pas besoin de la clé pipeline dans l'objet pipeline en raison de l'api sous jacente, vous devez maintenant inclure explicitement la clé pipeline la valeur doit être un tableau d'une ou deux étapes, comprenant groupe groupe et correspondre correspondre regardez documentation officielle de parse pour des exemples plus spécifiques 3 optimisations sous le capot certaines optimisations sous le capot ont été effectuées par exemple, un parse livequery récupérera les autorisations de niveau de classe (clp) avec les données pour éviter un double accès à la base de données 4\ email de réinitialisation parse lors de la demande d'un e mail de réinitialisation de mot de passe, le serveur renverra un succès même si cet e mail n'est pas enregistré de plus, les jetons de réinitialisation de mot de passe expirent lorsque l'e mail d'un utilisateur est réinitialisé 5\ mise à jour des déclencheurs cloud avec cette version, vous pouvez partager des données entre les beforesave et aftersave déclencheurs sur le même objet par exemple 1 parse cloud beforesave('comment', async request => { 2 request context = { 3 foo 'bar' 4 }; 5 }); 6 7 parse cloud aftersave('comment', async request => { 8 console log(request context foo); //bar 9 }); vous pouvez en savoir plus sur les changements dans parse server dans le changelog officiel de parse 3 1 en cliquant ici 6\ amélioration de livequery le client parse livequery vous permet de vous abonner à des requêtes et de recevoir des mises à jour du serveur au fur et à mesure qu'elles arrivent les requêtes traditionnelles sont exécutées une fois par le client, donc cela est très utile pour des cas comme la messagerie, etc avec back4app, vous pouvez également profiter de cette technologie https //www back4app com/docs/platform/parse server live query example avec la sortie de 3 x, la communauté parse a amélioré le système pour livequery acls https //docs parseplatform org/js/guide/#security for other objects vous pouvez maintenant passer un jeton de session à la méthode subscribe d'une requête en direct, et le serveur parse ne renverra que les résultats auxquels cet utilisateur a accès par exemple, un utilisateur peut avoir un accès en lecture/écriture à certains 'messages', mais pas à tous 1 let query = new parse query('message'); 2 // you can get session token with 3 // parse user current() getsessiontoken() when logged in 4 let subscription = client subscribe(query, sessiontoken); le code ci dessus s'abonnera automatiquement à tous les messages auxquels l'utilisateur a accès, vous déchargeant de la responsabilité de requêter des messages spécifiques la partie principale des changements concerne la manière dont le cloud code est géré pour cela, consultez le guide de migration ci dessous 1 aligner les fondamentaux techniques nous commencerons par un exemple de projet cloud utilisant la version 2 x de cette façon, nous pouvons naviguer à travers les changements de syntaxe appropriés vous pouvez voir le dépôt pour cet exemple de projet si vous êtes familier avec async et await, vous pouvez sauter cette section l'évolution du code asynchrone en javascript ressemble à ceci fonctions de rappel promesses async / await toute application javascript moderne utilisera probablement les trois les fonctions de rappel impliquent de passer une fonction comme argument à une autre fonction cette seconde fonction peut exécuter la première à un moment donné 1 // callbacks 2 // executes callback function after waiting 100 milliseconds 3 settimeout(function() { 4 alert('my callback function'); 5 }, 100); les rappels sont essentiels mais peuvent être encombrants lorsqu'il s'agit d'enchaîner beaucoup d'entre eux en particulier, imbriquer plusieurs couches peut être difficile à lire, et la gestion des erreurs s'avère difficile c'est pourquoi dans es2015, la promesse a été introduite 1 // promises 2 // executes several promises in a row with no significant nesting 3 const mypromise = new promise(function(resolve, reject) { 4 settimeout(function() { 5 if (math random() < 0 2) reject(new error('random failure!')); 6 resolve('finished'); 7 }, 100); 8 }); 9 10 // executes this promise 4 times and catches errors involved 11 mypromise 12 then(() => mypromise) 13 then(() => mypromise) 14 then(() => mypromise) 15 then(() => mypromise) 16 catch(e => console log(e)); les promesses améliorent la lisibilité de la programmation asynchrone elles rendent également les pipelines plus explicites mais des avancées encore plus importantes ont été réalisées dans es2017 avec les constructions async / await votre code peut maintenant attendre les résultats d'une promesse sans dépendre des blocs then / catch (qui peuvent également devenir difficiles à lire) 1 // using the definition of mypromise from the above code 2 async function foo() { 3 try { 4 let result = await mypromise; 5 result = await mypromise; 6 result = await mypromise; 7 } catch (e) { 8 console log(e); 9 } 10 } peut être que pour un exemple très simple, cela ne semble pas plus élégant que de simples promesses mais attendre les résultats d'une fonction asynchrone est souvent précisément ce que nous voulons faire par conséquent, cela optimise vraiment la lisibilité de notre code support pour async/await comme mentionné précédemment, async/await a été inclus dans la spécification ecmascript 2017 (es8) pour le code serveur, la version n'est guère un problème puisque vous pouvez mettre à jour vers la version de node js qui prend en charge ces fonctionnalités soyez assuré que l'environnement de back4app prend en charge les versions stables récentes pour le code navigateur, des transpileurs comme babel produiront un es2016 compatible avec le code qui utilise async / await et fonctionne dans les navigateurs modernes 2 penser différemment à votre code le principal changement avec le cloud code concerne ce que fait le développeur par rapport à ce que fait la bibliothèque auparavant, vous deviez gérer explicitement la réponse étant donné que la plupart des cloud code s'exécuteront de manière asynchrone effectuant des requêtes et des écritures dans la base de données il est plus logique de retourner une promesse, réduisant ainsi le code boilerplate l'intuition derrière les fonctions cloud est qu'il y a un minimum de configuration et de mise en place impliqués dans l'écriture de code côté serveur cette version incarne cette idée ; gardez cela à l'esprit lorsque vous refactorisez et créez de nouvelles fonctions pour montrer comment les fonctions cloud code fonctionnent dans parse server 3 1, nous avons réécrit un exemple fonctionnel de cloud code d'une version de parse server avant la migration vous pouvez trouver ce code en cliquant ici la même fonction cloud code est écrite dans parse 3 1 comme montré ci dessous 1 // cloud code before migration 2 // full code found in link above 3 const post = 'post'; 4 parse cloud define('posts\ get', function(request, response) { 5 // needs a post id 6 return new parse query(post) 7 get(request params id, { usemasterkey true }) 8 then(post => { 9 response success(post); 10 }) 11 catch(e => { 12 response error({ message e message }); 13 }); 14 }); 3 ajout de tous les marqueurs async toute fonction qui utilise await doit être déclarée avec le modificateur async ce simple refactoring attachera async à toutes les cloud functions il les remplacera également par des fonctions fléchées car elles sont plus succinctes dans ce cas (et c'est ce que le guide officiel parse mis à jour utilise) 1 // snippet of step 2 code refactoring see full code 2 // here in the link at the top of this step 3 const post = 'post'; 4 const comment = 'comment'; 5 6 parse cloud define('posts\ get', async (request) => { 7 // needs a post id 8 return new parse query(post) 9 get(request params id, { usemasterkey true }); 10 } votre code ressemblera à cela après ce refactoring rien de fou jusqu'à présent dans la prochaine étape, nous tirerons pleinement parti de ce changement 4 suppression des références à la réponse, utiliser await votre code ressemblera à cela après ce refactoring cette étape est un peu plus délicate nous devons supprimer toutes les références à la variable ‘response’, en retournant une promesse à la place dans le cas de plusieurs fonctions de requête/enregistrement, attendez la réponse consultez la méthode de création de commentaire pour voir comment cela se fait 1 // snippet of step 3 code refactoring see full code 2 // here in the link at the top of this step 3 parse cloud define('comment\ create', async request => { 4 // post should have text and should have a user and a post id 5 if (!request user) { 6 throw new error('unauthenticated!'); 7 } 8 9 if (!request params text) { 10 throw new error('a comment needs text!'); 11 } 12 if (!request params post id) { 13 throw new error('a comment needs a post!'); 14 } 15 16 // get the post 17 18 const post = await new parse query(post) get(request params post id, { 19 usemasterkey true 20 }); 21 return new parse object(comment, { 22 text request params text, 23 user request user, 24 post post 25 }) save(null, { usemasterkey true }); 26 }); notez que maintenant, une erreur javascript est lancée au lieu d’appeler response error parse s’occupera de transformer cela en une réponse pour nous supprimer un ‘post’ ou un ‘commentaire’ implique d’abord de récupérer l’objet, puis de le détruire en utilisant ‘await’, la méthode de destruction peut accéder à l’objet enregistré en dehors d’un bloc cela complète tous les refactorings nécessaires pour la migration c'est à dire que si vous arrivez jusqu'à cette étape, félicitations ! votre code fonctionnera sur back4app parse 3 1 ! 5 astuces avancées (optionnel) les changements suivants sont optionnels mais peuvent réduire considérablement votre code je trouve qu'ils réduisent le code standard vous avez probablement remarqué beaucoup de vérifications manuelles pour les paramètres ou l'utilisateur authentifié celles ci garantissent qu'aucun comportement étrange ne se produit par exemple, nous avons décidé que notre objet 'post' a besoin de texte, donc si aucun paramètre 'texte' n'est passé, l'objet sera enregistré sans une façon d'éviter cela est de vérifier que le texte a été passé mais les vérifications manuelles peuvent être longues et peu élégantes dans cette section, nous profitons de la déstructuration d'objet pour compléter implicitement ces vérifications vous devriez consulter la documentation ci dessus si vous ne savez pas ce qu'est la déstructuration mais en résumé, cela vous permet de transformer une propriété d'objet en une variable avec une syntaxe très concise 1 // this 2 var obj = { 3 hi true, 4 bye false 5 }; 6 var hi = obj hi; 7 var bye = obj bye; 8 9 // is equivalent to this 10 var obj = { 11 hi true, 12 bye false 13 }; 14 var { hi, bye } = obj; 15 16 console log(hi); 17 // true 18 console log(bye); 19 // false la déstructuration est moins verbeuse que l'assignation manuelle elle vous permet également de déclarer des variables de paramètres à la volée, ce qui est agréable 1 parse cloud define('posts\ get', async ({ params { id } }) => { 2 // id is declared 3 }); lorsqu'il est combiné avec une notation es2015 pour l'initialisation d'objet nous pouvons optimiser nos vérifications de paramètres nous pouvons faire cela 1 // iterates through object's keys makes sure, for each key, the value is set 2 const assertparams = parameter obj => { 3 for (var key of object keys(parameter obj)) { 4 if (typeof parameter obj\[key] === 'undefined') 5 throw new error(`missing parameter ${key}`); 6 } 7 }; 8 9 var obj = { 10 hi true, 11 bye false 12 }; 13 var { hi, undef, bye } = obj; // undef will be undefined 14 var check 1 = { hi, bye }; 15 var check 2 = { hi, undef }; 16 17 // check = { hi true, no undefined } 18 assertparams(check 1); // passes 19 assertparams(check 2); // throws error donc, pour notre code parse, nous pouvons faire ceci 1 // snippet of advanced code refactoring see full code 2 // here in the link at the top of this step 3 parse cloud define('posts\ delete', async ({ user, params { id } }) => { 4 // makes sure user is authenticated, and id parameter is passed 5 assertparams({ user, id }); 6 const post = await new parse query(post) get(id, { 7 usemasterkey true 8 }); 9 return post destroy({ usemasterkey true }); 10 }); si cela vous semble décourageant, ne vous inquiétez pas le code complet de l'exemple pourrait aider en résumé, ‘assertparams’ est une fonction utilitaire qui lance une erreur si une valeur est indéfinie nous pouvons vérifier les paramètres en un seul mouvement en combinant la déstructuration d'objet et l'initialisation d'objet es2015 cela supprime huit ou neuf vérifications manuelles qui commencent à devenir inesthétiques après un certain temps 6 mise à niveau sur back4app une fois que vous avez migré votre code, vous devez faire deux autres choses pour le faire fonctionner sur back4app mettez à jour la version de votre serveur back4app téléchargez votre nouveau code cloud j'ai brièvement mentionné la première étape auparavant tout ce que vous avez à faire est de vous connecter à back4app et d'aller sur le tableau de bord de votre application de là, sélectionnez simplement « paramètres du serveur » à gauche, suivi du bouton « paramètres » sur la carte « gérer le serveur parse » vous pouvez ensuite sélectionner le bouton radio du serveur parse 3 1 1 et cliquer sur « enregistrer » dernier point mais non des moindres, vous pouvez télécharger votre code via le back4app cli https //blog back4app com/2017/01/20/cli parse server/ , ou votre tableau de bord en utilisant le téléchargement manuel consultez ce guide https //www back4app com/docs/android/parse cloud code si vous avez besoin de plus d'informations sur cette étape remarques sur le lancement d'une nouvelle version si votre code est complexe, il pourrait être judicieux de faire quelques tests avant de réaliser ces deux étapes back4app a quelques guides sur la façon de faire cela ici et ici enfin, il est important de noter que ces changements sont breaking utiliser le code que nous avons écrit sur un serveur parse 2 x échouera, et utiliser du code 2 x sur un serveur 3 1 échouera également par conséquent, vous devez vous assurer de mettre à jour votre version de parse back4app dès que vous téléchargez votre cloud code mis à jour si vous avez de nombreux utilisateurs et que vous êtes préoccupé par le téléchargement du code et la mise à niveau de la version étant légèrement désynchronisés, vous pouvez faire quelque chose comme ça 1 const serverversion = 2 parse coremanager get('version') === 'js1 11 1' ? 'old' 'new'; 3 4 if (serverversion === 'new') { 5 parse cloud define('posts\ get', async ({ params { id } }) => { 6 assertparams({ id }); 7 // needs a post id 8 return new parse query(post) get(id, { 9 usemasterkey true 10 }); 11 }); 12 } else if (serverversion === 'old') { 13 // old definition here 14 } ce code détermine dynamiquement la version et définit les fonctions cloud en fonction de cela après avoir téléchargé cela, vous changeriez pour 3 1, puis vous pourriez re télécharger le code avec la partie ancienne supprimée inclure la vérification au début garantit qu'il n'y a pas de moment où votre code va planter étant donné que vous pouvez mettre à niveau et télécharger en quelques secondes, il n'est généralement pas nécessaire conclusion dans ce guide, nous avons simplement démontré comment migrer votre cloud code vers la version parse 3 1 n'oubliez pas de mettre à jour votre version back4app à 3 1 après avoir effectué ces changements de plus, il est également important de noter que ce guide a démontré une syntaxe améliorée que parse 3 1 utilise nos refactorisations ont réduit la base de code d'environ 160 lignes à environ 90 et l'ont rendue beaucoup plus lisible pour les applications réelles, cela rapportera des dividendes