GraphQLとApollo


GraphQLとApolloを学ぶために、資料探しの過程でも真似しやすい薄っぺらなコード辞書のYouTubeを参考にしました.

GraphQL


「必要な情報だけもらえますか?」苦悩から生まれたのがGraphQL.GraphQLは,ユーザテーブルに情報があると仮定すると,ユーザ名と性別に関するデータしか受信できない.
また、GraphQLは、必要な情報を一度に取得することができる.例えば、REST APIは、ユーザテーブルとコメントテーブルが存在する場合、Aというユーザのコメントを取得するために、ユーザとコメントに対する要求をそれぞれ送信する必要がある.
この2つの機能は、データを節約し、要求を最小化し、1つのendPointですべての要求を処理することができる.

GraphQLのメリットとデメリット


参考になる文章
  • の利点
  • で厳密に定義されたデータ型は、クライアントとサーバ間の通信エラーを低減します.
  • GraphQLでは、既存のクエリーを中断せずにアプリケーションAPIをアップグレードできます.(無停止配置)
  • REST APIでは使用できない機能を提供するために、ほとんどのオープンソースGraphQL拡張機能を使用することができます.
  • REST APIは、要求回数を必要とするリソースタイプに比例してリソースタイプ別に要求する必要がある.
    逆に、GraphQLは、必要な情報をすべて1つのQueryに含めることができ、HTTP応答のサイズを低減することができる.
  • の欠点
  • ファイル転送など、テキストだけでは難しい作業を処理するのは複雑です.
  • HTTPとHTTPによるキャッシュはRESTより複雑である.
  • の固定された要求および応答のみが必要である場合、Queryは、RESTful APIよりも要求のサイズを大きくする.
  • API保守担当者は、保守可能なGraphQLモードを作成するために追加のタスクを実行する必要があります.これには時間がかかります.(開発者間の不要な通信コストを低減できる)
  • REST API? GraphQL?


    では、どのような場合にREST APIとGraphQLを選択すればいいのでしょうか.
    異なる形状の異なる要求に応答する必要があり、ほとんどの要求がCRUDである場合、GraphQLを使用することが望ましい.
    RESTfulは、HTTPとHTTPSのcachingを使用し、ファイル転送などの要求が単純なテキストに処理されない場合に使用される.また、要求事項は変動していないので、要求構造を明確にする際にも使いやすいです.
    もちろん両方使えます.GraphQLにEndpointを作成し、他のRESTful APIにEndpointを作成し、それぞれの効率に合わせて使用するだけです.
    しかしながら、1つの目的のためには、2つのAPI構造の混合使用がAPI品質を低下させる可能性があるという問題を考慮する必要がある.

    Apollo


    なぜGraphQLを使うのか、どのような場合に適用すれば有効なのか分かりました.これらの動作がどのように可能なのかを知る必要があります.バックエンドは情報の提供と処理が必要であり、フロントエンドは適切な要求を送信する必要がある.これらのソリューションが簡単にできます.このうち、フロントエンドとバックエンドがサポートされており、多くのApolloは簡単な設定と多くの機能を提供しています.

    使用方法


    Apollo-Serverを使用してサーバを構築し、Apollo-Clientおよびreactを使用してフロントエンドを作成します.

    バックエンド設計


    クエリーの作成とリクエスト

    //Server
    const database = require('./database')
    const { ApolloServer, gql } = require('apollo-server')
    
    const typeDefs = gql`
        type Query {
            customers: [Customer]
        }
        type Customer {
            id: Int
            gender: String
    		name: String
    		group : Int
        }
    `
    const resolvers = {
      Query: {
        customers: () => database.customers
      }
    }
    
    const server = new ApolloServer({ typeDefs, resolvers })
    
    server.listen().then(({ url }) => {
    console.log(`🚀  Server ready at ${url}`)
    })
    上はcsvをdbファイルとして設計したものです.

  • Query
    定義
  • 要求で使用するクエリ
  • クエリー文ごとに返されるデータ型
  • を指定します.

  • type
  • 返されるデータのフォーマット
  • を指定します.

  • resolvers
  • 解析器のQueryでは、関数宣言
  • は、データをオブジェクトとして返すエントリ
  • DBクエリーコード(MySQL、PostgreSQL、MongoDBなど)
  • つまり、顧客タイプの顧客クエリーが定義されます.customerの戻り値はcustomer値(配列別)の意味です.
    アポロサーバは,このように生成されたtypeDefと解析器をコンストラクション関数のパラメータとしてサーバに受信する.
    query {
        customers {
            id
            gender
            name
            group
        }
    }
    このクエリ文を使用して、フロントからデータをロードできます.

    その他のデータの取得

    const typeDefs = gql`
        type Query {
            customers: [Customer]
    		friends: [Friend]
        }
        type Customer {
            id: Int
            gender: String
    		name: String
    		group : Int
    		friends: [Friend]
        }
        type Friend {
            id: Int
            gender: String
    		group : Int
        }
    `
    const resolvers = {
      Query: {
        customers: () => database.customers
        .map((customer) => {
            customer.friends = database.friends
            .filter((friend) => {
                return friend.group === customer.group
            })
            return customer
        }),
      }
    }
    
    お客様の友達の性別を知りたいです.そして、一度にお客様に問い合わせをお願いすると、Friendの情報も一緒に出てくるようにしたいと思います.
    ではまずFriendを作成しましょう解析器Queryのcustomersセクションを変更します.friendのgroupとcustomのgroupは同じものだけを検索し、customerに入れて車に戻ります.
    お客様にfriends: [Friend]を追加することを忘れないでください.
    query {
        customers {
            id
            gender
            name
            group
            friends{
            	id
                gender
                group
            }
        }
    }
    今ではリクエスト1回でfriendsの情報を受け取ることができます.

    特定情報のみ取得

    type Query {
        ...
        customers(gender: String): [Customers]
    }
    私はお客様から男の情報を得たいだけです.まず照会を記入します.
    Query: {
        //...
        customers: (parent, args, context, info) => database.teams
            .filter((customer) => {
                return customer.gender === args.gender
            }),
    }
    解析器のクエリでJavaScript関数を使用してフィルタリングします.
    query {
    customers(gender: 'man') {
          id
          gender
          name
          group
      }
    }
    今フロントでqueryリクエストで終わりました.これは現在のパラメータを使用して取得されたデータです.これを知りたい場合は、ヤルク因子とインバートを参照してください.

    マルチステーション(データ修正)


    解析器がJSコードをどのように記述するかによって、データを修正することができます.しかしREST APIで約束したようにGraphQLにも明細があります.

    データ消去

    type Mutation {
        deleteCustomer(id: Int): Customer
    }
    まず、id値を取得し、対応する顧客を削除する部分を作成します.戻り値はCustomerで、true falseなどのブール値を与えることも、id値を与えることもできます.(削除時に受け取る戻り値は、スタイルに基づいて決定できます.)
    Mutation: {
          deleteCustomer: (parent, args, context, info) => {
              const deleted = database.customers
                  .filter((customer) => {
                      return customer.id === args.id
                  })[0]
              database.customers = database.customers
                  .filter((customer) => {
                      return customer.id !== args.id
                  })
              return deleted
          }
    }
    削除するデータを削除に保存し、実際に削除してから削除に戻ります.
    mutation {
      deleteCustomer(id: 1) {
          id
          gender
          name
          group
      }
    }
    フロントの問い合わせのようにお願いできます.
    データの追加と削除も簡単です.注-ヤルコワークステーション

    モジュール化



    サービスが拡大するにつれて、クエリーの部分が大きくなります.どのように毒性を管理して、メンテナンスしやすいですか?ヤルコモジュール化を参照
    答えはモジュール化です.上記の例では、javascriptファイルが7つありますが、どのように抽象的になるかが開発者の心の声です.
    簡単に説明すると、equipmenttype EquipmenttypeDefsを対象としたresolversを発表した.module.exportsにQueryを加え、_queriesにMitationに関するコードを加える._mitationsもそうです.
    const { ApolloServer } = require('apollo-server')
    const _ = require('lodash')
    
    const queries = require('./typedefs-resolvers/_queries')
    const mutations = require('./typedefs-resolvers/_mutations')
    const equipments = require('./typedefs-resolvers/equipments')
    
    const typeDefs = [
        queries,
        mutations,
        equipments.typeDefs,
    ]
    
    const resolvers = [
        equipments.resolvers
    ]
    
    const server =  new ApolloServer({typeDefs, resolvers})
    
    server.listen().then(({url}) => {
        console.log(`🚀  Server ready at ${url}`)
    })
    これらはsuppliesで使用できるようになりました.indexは、QueryまたはMutationで状況に応じて実現される関数の空間であり、dbWorkで使用される.
    GraphQLの基本タイプとenumを使用したカスタムタイプ宣言とリストタイプについては、ヤルコタイプをご参照くださいを参照してください.また、汎用とインタフェースがどのように使われているかを見ることができます.

    の最後の部分


    フロント開発だけやっていて、バックグラウンドはあまりやったことがないので整理してみました.実際、公式文書やYouTube講座を見ると、それほど難しくないように見えます.しかし、サービスやプロジェクトを直接実施すると、多くの困難に直面する可能性があります.今回のチームメンバーとプロジェクトはGraphQLとApolloを使用しており、開発過程で遭遇した困難と解決過程は後でアップロードされる.
    GraphQLのフロントは、公式ファイルGet started with Apollo Clientで解決できます.