apeescape2.com
  • メイン
  • Kpiと分析
  • 計画と予測
  • モバイルデザイン
  • Uiデザイン
バックエンド

GraphQLとREST-GraphQLチュートリアル

ブロックの周りの新しい子供、GraphQLについて聞いたことがあるかもしれません。そうでない場合、GraphQLは一言で言えば、フェッチするための新しい方法です API 、RESTの代替。 Facebookの内部プロジェクトとして始まり、オープンソース化されて以来、 たくさんの牽引力 。

この記事の目的は、すでにGraphQLを考えている場合でも、試してみたい場合でも、RESTからGraphQLに簡単に移行できるようにすることです。 GraphQLの予備知識は必要ありませんが、記事を理解するには、RESTAPIにある程度精通している必要があります。

GraphQLとREST-GraphQLチュートリアル



記事の最初の部分は、私が個人的にGraphQLがRESTより優れていると思う3つの理由を説明することから始めます。 2番目の部分は、バックエンドにGraphQLエンドポイントを追加する方法に関するチュートリアルです。

GraphqlとREST:なぜRESTを削除するのですか?

GraphQLがニーズに適しているかどうかまだ迷っている場合は、「RESTとGraphQL」の非常に広範囲で客観的な概要を示します。 ここに 。ただし、GraphQLを使用する理由の上位3つについては、読み進めてください。

理由1:ネットワークパフォーマンス

バックエンドに、名、名前、電子メール、およびその他の10個のフィールドを持つユーザーリソースがあるとします。クライアントでは、通常、それらのうちの2つだけが必要です。

/usersでREST呼び出しを行うエンドポイントはユーザーのすべてのフィールドを返し、クライアントは必要なフィールドのみを使用します。明らかに、データ転送の無駄がいくらかあります。これは、モバイルクライアントで考慮される可能性があります。

GraphQLはデフォルトで、可能な限り最小のデータをフェッチします。ユーザーの名前と名前だけが必要な場合は、クエリでそれを指定します。

以下のインターフェースはGraphiQLと呼ばれ、GraphQLのAPIエクスプローラーのようなものです。この記事の目的のために小さなプロジェクトを作成しました。コードはホストされています GitHubで 、そして第2部で詳しく説明します。

サーバー側のレンダリングとクライアント側のレンダリング

インターフェイスの左側のペインにはクエリがあります。ここでは、すべてのユーザーを取得しています。GET /usersを実行します。 RESTを使用して、名前と名前のみを取得します。

クエリ

query { users { firstname lastname } }

結果

{ 'data': { 'users': [ { 'firstname': 'John', 'lastname': 'Doe' }, { 'firstname': 'Alicia', 'lastname': 'Smith' } ] } }

メールも取得したい場合は、「lastname」の下に「email」行を追加するとうまくいきます。

一部のRESTバックエンドは、/users?fields=firstname,lastnameのようなオプションを提供します部分的なリソースを返します。その価値については、 Googleはそれをお勧めします 。ただし、デフォルトでは実装されておらず、特に他のクエリパラメータを入力すると、リクエストがほとんど読めなくなります。

  • &status=activeアクティブユーザーをフィルタリングするには
  • &sort=createdAat作成日でユーザーを並べ替える
  • &sortDirection=descあなたは明らかにそれを必要とするので
  • &include=projectsユーザーのプロジェクトを含める

これらのクエリパラメータは、クエリ言語を模倣するためにRESTAPIに追加されたパッチです。 GraphQLは何よりもクエリ言語であり、最初からリクエストを簡潔かつ正確にします。

理由2:「インクルードとエンドポイント」の設計上の選択

簡単なプロジェクト管理ツールを構築したいとします。ユーザー、プロジェクト、タスクの3つのリソースがあります。また、リソース間の次の関係も定義します。

リソース間の関係

これが私たちが世界に公開するエンドポイントのいくつかです:

