'graphql'에 해당되는 글 4건

  1. 2018.01.05 GraphQL Overview (graphql.js server code)
  2. 2017.12.03 Netflix Falcor Overview
  3. 2017.11.24 GraphQL Overview
  4. 2017.11.24 Netflix falcor Overview slide

http://devcoding.tistory.com/24 슬라이드를 풀어서 써봤는데 가독성이 그리 좋진 않네요...

Graphql과 느낌이 비슷한 netflix falcor(http://devcoding.tistory.com/28)도 있으니 모르시는 분은 한번 알아두시면 좋을듯 합니다.



GraphQL Overview



Graph - 사전적으로 점과 선으로 이루어진 도형을 Graph라고 함

서로 관계가 있는 2개 또는 그 이상의 양의 상태값을 나타낸 도형

QL - SQL 비슷하다고 우선 생각하면 됨.

- 누가 만들었지?

Facebook

- 언제 만들었지?

2012년부터 내부적으로 사용하다 2015년 공개.

어떤 언어로 되어 있어?

단지 스펙이라서 구현을 하던지 언어별로 구현체가 있으니 가져다 쓰면 됨.http://graphql.org/code/

어디서 쓰고 있어?

Facebook - https://developers.facebook.com/docs/graph-api/using-graph-api)

Github - https://developer.github.com/

Why Github using GraphQL

블로그 : https://githubengineering.com/the-github-graphql-api/

  • 모든 Rest API를 제공하고 있지만 gw(integrators)의 요청을 유연하게 처리하기 힘들었다.

    GraphQL을 쓰면 신경 안써도 된다. 스키마만 업데이트 해주면 된다.

  • 때때로 response를 위해 2, 3번의 호출이 필요했다.

    GraphQL이 알아서 해준다.

  • 매개 변수에 대한 검증이 필요했다.

    매개변수에 대한 검증도 FE의 요청쿼리에 대한 validation 가능하다. eslint-plugin-graphql

  • 코드를 통해 문서를 생성하길 원했다.

    GraphiQL을 쓰면 schema에 대한 정보를 볼수 있고 Query도 실행/검증 가능

  • 요청 받을 Response에 대해서 요청자가 정의하길 원한다.

    이건 넣고 이건 빼고 할필요 없음. 요청자가 요청한 정보만 내려온다.(=overfetch 방지)

Rest API vs GraphQL HTTP상의 Endpoint 비교

REST API

엔티티별로 아래와 같은 스타일.

  • 리스트 조회 : GET /api/posts

  • 조회 : GET /api/posts/1

  • 생성 : POST /api/posts

  • 치환(수정) : PUT or PATCH /api/posts/1

  • 삭제 : DELETE /api/posts/1

GraphQL

모든 엔티티에 대해서 하나의 URL만 가짐.

  • POST /graphql

    ​-> 리스트, 조회, 생성, 수정, 삭제등

이정도면...간단하게 Database의 console에 붙어서 Query한다 생각하면 편하다.

다만 Query의 스펙을 미리 정의(=Schema) 해놓아야만 한다. Query 에 따라서 입력/조회/수정/삭제를 한다.

GraphQL Server가 할일은?

1. Node 정의



개별 node를 정의. 예 : 유저, 글, 댓글, 회사, 상품, 판매자

쉽게 이야기하면 Database의 테이블 단위

2. Node 간 관계설정



  • node에 관계 필드를 추가.- user node에 companyInfo 추가- company node에 users 추가

  • 관계 필드에 대해서 Store 연결.

    - companyInfo필드의 Type은 CompanyType- users 필드의 Type은 GraphQLList(UserType)과 같이 감싸준다.

노드(점)의 관계 필드(선)가 곧 Store 연결(=DB 조회)


3. Root Query 생성(선정).

Node중 최상위에서 조회가능한 녀석들을 분류해야한다.


Root Query?

  • REST API의 여러 조회용 END POINT의 모음이라 생각하면 이해하기 쉽다. 즉. Entry Point를 제공자가 정의해주는 것이다.

  • RootQuery는 의미적인 표현인 것이고 일반 node와 Type/동작 동일.= GraphQLObjectType

  • 다만 의미적으로 Root Query Node의 경우에는 다른 node를 참조만 하고,다른 노드로 부터 참조되지 않는다.

GraphQL로 서비스 구성 예시

DB든 외부연동서버든 처리할 데이타에 대해서는 Node 정의를 해주어야 합니다.


GraphQL로 서비스 예시 2

여기서도 GraphQL서버에서 Composite을 위해서 서버별 타입별로 Node정의를 해주어야 한다.

만약 A,B 서버에 동일하게 생긴 Node가 있더라도 관계설정이 달라질수 있으므로각각을 구분해주어야 한다.

GraphQL 사용시 주요 장점.

  • FE/Native의 요청 필드만 리턴하므로 Overfetch 방지.

  • MSA 구조에서 여러 서버의 데이타를 효율적으로 Data Integration 한다.

  • REST API에서 2~3회 요청에 걸쳐 데이타를 가져오는 경우를 간단하게 1 회 요청으로 끝낼 수 있다.(유연성 甲)# BE 개발자가 별도 Endpoint 추가하고 로직으로 풀던 문제를 쉽게 끝낼 수 있다.

전체 구조



이렇게도 나누는것도 가능은 할듯.

코드를 보면 이렇게도 가능할 것으로 생각된다.다만 아래와 같이 나눌 경우 동일 데이타에 대해서 변경과 조회가

함께 일어나므로 시점에 따라 값이 달라질수도 있는 문제가 발생 할 수 있다.

샘플코드

회사와 사람 Node

코드로 두 Node로 관계를 지어보자.

샘플을 실행시켜보려면 https://github.com/gidong-lee/graphQL_exam

샘플코드에 대해서.

  • axios는 back 단 rest api를 호출해주는 jQuery의 ajax같은 라이브러리다.(예 : Spring 개발시 RestTemplate)

  • JSON Server는 json파일을 읽어 쉽게 개발/목킹용 rest api 서버를 만들어 주는 녀석이다.입력,수정,삭제,페이징등을 모두 처리해준다.GitHub : https://github.com/typicode/json-server

User Type

const UserType = new GraphQLObjectType({
 name: 'User', // GraphQL Object Name(필수)
 fields: () => ({
   id: {type: GraphQLString},
   firstName: {type: GraphQLString},
   age: {type: GraphQLInt},
   companyId: {type: GraphQLString},
   company: {   /* 연결(user -> company) */
     type: CompanyType,
     resolve(parentValue, args) {
       console.log(parentValue, args);
       return axios.get(`${SERVER_DOMAIN}/companies/${parentValue.companyId}`)
        .then(req => req.data);
    }
  }
})
});

위의 fields.company 필드가 관계필드가 된다.

관계 필드는 곧 DB/Cache/rest server 연결(=DB 조회)을 뜻한다.

코드의 axios는 뒤단의 rest api를 호출하여 데이타를 가져오는 것이니 크게신경 안써도 됨.

Company Type


const CompanyType = new GraphQLObjectType({
 name: 'Company',
 fields: () => ({
   id: {type: GraphQLString},
   name: {type: GraphQLString},
   description: {type: GraphQLString},
   users: { /* 연결(company -> users) */
     type: new GraphQLList(UserType),
     args: {limit: {type: GraphQLInt}},
     resolve(parentValue, args) {
       const { limit = 20 } = args;
       return axios.get(
         `${SERVER_DOMAIN}/companies/${parentValue.id}/users?_limit=${limit}`
      ).then(req => req.data);
    }
  }
})
});

위의 fields.users 필드가 관계필드가 된다.

관계 필드는 곧 DB/Cache/rest server 연결(=DB 조회)을 뜻한다.

users필드의 타입이 GraphQLList(UserType)인 것을 잘 숙지하자.

Root Query

Query(조회) 시 시작될 수 있는 node 를 지정하여야 한다.따라서 node product 조회는 RootQuery 필드에 없으므로 company를 통해서만 접근 할 수 있다.


RootQuery 지정


const RootQuery = new GraphQLObjectType({
 name: 'RootQueryType',
 fields: () => ( {
   user: { /* RootQueryObject에 User연결 */
     type: UserType,
     args: {id: {type: GraphQLString}},
     resolve(parentValue, args) {
       return axios.get(`${SERVER_DOMAIN}/users/${args.id}`)
        .then(req => req.data);
    }
  },
   company: { /* RootQueryObject에 Company연결 */
     type: CompanyType,
     args: {id: {type: GraphQLString}},
     resolve(parentValue, args) {
       return axios.get(`${SERVER_DOMAIN}/companies/${args.id}`)
        .then(req => req.data);
    }
  }
})
});

관계 필드의 resolve 함수?

parentValue -> 나의 상위에서 주입해준 값.user의 Company에서 조회하여 리턴해준값

args -> Query 호출시에 적어주는 값. 예 : id, searchKeyword, limit, first, last, page, lastNum


const CompanyType = new GraphQLObjectType({
 name: 'Company',
 fields: () => ({
   id: {type: GraphQLString},
   name: {type: GraphQLString},
   description: {type: GraphQLString},
   users: {
     type: new GraphQLList(UserType),
     args: {limit: {type: GraphQLInt}},
     resolve(parentValue, args) {
       const { limit = 20 } = args;
       return axios.get(
         `${SERVER_DOMAIN}/companies/${parentValue.id}/users?_limit=${limit}`
      ).then(req => req.data);
    }
  }
})
});

GraphiQL - Graphql의 개발자도구.

작성한 Schema를 보고 Query를 작성하고 유효성을 검사하면서 테스트를 할 수 있는 good dev tool


설치버전도 있고, 서버(dev용으로) 띄울때 함께 띄울수 있다.




Query 해보기

User정보와 회사정보를 가져오는 샘플

요청


{
 user(id: "23") {
   id
   firstName
   company {
     name
  }
}
}
결과


{
 "data": {
   "user": {
     "id": "23",
     "firstName": "ko",
     "company": {
       "name": "tomorrow"
    }
  }
}
}

Company정보와 users를 가져오는 샘플

요청


{
 company(id: "1") {
   id
   name
   description
   users {
     id
     firstName
     age
  }
}
}
결과

{
 "data": {
   "company": {
     "id": "1",
     "name": "tomorrow",
     "description": "111st",
     "users": [
      {
         "id": "23",
         "firstName": "ko",
         "age": 20
      },
      {
         "id": "40",
         "firstName": "lee",
         "age": 40
      },
      {
         "id": "44",
         "firstName": "ra",
         "age": 45
      }
    ]
  }
}
}

Mutation

변경작업(추가, 수정, 삭제)

Response Type에 따라서 Query를 원하는대로 데이타를 받을 수도 있다.

Mutation 사용시 장점.

  • 사실 로직적으로 내부적으로 변경하는 로직을 있는것 뿐 조회 Query와 구조적으로는 같다.

  • Mutation query를 호출하더라도 해당 Mutation의 Return Type에 따라서 Response를 자유롭게 변경 할 수 있다.



Mutation - User 추가


const mutation = new GraphQLObjectType({
 name: 'Mutation',
 fields: {
   addUser: {
     type: UserType,
     args: {
       firstName: {type: new GraphQLNonNull(GraphQLString)},
       age: {type: new GraphQLNonNull(GraphQLInt)}     },
     resolve(parentValue, {firstName, age}) {
       return axios.post(`${SERVER_DOMAIN}/users`, {firstName, age})
        .then(res => res.data);
    }
  },
   deleteUser: {},
   editUser: {}
}
})

mutation을 이용한 유저 추가 및 생성 정보 받기

요청


mutation {
 addUser( firstName: "gu", age: 40 ) {
   id
   firstName
   age
}
}
결과


{
 "data": {
   "addUser": {
     "id": "SJ0Wox-i-",
     "firstName": "gu",
     "age": 40
  }
}
}


Mutation - User 삭제


const mutation = new GraphQLObjectType({
 name: 'Mutation',
 fields: {
   addUser: {},
   deleteUser: {
     type: UserType,
     args: {
       id: {type: new GraphQLNonNull(GraphQLString)}
    },
     resolve(parentValue, {id}) {
       return axios.delete(`${SERVER_DOMAIN}/users/${id}`)
        .then(res => res.data);
    }
  },
   editUser: {}
}
})

mutation을 이용한 유저 삭제

요청


mutation {
deleteUser(id : "SJ0Wox-i-") {
  id
}
}
결과


{
 "data": {
   "deleteUser": {
     "id": null
  }
}
}


Mutation - User 수정


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

mutation을 이용한 유저 수정(Patch)

요청

mutation {
 editUser( id: "44", firstName: "ra", age: 45) {
   id,
   firstName,
   age,
   company {
     id,
     name,
     description
  }
}
}
결과


{
 "data": {
   "editUser": {
     "id": "44",
     "firstName": "ra",
     "age": 45,
     "company": {
       "id": "1",
       "name": "tomorrow",
       "description": "111st"
    }
  }
}
}

상황극

GraphQL을 안쓸때 상황.

  • login.json에 userName이랑 image좀 추가해주세요.

  • NoticeList.json에서는 id, title, 작성자만 필요하니 나머지는 빼주세요.

  • 몇일있다가 수정일은 추가해주세요.

  • 이 데이타는 결과에 따라서 추가 Request가 필요하므로 서버에서 한번에 말아주세요.

  • 하위 호환 때문에 API 버전 변경이 필요해요.

GraphQL을 쓰게되면.

  • Root Query에 머하나 추가해주세요.

  • A 랑 B랑 릴레이션 맺어주심 안돼요?

  • mutation 추가해주세요.

  • 빨리 끝내고 커피 한 잔 하러 가시죠.(추정)

FrontEnd Client 3총사

URL


'Javascript/node.js Coding' 카테고리의 다른 글

ES6+(EcmaScript2015+) 정리(ing)  (0) 2017.12.27
Mobx with angular 정리.  (0) 2017.12.05
Netflix Falcor Overview  (0) 2017.12.03
Posted by 다인,보리아빠
,

Falcor Overview

Introduce

Falcor는 효율적인 데이터 가져 오기를위한 JavaScript 라이브러리.

GraphQL과 같이 One Fetch에 필요한 데이타만를 받고자 하는 것은 비슷하다.

또한 Facebook의 GraphQL Cache Framework 인 relay(+GraphQL)와 많이 비교된다.

Overfetch를 방지를 해주는 것도 비슷하다.


서론

falcor를 이야기 하자면 JSON Graph 를 이야기 하지 않을 수 없지만 우선 왜 이런 아키텍처가 나왔는지 생각해보자.

우선 NETFLIX 서비스를 생각해 보자.



앞선 이미지에서 3개 카테고리가 있을 때 one fetch에 중복을 제거하고 데이타를 받기 위해서는 어떻게 해야할까?

GraphQL을 사용한다면 아마도 One Fetch로 데이타를 받을 경우 중복 데이타(복제본)가 발생한다.

기본적으로 JSON은 근본적으로 Tree 구조이므로 원하는 데이타를 원하는 모양으로 받는데 문제는 없지만 중복은 어쩔수 없다.

그래서 Falcor가 JSON Graph를 통해 어떻게 이 문제를 풀어가는지 생각해보자.


Model

View와 DataSource(또는 HTTPDataSource)간에 중개자 역활을 수행한다.

  • 데이타 검색 기능(단일 값, JSON 데이타)

  • 이전 데이타에 대해서 캐싱

  • DataSource를 통해 검색된 JSON Graph 를 조회시 JSON으로 변환한다.

  • 여러개의 동시요청을 일괄 요청으로 변경하여 효율적인 네트워크 액세서 패턴을 제공한다.

  • 비동기 처리 및 개발 용이성(mock data)을 위해 데이타 조회시 Promise 반환 지원.

  • 캐싱 데이타와 아닌 데이타를 구분해서 아닌 데이타만 서버에 요청한다.(Realy와 같다.)

  • 기본적으로 GET방식 호출이므로 호출 API는 브라우저에서 캐싱된다.




Data Sources

DataSource : JSON Graph 통데이타를 구성해서 데이타로 사용할때.

HttpDataSource : 원격지(서버)의 데이타를 Model의 데이타로 사용할 때. 이때 모델 내에 캐싱데이타가 전부/일부라도 없으면 서버에 요청해서 받아와 캐싱한다.

  • get : DataSource를 통해 JSON 또는 단일값을 가져온다.

  • set : DataSource 데이타 변경

  • call : DataSource의 해당 path의 call에 해당되는 작업을 한다. Mutation 작업에 어울린다.


Router

Falcor 라우터는 DataSource 인터페이스 의 구현체로서 호출자의 PathSet 에 따라서 falcor 미들웨어에서 해당 데이타를 조회하고 구조에 맞게 리턴한다.

express의 app.get 또는 spring의 RequestMapping와 비슷한 개념이다.차이점에 한번의 fetch에 여러 pathSet이 있는 경우 여러개의 method와 match될 수 있다.

따라서 라우터 특정 Method에 매칭 기준을 PathSet값으로 되어 있다.

PathSet은 model"productList"seller" 와 같이 키 또는 인덱스의 조합이다.


JSON Graph

Falcor는 중복 데이타가 fetch되어 발생하는 낭비를 제거하기 위해 JSON Graph를 사용하고 있다.


기본적인 JSON Type

우선 JSON의 경우 데이타가 단순한 Tree 구조를 가지고 표현이 되며 중복데이타가 있으면 동일하게 표현된다.

그러나 실제 우리가 서비스를 할때는 이 단순한 JSON 객체로 서비스를 하게 된다.

Falcor를 사용하기 위해서는 JSON Graph와 JSON을 Type을 잘 이해하여 사용하여야 한다.


JSON 구조 및 접근 구조.

var model = {
   productList : [{
           id : 100,
        name : "생수",
      seller : {
          id : 10000,
            name : "물장수",
            like : false
      }
      },{
           id : 200,
        name : "맥스 커피",
      seller : {
          id : 10000,
            name : "물장수",
            like : false
}}]
}
/* 참조 방법 */
model["productList][0]["seller"]["name"] // 물장수
model["productList][0]["seller"]["like"] = true
//JSON은 단순 트리 구조로 위의 seller가 같더라도 하나의 값만 바뀐다..

JSON Graph

기본적으로 일반적으로 사용되는 JSON DataType에 레퍼런스을 추가하였다고 생각하면 된다.

Falcor Model에 의해 들어온 값들은 모두 Sentinels 이라는 JSON 객체로 변환된다.

Sentinels JSON 객체는 ref, atom, error 3가지 type으로 분류한다..


- Reference

가장 중요한 Type으로 이를 통해 중복 데이타 제거가 가능하다.

레퍼런스가 가능함에 따라서 Graph 구조의 데이타를 가질 수 있다.

linux의 Symbolic link와 같은 개념이다.


{
   $type: "ref", value: ["sellerById", 10000]
}
 /*
  ["sellerById", 10000]은 주소 값으로 데이타를 추출저장 할때는
  해당 위치에 데이타를 사용하게 된다.
*/

- Atom(원자)

Atom은 $type값이 atom인 Sentinels 객체이다.

데이타를 boxing하고, model에서 데이타를 추출할 때는 unboxing 된다. atom 으로 boxing되지 않는 array는 map으로 내부적으로 바뀌어 저장되게 되므로 데이타 종류에 따라서 사용하여야 한다.

내부적으로 아래와 같이 저장된다. 쪼개고 싶지 않은 데이타를 atom으로 사용하면 된다.


subtitles: ['en', 'fr']  // 실제 데이타
subtitles : { // JSON Graph 구조로 변환
 "0" : { $type: "atom", value : "en" },
 "1" : { $type: "atom", value : "fr"}
}
subtitlesAtom: $atom(['en', 'fr']) // $atom으로 실제 데이타
//JSON Graph
subtitlesAtom : { $type: "atom", value : ["en", "fr"] }

Atom 샘플

  var falcor = require('falcor');
 var model = new falcor.Model({cache: {
   titlesById: {
     "44": {
       name: "Die Hard",
       subtitles: ['en', 'fr']
       subtitlesAtom: { $type: "atom", value: ['en', 'fr'] },
      }
    }
}});

// 데이타를 항상 Promise 객체를 반환.(그래서 async,await 썼으니 참고)
 await model.getValue(['titlesById', 44, 'subtitlesAtom']);
 // ['en', 'fr']
 await model.getValue(['titlesById', 44, 'subtitles']);
 // undefined
 await model.getValue(['titlesById', 44, 'subtitles', 0]);
 //'en'

- Error

error 정보를 담고 있는 Sentinels 객체

라우터에서 데이타를 내려줄때 특정 Path에서 에러가 발생한 경우아래와 같이 error Type을 내려주게 된다. 다시한번 말하지만 Response의 전체가 Error가 되는 것이 아닌 특정 Path에 대해서만 Error가 내려간다.


{ $type: "error", value: "request time out" }

JSON Graph Data 샘플

  var $ref = falcor.Model.ref;
 var $atom = falcor.Model.atom;
 var model = new falcor.Model({
     cache: {
       productList: [{
           id: 100,
           name: "생수",
           lang: ["en", "ko"],
           seller: $ref("sellerById[10000]")
        },{
           id: 200,
           name: "맥스 커피",
           seller: $ref("sellerById[10000]"),
           lang :
      }],
       sellerById: {
         "10000": {
           id: 10000,
           name: "물장수",
           like: false
      }}}});

데이타 접근방식

데이타에 접근하기 위해서는 키배열방식과 pathSet방식 모두를 지원한다.

- 키 배열 방식의 데이타 접근.

await model.getValue('productList[0]["seller"]["like"]');
await model.getValue('sellerById["10000"]["like"]');
// 둘다 false

// 수정
await model.setValue('productList[0]["seller"]["like"]', true);

await model.getValue('productList[0]["seller"]["like"]');
// true

- PathSet 방식의 데이타 접근

/*
PathSet 배열 방식
["productList",{length:2},["name","id","seller"],["name","like"]]
["productList",{from:0,length:2},["name","id","seller"],["name","like"]]
["productList",{length:2},["name","id","seller"],["name","like"]]

PathSet 구문 문자열
'productList[0..1]["name", "id", "seller"]["name", "like"]
*/

//array index 가 0 부터 1까지.
await model.get(
 'productList[0..1]["name", "id", "seller"]["name", "like"]'
);

조회된 값은 모두 같다.

/*
{
  "json": {
      "productList": {
          "0": {
              "name": "생수",
              "id": 100,
              "seller": {
                  "name": "물장수",
                  "like": true
              }
          },
          "1": {
              "name": "맥스 커피",
              "id": 200,
              "seller": {
                  "name": "물장수",
                  "like": true
          }}}}}
*/

Falcor 어디다가 써야 할까?

모던 웹플리케이션인 SPA(Single Page Application)에 사용하면 캐시데이타를 품은 Model객체를 지속적으로 가져갈수 있으므로 효율이 좋습니다.

SPA가 아닌 웹서비스에서는 캐싱의 효과가 떨어지지만 브라우저 캐싱의 효과가 있다.

그 이유는 falcor Model을 통하여 HttpDataSource를 호출하는 경우 GET 데이타로 호출하게 되고 중복 호출의 경우에는 304 Not Modified로 브라우저 캐싱를 사용하게 된다.

GraphQL + relay와 비교를 많이 하는 만큼 비슷한 경우에 쓰면 되겠죠?


요약하면

  • Falcor는 정말 효율적 데이터 가져 오기를위한 JavaScript 라이브러리

  • JSON Graph를 통한 중복 데이타 제거 및 Overfetch 제거.

  • 데이타 캐싱, 이전 호출 데이타 브라우저 캐싱.

  • GraphQL의 장점에 Relay의 장점을 가지고 있다.


조사하면서 느낀점.

  • 샘플이 GraphQL에 비해 많지 않다.

  • 쓰는 사람이 많이 없다.

  • 아는 사람도 많이 없다.(Falcor를 처음 듣는 사람이 대부분이다.)

  • Falcor가 GraphQL + relay 조합보다 쉽다고 하는데 Falcor가 의외로 쉽지만은 않은 것 같다.

  • Router 작성이 의외로 어려운것 같다.

  • GraphQL처럼 Document(GraphiQL)를 볼 수 없는 것이 아쉽다.


URLS


'Javascript/node.js Coding' 카테고리의 다른 글

GraphQL Overview (graphql.js server code)  (0) 2018.01.05
ES6+(EcmaScript2015+) 정리(ing)  (0) 2017.12.27
Mobx with angular 정리.  (0) 2017.12.05
Posted by 다인,보리아빠
,

GraphQL Overview

세미나 자료 2017. 11. 24. 13:48

GraphQL Overview 과정.


Sample Code : https://github.com/gidong-lee/graphQL_exam






Posted by 다인,보리아빠
,

Netflix의 Falcor 라이브러리에 대해서 FE와 BE에 대한 설명.


GraphQL + relay와 많이 비교가 되며 JSON Graph 타입을 사용합니다.


글버전 바로가기(http://devcoding.tistory.com/28)


예제 코드 추가 : ‐> https://github.com/gidong‐lee/falcor‐exam 







Posted by 다인,보리아빠
,