Advanced Guides
Parse Server 3.1 アップグレードガイド: Cloud Codeの最適化
19 分
parse server 3 1でアプリにさらなる力を はじめに parseコミュニティは最近、 parse serverの3 1 https //docs parseplatform org/parse server/guide/ をリリースしました。このアップデートでは、cloud codeの構文が整理され、es6のasyncおよびawait構文を活用しやすくなりました。 さらに、parseを使用する際のいくつかの特異性が削除されました。たとえば、cloud関数は、responseオブジェクトの エラー エラー または 成功 成功 メッセージを使用するのではなく、単にpromiseを返します。 ダッシュボード上でback4appのアプリを簡単にアップグレードできます。このガイドでは、3 1の新機能を活用するためにコードをアップグレードする方法を示します。 このガイドに従うには、提供された サンプルプロジェクト を確認することをお勧めします。 これは、 ジョン・コンシダイン https //github com/considine によって書かれたゲストチュートリアルです。彼は k optional https //koptional com/ のリード開発者です。 目標 back4appのparse serverを3 1にアップデートし、それに応じてcloud codeを移行すること。 前提条件 このチュートリアルを完了するには、以下が必要です: ° parse server 2 xを使用している既存のback4appアプリケーション ° back4appでアプリを作成する方法を学ぶには、 新しいアプリ作成チュートリアル を参照してください。 変更の概要 最も注目すべき変更は以下の通りです。 1\ cloud codeはparse sdk 2 xで実行されます。 以前は、cloud codeはparse sdk 1 xで実行されていました。parse server 3 1では、parse sdk 2 xで実行されます。 次を見てください parse sdkのリリース これが何を意味するのかをよりよく理解するために。このメジャーバージョンのアップは主にバグ修正を含みます。また、 containedby と includeall のクエリメソッドが追加され、インクルードを使用してオブジェクトを取得する機能も追加されました。 2 集約更新 parse 2 7 1以降、クエリで aggregate メソッドを使用できます。これにより、基盤となるデータベースをもう少し活用できます。現在、 aggregateメソッド の構文が parse query parse query で更新されました。 クエリを実行するには、2つのステージを使用できます match match と group group ステージです。 以前は、パイプラインオブジェクトに pipeline キーは必要ありませんでした。基盤となる api のため、今は明示的に pipeline キーを含める必要があります。値は、1 つまたは 2 つのステージの配列である必要があります。 group group と match match 詳細な例については、 parse 公式ドキュメント をご覧ください。 3 内部最適化 いくつかの内部最適化が行われました。例えば、 parse livequery は、データと共にクラスレベルの権限 (clp) を取得し、データベースへの二重アクセスを防ぎます。 4\ parse リセットメール パスワードリセットメールをリクエストすると、サーバーはそのメールが保存されていなくても成功を返します。さらに、ユーザーのメールがリセットされると、パスワードリセットトークンは期限切れになります。 5\ クラウドトリガーの更新 このリリースでは、同じオブジェクトの beforesave と aftersave トリガー間でデータを共有できます。例えば 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 }); parse serverの変更については、公式のparse 3 1 changelogをクリックして詳しく見ることができます こちら 6\ livequeryの改善 parse livequeryクライアントを使用すると、クエリにサブスクライブし、サーバーからの更新を受け取ることができます。従来のクエリはクライアントによって一度だけ実行されるため、メッセージングなどのケースに非常に役立ちます。 back4appを使用すると、あなたはこの技術を 活用することができます https //www back4app com/docs/platform/parse server live query example 。 3 xのリリースにより、parseコミュニティはlivequeryのシステムを改善しました acls https //docs parseplatform org/js/guide/#security for other objects 。 現在、ライブクエリのsubscribeメソッドにセッショントークンを渡すことができ、parse serverはこのユーザーがアクセスできる結果のみを返すように管理します。例えば、ユーザーは特定の「メッセージ」に対して読み書きアクセスを持っているかもしれませんが、すべてのメッセージにはアクセスできないかもしれません。 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); 上記のコードは、ユーザーがアクセスできるすべてのメッセージに自動的にサブスクライブし、特定のメッセージをクエリする責任を軽減します。 変更の主な部分は、cloud codeの取り扱いに関するものです。これについては、以下の移行ガイドを参照してください。 1 技術的基礎の整合性 2 xリリースを使用した例のクラウドプロジェクトから始めます。これにより、適切な構文の変更をナビゲートできます。 リポジトリ をこの例のプロジェクトとして見ることができます。 asyncとawaitに慣れている場合は、このセクションをスキップできます。 javascriptにおける非同期コードの進化は、次のようになります コールバック関数 プロミス async / await 現代のjavascriptアプリケーションは、すべての3つを使用する可能性が高いです。コールバック関数は、関数を別の関数への引数として渡すことを含みます。この2番目の関数は、ある時点で最初の関数を実行できます。 1 // callbacks 2 // executes callback function after waiting 100 milliseconds 3 settimeout(function() { 4 alert('my callback function'); 5 }, 100); コールバックは不可欠ですが、多くのコールバックをチェーンする際には扱いにくくなることがあります。特に、いくつかのレイヤーをネストすると読みづらくなり、エラーハンドリングが難しくなります。したがって、es2015ではpromiseが導入されました。 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)); プロミスは非同期プログラミングの可読性を向上させます。また、パイプラインをより明示的にします。しかし、さらに大きな進歩がありました。 es2017 では、async / await構文が導入されました。これにより、コードはthen / catchブロックに依存せずにpromiseの結果を待つことができます(これも読みづらくなることがあります)。 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 } 非常にシンプルな例では、これが単純なプロミスよりも優雅に見えないかもしれません。しかし、非同期関数の結果を待つことは、しばしば私たちがやりたいことです。したがって、これは私たちのコードの可読性を本当に最適化します。 async/awaitのサポート 前述のように、async/awaitは ecmascript 2017仕様 (es8) に含まれています。サーバーコードの場合、バージョン管理はほとんど問題になりません。なぜなら、これらの機能をサポートする node jsのバージョンに更新できるからです 。安心してください、back4appの環境は最近の安定版をサポートしています。ブラウザコードの場合、 babel のようなトランスパイラが、async / awaitを使用するコードと互換性のあるes2016を生成し、最新のブラウザで動作します。 2 コードを異なる視点で考える cloud codeの主な変更点は、開発者が行うこととライブラリが行うことの違いです。以前は、レスポンスを明示的に管理していました。ほとんどのcloud codeは非同期で実行されるため データベースのクエリや書き込みを行うため promiseを返す方が理にかなっており、ボイラープレートコードを減らすことができます。 cloud関数の直感は、サーバーサイドコードを書く際に最小限のセットアップと構成が必要であるということです。このリリースはそのアイデアを具現化しています。リファクタリングや新しい関数を作成する際には、この点を念頭に置いてください。 parse server 3 1でcloud code関数がどのように機能するかを示すために、移行前のparse serverのバージョンから機能的なcloud codeサンプルを再作成しました。このコードは、 こちら をクリックすることで見つけることができます。同じcloud code関数は、以下のようにparse 3 1で記述されています。 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 すべての非同期マーカーを追加する awaitを使用する関数は、async修飾子で宣言する必要があります。このシンプルなリファクタリングは、すべてのcloud functionsにasyncを付加します。また、これらを アロー関数 に置き換えます。これはこの場合、より簡潔であり(更新された公式parseガイドが使用しているものです)。 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 } あなたのコードは、 これ に見えるようになります。このリファクタリングの後、 これまでのところ、特に驚くべきことはありません。次のステップでは、この変更に対してお金の価値を得ることができます。 4 responseへの参照を削除し、awaitを使用する あなたのコードは次のようになります これ このリファクタリングの後に このステップは少し難しいです。私たちは ‘response’変数へのすべての参照を削除し、代わりにpromiseを返す 複数のクエリ/保存関数の場合、応答を待つ コメント作成メソッドを確認して、これがどのように行われるかを見てください 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 }); 注意してください 今やjavascriptエラーがスローされ、response errorを呼び出す代わりになります。parseはこれを私たちのために応答に変換する処理を行います。 ‘post’または‘comment’を削除するには、まずオブジェクトを取得し、その後それを破壊します。‘await’を使用することで、破壊メソッドはブロックの外で保存されたオブジェクトにアクセスできます。 これで移行に必要なすべてのリファクタリングが完了しました。つまり、このステップまで進めば、おめでとうございます!あなたのコードはback4app parse 3 1で動作します! 5 高度なトリック(オプション) 以下の変更はオプションですが、コードを大幅に短縮することができます。私はこれらがボイラープレートを減らすと感じています。 おそらく、パラメータや認証されたユーザーのための多くの手動チェックに気づいたでしょう。これらは奇妙な動作が発生しないようにします。例えば、私たちは「post」オブジェクトにテキストが必要だと決定したので、「text」パラメータが渡されない場合、オブジェクトはそれなしで保存されます。これを防ぐ一つの方法は、テキストが渡されたことを確認することです。 しかし、手動チェックは時間がかかり、優雅ではありません。このセクションでは、 オブジェクトの分割代入 を利用して、これらのチェックを暗黙的に完了させます。 分割代入が何か分からない場合は、上記のドキュメントを参照してください。しかし簡単に言うと、オブジェクトのプロパティを非常に簡潔な構文で変数に変換することができます。 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 分割代入は手動の代入よりも冗長ではありません。また、パラメータ変数をその場で宣言できるため、便利です 1 parse cloud define('posts\ get', async ({ params { id } }) => { 2 // id is declared 3 }); es2015の表記と組み合わせると、 オブジェクト初期化 のために、パラメータチェックを最適化できます。 これを行うことができます 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 私たちのparseコードについては、次のようにできます 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 }); これが daunting であれば、心配しないでください。 完全なコード の例が役立つかもしれません。 要するに、‘assertparams’は、値が未定義の場合にエラーをスローするためのユーティリティ関数です。オブジェクトの分割代入とes2015オブジェクト初期化を組み合わせることで、パラメータを一度にチェックできます。 これにより、しばらくすると見苦しくなり始める8または9の手動チェックが削除されます。 6 back4appでのアップグレード コードを移行したら、back4appで実行するためにさらに2つのことを行う必要があります。 back4appサーバーのバージョンをアップグレードする 新しいクラウドコードをアップロードする。 最初のステップについては以前に簡単に触れました。必要なことは、back4appにログインし、アプリのダッシュボードに移動することです。そこから、左側の「サーバー設定」を選択し、「parseサーバーの管理」カードの「設定」ボタンをクリックします。次に、parse server 3 1 1のラジオボタンを選択し、「保存」をクリックします。 最後に、コードをアップロードする方法として、 back4app cli https //blog back4app com/2017/01/20/cli parse server/ を使用するか、ダッシュボードを使って手動でアップロードすることができます。このステップについての詳細が必要な場合は、 このガイド https //www back4app com/docs/android/parse cloud code を参照してください。 新しいバージョンのリリースに関する注意事項 コードが複雑な場合は、これらの2つのステップを行う前にテストを実行することをお勧めします。back4appには、これを行う方法に関するガイドがあります。 こちら と こちら を参照してください。 最後に、これらの変更が breaking であることに注意することが重要です。2 x parse serverで書いたコードは失敗し、3 1サーバーで2 xコードを使用すると失敗します。したがって、アップグレードされたcloud codeをアップロードする際には、back4appのparseバージョンを必ずアップグレードする必要があります。多くのユーザーがいて、コードのアップロードとバージョンのアップグレードがわずかに同期していないことを心配している場合は、次のようなことができます。 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 } このコードは、バージョンを動的に判断し、それに基づいてcloud functionsを定義します。これをアップロードした後、3 1に変更し、古い部分を削除したコードを再アップロードできます。最初にチェックを含めることで、コードがクラッシュするポイントがないことを保証します。数秒以内にアップグレードとアップロードができるため、通常は必要ありません。 結論 このガイドでは、cloud codeをparse 3 1リリースに移行する方法を簡単に示しました。これらの変更を行った後は、back4appのバージョンを3 1にアップグレードすることを忘れないでください。 また重要なことに、このガイドではparse 3 1が活用する改善された構文を示しました。私たちのリファクタリングにより、コードベースは約160行から約90行に削減され、はるかに読みやすくなりました。実際のアプリケーションにとって、これは大きな利益をもたらすでしょう。