終点 説明
GET /users すべてのユーザーを一覧表示
GET /users/:id id:idのシングルユーザーを取得します
GET /users/:id/projects 1人のユーザーのすべてのプロジェクトを取得する

エンドポイントはシンプルで読みやすく、よく整理されています。

リクエストがより複雑になると、事態はさらに複雑になります。 GET /users/:id/projectsを見てみましょうエンドポイント:ホームページにはプロジェクトのタイトルのみを表示し、ダッシュボードにはプロジェクトとタスクを表示し、複数のREST呼び出しを行わないようにします。私は呼ぶでしょう:

  • GET /users/:id/projectsホームページ用。
  • GET /users/:id/projects?include=tasks (たとえば)ダッシュボードページで、バックエンドがすべての関連タスクを追加するようにします。

クエリパラメータを追加するのが一般的な方法です?include=...これを機能させるために、そしてによってさえ推奨されています JSON API 仕様。 ?include=tasksのようなクエリパラメータまだ読み取り可能ですが、やがて?include=tasks,tasks.owner,tasks.comments,tasks.comments.authorになります。

この場合、/projectsを作成する方が賢明でしょう。これを行うエンドポイント? /projects?userId=:id&include=tasksのようなものです。含める関係のレベルが1つ少ないのでしょうか?または、実際には/tasks?userId=:idエンドポイントも機能する可能性があります。これは難しい設計上の選択になる可能性がありますが、 さらに複雑 多対多の関係がある場合。

ファミリーオフィスのヘッジファンドとは

GraphQLはincludeを使用しますどこにでもアプローチします。これにより、関係をフェッチするための構文が強力で一貫性のあるものになります。

ID1のユーザーからすべてのプロジェクトとタスクを取得する例を次に示します。

クエリ

{ user(id: 1) { projects { name tasks { description } } } }

結果

{ 'data': { 'user': { 'projects': [ { 'name': 'Migrate from REST to GraphQL', 'tasks': [ { 'description': 'Read tutorial' }, { 'description': 'Start coding' } ] }, { 'name': 'Create a blog', 'tasks': [ { 'description': 'Write draft of article' }, { 'description': 'Set up blog platform' } ] } ] } } }

ご覧のとおり、クエリ構文は簡単に読み取れます。さらに深く掘り下げて、タスク、コメント、写真、作成者を含めたい場合、APIを整理する方法について2度考えません。 GraphQLを使用すると、複雑なオブジェクトを簡単にフェッチできます。

理由3:さまざまなタイプのクライアントの管理

バックエンドを構築するとき、私たちは常にAPIをすべてのクライアントができるだけ広く使用できるようにすることから始めます。それでも、クライアントは常に呼び出しを減らしてフェッチを増やしたいと考えています。深いインクルード、部分的なリソース、およびフィルタリングにより、Webクライアントとモバイルクライアントによって行われる要求は、互いに大きく異なる可能性があります。

RESTには、いくつかの解決策があります。カスタムエンドポイント(つまり、エイリアスエンドポイント、たとえば/mobile_user)、カスタム表現(Content-Type: application/vnd.rest-app-example.com+v1+mobile+json)、またはクライアント固有のAPI( Netflixはかつて )。これら3つはすべて、バックエンド開発チームによる追加の作業が必要です。

GraphQLは、クライアントにより多くのパワーを提供します。クライアントが複雑なリクエストを必要とする場合、対応するクエリ自体を構築します。各クライアントは、同じAPIを異なる方法で使用できます。

GraphQLの使用を開始する方法

今日の「GraphQLvs。REST」に関するほとんどの議論では、人々は2つのうちのいずれかを選択する必要があると考えています。これは単に真実ではありません。

