インターネットカタログの例の開発でGraphQLをどのように使用したか

この記事では、GraphQLを実際に使用してオンラインカタログを作成した経験を共有します。 GraphQL + Apolloクライアント、Next JS(SSR)+ TypeScriptスタックを使用したときに見つかったこのクエリ言語の長所と短所について説明しましょう。



免責事項:「魔法の本質」と楽器の起源の歴史については詳しく説明していません(これについてはすでに多くのことが語られています)。すでにGraphQLに精通している方が、私たちの実践的な経験から恩恵を受けることを願っています。







最近、照明器具のインターネットカタログの作成に参加しました。広告ページを作成するには、サイト管理者がデザイナーを使用できます。必要なブロック(バナーやリストなど)を選択し、データを入力し、表示順序やその他の設定を定義します。同時に、アプリケーションは、ブロックタイプごとに事前にレイアウトされたコンポーネントをレンダリングしました。



オンラインカタログの各カテゴリには、さまざまな製品グループのカードが表示され、カードにカーソルを合わせると、添付されている製品のプロパティのリストが表示されました。



商品の特性をツリー構造で表示し、十分に高速な要求処理を提供する必要がありました。



リクエストに応じて、次の作業順序を選択しました。



  1. 特定のカテゴリのすべての製品グループ(通常は約50グループ)を要求します。
  2. 各グループの製品リストをリクエストしてください。
  3. 各製品のプロパティのリストをリクエストします。


GraphQLに基づいてアプリケーションを開発していたので、一部のデータがかなり複雑なネストされた構造を持つという事実に備えました。この構造の分岐はバックエンド開発にとって論理的でしたが、設計に従って、データを処理してコンポーネントに出力するために、いくつかの「追加の」ロジックを前面に書き込む必要がありました。



GraphQLコンストラクターの特性により、プロパティと一意の値を背面ではなく前面で収集し、特定の順序でレンダリングすることにしました。ただし、リクエストの処理は遅すぎました。最大20秒でした。もちろん、これは私たちには適していませんでした。



このため、各リクエストを小さなサブクエリに分割し、データを部分的にロードするようになりました。その結果、アプリケーションの速度が著しく向上しました。リクエストにかかる時間は2秒以内でした。リクエスト数は増えましたが、システムへの負荷が軽減され、未使用のデータをロードする必要がなくなりました。



次に、GraphQLの操作について直接詳しく説明しましょう。



GraphQLを使用する機能



製品の要件は、Facebookによって開発されGraphQLクエリ言語を使用することでした。このため、GraphQLとRESTのどちらが優れているかについての無限の議論に甘んじることはありませんでした。代わりに、すべての長所を考慮して、最も効率的な方法で適切なテクノロジーを使用することにしました。



GraphQLは、主に単一のエンドポイントを持つことにより、APIの開発と保守を簡素化するように設計されていることを考慮に入れました。



GET	/news
GET	/posts
POST	/news
POST	/post


GraphQLには単一のエンドポイントがあります。これは、2つの異なるリソースからデータを取得するために2つの別々の要求を行う必要がないことを意味します。 GraphQLは、すべてのリクエストとミューテーションを1つのエンドポイントに統合し、参照できるようにするだけでなく、RESTAPIに固有のバージョン管理を回避します。



GraphQLは、パフォーマンスを最適化し、特別なクエリ構文を使用して現時点で必要なデータを正確に取得する機能を提供します。必須フィールドはクエリにリストされている必要があります。



const FETCH_USER_DATA = gql`
 query FetchUserData {
   user {
     firstName
     lastName
     date
   }
 }
`;


GraphQLは、厳密に型指定されたエンティティと型スキーマを使用します。これは、TypeScriptおよびフロントエンドの型生成と組み合わせて使用​​すると便利です。



これらの機能の多くは確かにRESTAPIに実装できますが、GraphQLはすぐに使用できます。



GraphQLとのクライアントの相互作用については、優れたドキュメントを備えた最も人気のあるソリューションであるApolloクライアントライブラリを選択しました。これにより、アプリケーションデータを取得、キャッシュ、および変更できます。 Apollo Clientを使用すると、リクエストフックとミューテーションフックおよびツールを使用して、ダウンロード/エラーステータスを簡単に追跡できます。



