GraphQL+NodeJS練習!


ノードで比較REST APIのGraphQLを練習した.
GraphQLを使う理由はいろいろありますが、その中でも
これが「over Fetching」と「Under Fetch」(必要なデータを得るために1回以上通信する)が主な原因である.
GraphQLは目的のデータしか受信できないため、上記の問題を解決することができます.それ以外にもメリットとデメリットがあります.
この部分は単独で位置決めするつもりです.

プリファレンス


準備物は基本アイテムでまずGraphql-ヨガを受けましょう!(graphsqlの設定が容易なパッケージ)
npm i graphql-yoga
次に、ノード環境でES 6構文にbabelをインストールし、パッケージ化します.jsonを設定します.
npm i @babel/cli babel/core babel/node babel/preset-env -dev

--package.json--
"scripts": {
    "start": "nodemon --exec babel-node index.js"
  },

サーバの作成


Queryは、サーバまたはDBから値を取得するREST APIにおいてGETの機能を有する.
typeDefsはschemaの詳細機能を担当しています.
解析器はデータをインポートする関数機能を担当します.
import { createServer } from "@graphql-yoga/node";
const server = createServer({
  schema: {
    typeDefs: `
      type Query {
		greeting: String!
	  }	
    `,
    resolvers: {
      Query: {
        greeting: () => "Hello"
      }
    }
  }
})
server.start(() => console.log("GraphQL Server Start"))
Yogaを使用すると、グラフィックライブラリでAPIをテストして検証することができ、非常に簡単です.

アレイの作成と出力


メンテナンスの観点から、schema、解析器などの機能を個別のファイルに分離することが望ましい.
[db.js]

export const movies = [
  {
    id: 1,
    title: "Star Wars",
    rating: 8.5
  },
  {
    id: 2,
    title: "Avengers",
    rating: 9.3
  },
  {
    id: 3,
    title: "Lottos",
    rating: 7.0
  },
  {
    id: 4,
    title: "The Wars",
    rating: 6.4
  },
  {
    id: 5,
    title: "Bank",
    rating: 5.6
  },
]
ワークステーションは、サーバ、データベースを介してデータの変更を行い、REST APIのPost、Updateなどの機能と一致します.
import { createServer } from "@graphql-yoga/node";
import { movies } from "./graphql/db.js";
const server = createServer({
  schema: {
    typeDefs: `
      type Query {
        getMovies: [Movie]!,
        search(id: Int!): Movie
      }
	// schema Type 지정
      type Movie {
        id: Int!
        title: String!
        rating: Int!
      }
      type Mutation {
        addMovie(title: String!, rating: Float!): Boolean
      }
    `,
    resolvers: {
      Query: {
        getMovies: () => movies,
        search: (_, { id }) => movies.find((movie) => movie.id === id),
      },
      Mutation: {
        addMovie: (_, {title, rating}) => {
          const newMovie = {
            id: movies.length + 1,
            title,
            rating
          }
          const beforeLength = movies.length;
          movies.push(newMovie);
          const afterLength = movies.length
          if (beforeLength < afterLength) {
            return true
          } else {
            return false
          }
        },
      }
    }
  }
})

server.start(() => console.log("GraphQL Server Start"))
Resolver関数については、function(obj, args, context, info) {}の形式で表され、2番目のパラメータargsは伝達パラメータに用いられるが、例を用いない場合は_の形式で表されるのが好ましい.
では、GraphiQLで正常に動作していることを確認しましょう.
// 실행
mutation {
  addMovie(title: "Forest Gump",rating: 9.52)
}

// 결과

{
  "data": {
    "addMovie": true
  }
}
// 실행 
query {
  getMovies {
    id
    title
  }
}

// 결과
{
  "data": {
    "getMovies": [
      {
        "id": 1,
        "title": "Star Wars"
      },
      {
        "id": 2,
        "title": "Avengers"
      },
      {
        "id": 3,
        "title": "Lottos"
      },
      {
        "id": 4,
        "title": "The Wars"
      },
      {
        "id": 5,
        "title": "Bank"
      },
      {
        "id": 6,
        "title": "New Movie"
      },
      {
        "id": 7,
        "title": "Forest Gump"
      }
    ]
  }
}
よく撮れました!
次回はNestJS+TypeORMに適用します.

Reference

  • Announcing GraphQL Yoga 2.0!
  • GraphQLサーバの基本的な使い方
  • https://graphql.org/learn/execution/#root-fields-resolvers