最近のアプリケーションは通常、いくつかのAPIを公開するいくつかの異なるサービスを使用します。実際、GraphQLは、これらすべてのサービスへのゲートウェイまたはラッパーと考えることができます。すべてのクライアントはGraphQLエンドポイントにヒットし、このエンドポイントはデータベースレイヤー、ElasticSearchやSendgridなどの外部サービス、またはその他のRESTエンドポイントにヒットします。

GraphQLとRESTエンドポイントの比較

両方を使用する2番目の方法は、個別の/graphqlを使用することです。 RESTAPIのエンドポイント。これは、REST APIにアクセスするクライアントがすでに多数あるが、既存のインフラストラクチャを損なうことなくGraphQLを試してみたい場合に特に便利です。そして、これが私たちが今日探求しているソリューションです。

サーバー側のWebアプリケーションを保護することが難しい理由ではないのはどれですか?

前に述べたように、私はこのチュートリアルを利用可能な小さなサンプルプロジェクトで説明します GitHubで 。これは、ユーザー、プロジェクト、およびタスクを備えた単純化されたプロジェクト管理ツールです。

このプロジェクトで使用されるテクノロジーは、Webサーバー用のNode.jsとExpress、リレーショナルデータベースとしてのSQLite、およびORMとしてのSequelizeです。ユーザー、プロジェクト、タスクの3つのモデルは、 models フォルダ。 RESTエンドポイント /api/users 、 /api/projects そして /api/tasks 世界にさらされており、 rest フォルダ。

GraphQLは、任意のプログラミング言語を使用して、任意のタイプのバックエンドおよびデータベースにインストールできることに注意してください。ここで使用されているテクノロジーは、単純さと読みやすさのために選択されています。

私たちの目標は/graphqlを作成することですRESTエンドポイントを削除せずにエンドポイント。 GraphQLエンドポイントはデータベースORMに直接ヒットしてデータをフェッチするため、RESTロジックから完全に独立しています。

タイプ

データモデルはGraphQLで次のように表されます。 タイプ 、強く型付けされています。モデルとGraphQLタイプの間には1対1のマッピングが必要です。私たちのUserタイプは次のようになります。