また、前面では、次の要素を考慮して選択されたNextJSフレームワークを使用しました:事前レンダリング(NextJSは、静的生成とSSRをすぐに実装するための非常に単純なメカニズムを提供します)、既存のすべてのcss-in-jsソリューションのサポート、動的ルーティング、静的ファイルのサポートReactコンポーネントの(画像など)。



最後に、テクノロジーが選択されたら、開発に移りましょう。一見すると、すべてが良さそうに見えます。最新のライブラリ、優れたドキュメント、さまざまな使用例です。各テクノロジーは個別に、快適で迅速な開発を促進するように設計されています。欠かすことのできない定型文を作成し、UIコンポーネントを設計することで、ライブラリ間の効果的な相互作用の段階に徐々に近づきました。ここですべての楽しみが始まりました。



NextJSのメカニズムを詳しく見ると、静的生成とSSRの2つの形式のプリレンダラーが使用されていることがわかります。これらの戦略は両方とも、特別なデータプリロード関数を使用して実装されます。



`getInitialProps`(SSR)-最初のロード時に、サーバー上で実行され、データを要求して、小道具としてコンポーネントに渡します。



function Component ({data}) {
 ...
}
 
Component.getInitialProps = async (ctx) => {
 const res = await fetch('https://...')
 const json = await res.json()
 return { data: json.data }
}


`getStaticProps`(静的生成)-ビルド段階で実行されます。NextJSは、この関数から返された小道具を使用してページを事前にレンダリングします。



export async function getStaticProps(context) {
 return {
   props: {}, //       props
 }
}


`getServerSideProps`(サーバー側のレンダリング)-NextJSは、この関数から返されたデータを小道具として使用して、リクエストごとにページを事前にレンダリングします。



export async function getServerSideProps(context) {
 return {
   props: {}, //       props
 }
}


したがって、リストされているすべての関数はコンポーネントの外部で宣言され、データを受け取り、それをコンポーネントに渡します。これは、Apolloクライアントとの相互作用の問題の1つにつながります。ライブラリは、「useQuery」フックや「Query」コンポーネントなどのクエリメカニズムを提供し、提案されたメソッドはいずれもコンポーネントの外部で使用できません。このことを念頭に置いて、私たちのプロジェクトでは、next-with-apolloライブラリを使用することにし、最終的には結果に満足しました。



Apollo Clientのもう1つの既知の問題は、「useQuery」フックからの要求が無限にループする可能性があることです。問題の核心は、Apolloクライアントがデータを正常に受信するまでリクエストを無期限に送信し続けることです。これにより、サーバーが何らかの理由でデータを返すことができない場合、コンポーネントが無限の要求で「ハング」する状況が発生する可能性があります。



私たちの場合、その理由の1つは、背面のスキームの変更でした。Apolloは独自に型を生成するため、フロントでクエリを作成するときは、バグを回避するために生成された型に従う必要がありました。たとえば、タイプの問題がなく、作業リクエストがありました。ただし、バックプレーンのスキーマを変更すると、タイプも同時に変更されたため、作業要求が機能しなくなる可能性がありました。これを考えると、チームの神経と時間を節約するために、すぐにロギングと明確なエラー処理システムを実装することが最適です。



私たちの意見では、graphqlクエリで、受信するデータを正確に指定できることが非常に便利であることがわかりました。多数のリクエストを送信する場合、これにより不要なデータの処理を回避できます。同様に、これはデータ量が増えるにつれてパフォーマンスに大きな影響を与える可能性があります。



GraphQLの利点の1つは、開発とAPIサポートの利便性と見なされていることは注目に値しますが、このプロパティはバックエンド開発にとってより重要であり、私たちの観察によれば、フロントに大きな影響はありません。型が生成されるため、バックプレーンでスキーマが変更されるたびに、影響を受けるすべてのクエリを書き直しました。ベックはまた、まだ実装されていない何かを前面に出す必要がある場合は、スキームを改良する必要がありました。同時に、TypeScriptを使用する際の型の生成により、コードの記述段階で多くのエラーをキャッチすることが可能になりました。



まとめ



私たちの観察によれば、GraphQLはさまざまなタイプのITソリューションで広く使用されており、開発チームに特定の利点を提供します。プロジェクトの開発中に遭遇したGraphQLの主な機能を要約しましょう。



  • . graphql , TypeScript .
  • . GraphQL - . , ( , ). graphql «» ,
  • . graphql- , . .
  • . GraphQL , .


! , .



All Articles