[Note] GraphQL ecosystem, etc

bbio3o·2021년 6월 7일
0

👩‍💻 노트

목록 보기
5/10

노트 정리중mm

1. GraphQL ecosystem

client

Lakka

가장 단순하고 간단함. Basic queries, mutations, 간단한 캐싱 등을 제공

Apollo Client

MeteorJS 개발자가 개발, 기능과 복잡도의 적절한 균형

Relay

모바일에서 뛰어난 성능 퍼포먼스 보이지만, 굉장히 복잡하다. 대형 애플리케이션에서 활용 가능

Server

GraphQL Express

익스프레스-그래프QL은 익스프레스나 미들웨어를 지원하는 웹 프레임워크를 사용하여 그래프QL 서버를 빠르게 설정하는 미들웨어의 일부입니다. 한 오브젝트 안에 어떤 역할을 하는지 볼 수 있습니다.

Apollo Server

아폴로 서버는 기존 노드 서버에 위치하여 그래프QL 쿼리를 구문 분석하는 패키지입니다. (express-graphql과 매우 유사함) Express, Koa 등과 함께 사용할 수 있습니다.


참고

graphql-express 셋팅

package.js

{
  "name": "users",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "json:server": "json-server --watch db.json",
    "dev": "nodemon server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^0.21.1",
    "express": "^4.17.1",
    "express-graphql": "^0.12.0",
    "graphql": "^15.5.0",
    "json-server": "^0.16.3",
    "loadash": "^1.0.0",
    "nodemon": "^2.0.7"
  }
}

server.js

// server.js
const express = require('express');
const { graphqlHTTP } = require('express-graphql')

;
const schema = require('./schema/schema');

const app = express();

app.use('/graphql', graphqlHTTP({
  schema,
  graphiql: true
}));

app.listen(4000, () => {
  console.log('Listening');
});

schema/schema.js

// schema/schema.js
const graphql = require('graphql');
// const _ = require('lodash');
const axios = require('axios');
const {
  GraphQLObjectType, 
  GraphQLString,
  GraphQLInt,
  GraphQLSchema,
  GraphQLList,
  GraphQLNonNull
} = graphql;

const CompanyType = new GraphQLObjectType({
  name: 'Company',
  // this function gets defined but does not get excuted until after this entire file with arrow function
  // 화살표 함수를 통해 UserType이 선언되기 전에 참조하는 에러 해결
  fields: () => ({
    id: { type: GraphQLString },
    name: { type: GraphQLString },
    description: { type: GraphQLString },
    users: {
      // multiple users
      type: new GraphQLList(UserType),
      resolve(parentValue, args) {
        return axios.get(`http://localhost:3000/companies/${parentValue.id}/users`)
          .then(res => res.data)
      }
    }
  })
});

const UserType = new GraphQLObjectType({
  name: 'User',
  fields: () => ({
    id: { type: GraphQLString },
    firstName: { type: GraphQLString },
    age: { type: GraphQLInt },
    company: {
      type: CompanyType,
      resolve(parentValue, args) {
        return axios.get(`http://localhost:3000/companies/${parentValue.companyId}`)
          .then(res => res.data);
      }
    }
  })
});

const RootQuery = new GraphQLObjectType({
  name: 'RootQueryType',
  fields: {
    // Multiple RootQuery Entry Points
    user: {
      type: UserType,
      args: { id: { type: GraphQLString } },
      resolve(parentValue, args) {
        // return _.find(users, { id: args.id })
        return axios.get(`http://localhost:3000/users/${args.id}`)
          .then(resp => resp.data);
      }
    },
    company: {
      type: CompanyType,
      args: { id: { type: GraphQLString } },
      resolve(parentValue, args) {
        return axios.get(`http://localhost:3000/companies/${args.id}`)
          .then(resp => resp.data);
      }
    }
  }
});

const mutation = new GraphQLObjectType({
  name: 'Mutation',
  fields: {
    addUser: {
      type: UserType,
      args: {
        // must provide firstname
        firstName: { type: new GraphQLNonNull(GraphQLString) },
        age: { type: GraphQLInt },
        companyId: { type: GraphQLString }
      },
      resolve(parentValue, { firstName, age, companyId }) {
        return axios.post('http://localhost:3000/users', { firstName, age, companyId })
          .then(res => res.data);
      }
    },
    deleteUser: {
      type: UserType,
      args: {
        id: { type: new GraphQLNonNull(GraphQLString) }
      },
      resolve(parentValue, { id }) {
        return axios.delete(`http://localhost:3000/users/${id}`)
          .then(res => res.data);
      }
    },
    editUser: {
      type: UserType,
      args: {
        id: { type: new GraphQLNonNull(GraphQLString) },
        firstName: { type: GraphQLString },
        age: { type: GraphQLInt },
        companyId: { type: GraphQLString }
      },
      resolve(parentValue, args) {
        return axios.patch(`http://localhost:3000/users/${args.id}`, args)
          .then(res => res.data);
      }
    }
  }
});

module.exports = new GraphQLSchema({
  mutation,
  query: RootQuery
});

db.js

// db.js
{
  "users": [
    {
      "id": "40",
      "firstName": "Alex",
      "age": 30,
      "companyId": "2"
    },
    {
      "id": "41",
      "firstName": "Nick",
      "age": 40,
      "companyId": "2"
    },
    {
      "firstName": "Samantha",
      "age": 25,
      "companyId": "1",
      "id": "S1TKHzuwl"
    }
  ],
  "companies": [
    {
      "id": "1",
      "name": "Apple",
      "description": "iphone"
    },
    {
      "id": "2",
      "name": "Google",
      "description": "search"
    }
  ]
}

PUT과 PATCH 차이

PUT : 리소스의 모든 것을 업데이트 한다.
PATCH : 리소스의 일부를 업데이트 한다.

가령 한 사용자에 대해 여러 정보를 객체로 수집하여 서버로 보내는 경우, PUT은 보내지지 않은 정보에 대해서는 null값으로 업데이트하지만, PATCH는 기존 데이터를 유지하는 방식으로 대응한다.

profile
그림도 그리는 개발자 🎨👩‍💻

0개의 댓글