type User { id: ID! # The '!' means required firstname: String lastname: String email: String projects: [Project] # Project is another GraphQL type }

クエリ

クエリ GraphQLAPIで実行できるクエリを定義します。慣例により、既存のすべてのクエリを含むRootQueryが必要です。また、各クエリに相当するRESTについても指摘しました。

type RootQuery { user(id: ID): User # Corresponds to GET /api/users/:id users: [User] # Corresponds to GET /api/users project(id: ID!): Project # Corresponds to GET /api/projects/:id projects: [Project] # Corresponds to GET /api/projects task(id: ID!): Task # Corresponds to GET /api/tasks/:id tasks: [Task] # Corresponds to GET /api/tasks }

突然変異

クエリがGETの場合リクエスト、 突然変異 POST / PATCH / PUT / DELETEとして見ることができますリクエスト(実際にはクエリの同期バージョンですが)。

慣例により、すべてのミューテーションをRootMutationに入れます。

type RootMutation { createUser(input: UserInput!): User # Corresponds to POST /api/users updateUser(id: ID!, input: UserInput!): User # Corresponds to PATCH /api/users removeUser(id: ID!): User # Corresponds to DELETE /api/users createProject(input: ProjectInput!): Project updateProject(id: ID!, input: ProjectInput!): Project removeProject(id: ID!): Project createTask(input: TaskInput!): Task updateTask(id: ID!, input: TaskInput!): Task removeTask(id: ID!): Task }

ここでは、UserInput、ProjectInput、およびTaskInputと呼ばれる新しいタイプを導入したことに注意してください。これは、リソースを作成および更新するための入力データモデルを作成するための、RESTでも一般的な方法です。ここで、私たちのUserInputタイプは私たちのUser idなしで入力しますおよびprojectsフィールド、およびキーワードinputに注意してくださいtypeの代わりに:

input UserInput { firstname: String lastname: String email: String }

スキーマ

タイプ、クエリ、ミューテーションを使用して、 GraphQLスキーマ 、これはGraphQLエンドポイントが世界に公開するものです。

schema { query: RootQuery mutation: RootMutation }

このスキーマは強く型付けされており、これらの便利なオートコンプリートを使用できるようになりました。 GraphiQL 。

リゾルバ

パブリックスキーマができたので、これらのクエリ/ミューテーションのそれぞれが要求されたときに何をすべきかをGraphQLに指示します。 リゾルバ 大変な仕事をします。たとえば、次のことができます。

  • 内部RESTエンドポイントにヒット
  • マイクロサービスを呼び出す
  • データベースレイヤーをヒットしてCRUD操作を実行します

サンプルアプリでは3番目のオプションを選択しています。私たちのを見てみましょう リゾルバファイル :

const models = sequelize.models; RootQuery: { user (root, { id }, context) { return models.User.findById(id, context); }, users (root, args, context) { return models.User.findAll({}, context); }, // Resolvers for Project and Task go here }, /* For reminder, our RootQuery type was: type RootQuery { user(id: ID): User users: [User] # Other queries }

これは、user(id: ID!)の場合を意味しますGraphQLでクエリが要求されると、データベースからSequelizeORM関数であるUser.findById()が返されます。

リクエストで他のモデルに参加するのはどうですか?さて、より多くのリゾルバーを定義する必要があります。

User: { projects (user) { return user.getProjects(); // getProjects is a function managed by Sequelize ORM } }, /* For reminder, our User type was: type User { projects: [Project] # We defined a resolver above for this field # ...other fields } */

したがって、projectsを要求するとUserのフィールドGraphQLと入力すると、この結合がデータベースクエリに追加されます。

そして最後に、突然変異のリゾルバ:

RootMutation: { createUser (root, { input }, context) { return models.User.create(input, context); }, updateUser (root, { id, input }, context) { return models.User.update(input, { ...context, where: { id } }); }, removeUser (root, { id }, context) { return models.User.destroy(input, { ...context, where: { id } }); }, // ... Resolvers for Project and Task go here }

ここでこれをいじることができます。サーバー上のデータをクリーンに保つために、ミューテーションのリゾルバーを無効にしました。つまり、ミューテーションはデータベース内の作成、更新、または削除操作を実行しません(したがって、インターフェイスでnullを返します)。 。

クエリ

query getUserWithProjects { user(id: 2) { firstname lastname projects { name tasks { description } } } } mutation createProject { createProject(input: {name: 'New Project', UserId: 2}) { id name } }

結果

{ 'data': { 'user': { 'firstname': 'Alicia', 'lastname': 'Smith', 'projects': [ { 'name': 'Email Marketing Campaign', 'tasks': [ { 'description': 'Get list of users' }, { 'description': 'Write email template' } ] }, { 'name': 'Hire new developer', 'tasks': [ { 'description': 'Find candidates' }, { 'description': 'Prepare interview' } ] } ] } } }

既存のアプリのすべてのタイプ、クエリ、リゾルバーを書き直すには時間がかかる場合があります。ただし、役立つツールはたくさんあります。例えば、 そこ です ツール SQLスキーマをリゾルバーを含むGraphQLスキーマに変換します!

すべてをまとめる

明確に定義されたスキーマと、スキーマの各クエリで何をするかについてのリゾルバーを使用して、/graphqlをマウントできます。バックエンドのエンドポイント:

// Mount GraphQL on /graphql const schema = makeExecutableSchema({ typeDefs, // Our RootQuery and RootMutation schema resolvers: resolvers() // Our resolvers }); app.use('/graphql', graphqlExpress({ schema }));

そして、私たちは持つことができます 見栄えの良いGraphiQLインターフェース バックエンドで。 GraphiQLなしでリクエストを行うには、単にコピーします リクエストのURL 、cURL、AJAXを使用して、またはブラウザで直接実行します。もちろん、これらのクエリの作成に役立つGraphQLクライアントがいくつかあります。いくつかの例については、以下を参照してください。

資本予算は1つです。

次は何ですか?

この記事の目的は、GraphQLがどのように見えるかを味わい、RESTインフラストラクチャを破棄せずにGraphQLを試すことが間違いなく可能であることを示すことです。 GraphQLがニーズに合っているかどうかを知る最良の方法は、自分で試すことです。この記事があなたにダイビングをしてくれることを願っています。

リアルタイム更新、サーバー側のバッチ処理、認証、承認、クライアント側のキャッシュ、ファイルのアップロードなど、この記事では説明していない機能がたくさんあります。これらの機能について学ぶための優れたリソースは GraphQLの方法 。

以下は、その他の役立つリソースです。

サーバー側ツール 説明
graphql-js GraphQLのリファレンス実装。 express-graphqlで使用できますサーバーを作成します。
graphql-server によって作成されたオールインワンGraphQLサーバー アポロチーム 。
他のプラットフォームの実装 Ruby、PHPなど。
クライアント側ツール 説明
リレー ReactをGraphQLに接続するためのフレームワーク。
apollo-client 。 のバインディングを持つGraphQLクライアント React 、 Angular 2 、および 他のフロントエンドフレームワーク 。

結論として、GraphQLは誇大広告以上のものであると私は信じています。明日はまだRESTに取って代わることはありませんが、真の問題に対するパフォーマンスの高いソリューションを提供します。これは比較的新しく、ベストプラクティスはまだ開発中ですが、これは間違いなく、今後2、3年で耳にするテクノロジーです。

基本を理解する

GraphQLとは何ですか?

GraphQLはクエリ言語であり、RESTの代替手段です。 Facebookの内部プロジェクトとして始まりました。

GraphQL over RESTの違いは何ですか?

GraphQLは、すべてのRESTfulエンドポイントを1つにマージし、使用するネットワークトラフィックを減らします。

iOSおよびAndroidデザインでの悪い習慣の回避

モバイル

iOSおよびAndroidデザインでの悪い習慣の回避
機械と信頼:AIバイアスを軽減する方法

機械と信頼:AIバイアスを軽減する方法

バックエンド

人気の投稿
BEM方法論の紹介
BEM方法論の紹介
Ember.js開発者が犯す8つの最も一般的な間違い
Ember.js開発者が犯す8つの最も一般的な間違い
ソフトウェア設計ドキュメントを書くことが重要な理由
ソフトウェア設計ドキュメントを書くことが重要な理由
初期市場参入の課題
初期市場参入の課題
AngularMaterialを使用して最新のWebアプリを構築する
AngularMaterialを使用して最新のWebアプリを構築する
 
モバイルエクスペリエンスのためのeコマースUX
モバイルエクスペリエンスのためのeコマースUX
コンサルタントツールボックス:あらゆるものを解決するためのフレームワーク
コンサルタントツールボックス:あらゆるものを解決するためのフレームワーク
モバイルWebアプリケーションの開発:いつ、なぜ、そしてどのように
モバイルWebアプリケーションの開発:いつ、なぜ、そしてどのように
トップピッチデッキの間違い
トップピッチデッキの間違い
GraphQLとREST-GraphQLチュートリアル
GraphQLとREST-GraphQLチュートリアル
人気の投稿
  • ギリシャの債務危機を簡単に説明
  • c法人vss法人
  • SQLServerデータ同期ツール
  • 不十分なデータベース設計の問題
  • セレンwebdriverページオブジェクトモデル
  • インターフェイス設計のベストプラクティス
カテゴリー
Uiデザイン その他 財務プロセス モバイルデザイン アジャイル 製品の担当者とチーム トレンド 計画と予測 プロジェクト管理 分散チーム

© 2021 | 全著作権所有

apeescape2.com