SlideShare a Scribd company logo
1 of 77
Download to read offline
Hello, GraphQL!
2017.4.14 조민환
발표 목차
• GraphQL이란?
• GraphQL 도입으로 얻은 긍정적 효과
• 주의할 점
• 마무리
GraphQL?
Graph
Q
L
uery
anguage
Graph
Q
L
uery
anguage
Graph
Q
L
uery
anguage
Graph
Q
L
uery
anguage
Implementation
Community
GraphQL Schema
type User {

name: String
friendsCount: Int

friends(first: Int!): [User]

}
Default Scalar Types in GraphQL Schema
Int Float String Boolean
User-made Object Type
{
me {
name
friendsCount
}

}
Basic Query
type User {

name: String
friendsCount: Int

friends(first: Int!): [User]

}
{
me {
name
friendsCount
}

}
Basic Query
{

“data”: {
“me”: {
“name”: “Minhwan Cho”,
“friendsCount”: 2
}

}

}
type User {

name: String
friendsCount: Int

friends(first: Int!): [User]

}
{
me {
name
friends {

name
}
}

}
Basic Query
type User {

name: String
friendsCount: Int

friends(first: Int!): [User]

}
{
me {
name
friends {

name
}
}

}
Basic Query
{
"errors": [
{
"message": "must provide first"
}
]
}
type User {

name: String
friendsCount: Int

friends(first: Int!): [User]

}
{
me {
name
friends(first: 2) {

name
}
}

}
Basic Query
type User {

name: String
friendsCount: Int

friends(first: Int!): [User]

}
{
me {
name
friends(first: 2) {

name
}
}

}
Basic Query
type User {

name: String
friendsCount: Int

friends(first: Int!): [User]

}
{

“data”: {
“me”: {

“name”: “Minhwan Cho”,
“friends”: [

{ “name”: “Naru Han” },
{ “name”: “Woori Chae” }

]
}

}

}
{
me {
friends(first: 2) {

name
friendsCount
}
}

}
Basic Query
type User {

name: String
friendsCount: Int

friends(first: Int!): [User]

}
{
me {
friends(first: 2) {

name
friendsCount
}
}

}
Basic Query
type User {

name: String
friendsCount: Int

friends(first: Int!): [User]

} {

“data”: {
“me”: {
“friends”: [

{
“name”: “Naru Han”,
“friendsCount”: 204
},
{ 

“name”: “Woori Chae”,
“friendsCount”: 53

}

]
}

}

}
{ API }
{ API }
{ API }
클라이언트마다 각각 다른 요구사항을 

GraphQL 하나로 해결할 수 있다
GraphQL 장점!
GET : /home/news?platform=apple-watch
GET : /home/news?platform=ios10
GET : /home/news?platform=apple-watch
GET : /home/news?platform=ios10
GET : /home/news?platform=apple-watch GET : /home/news?platform=mobile-amp
GET : /home/news?platform=ios10
GET : /home/news?platform=apple-watch GET : /home/news?platform=mobile-amp
{

news(first: 1) {

summaryText

}

}
{

news(first: 1) {

summaryText

}

}
{

news(first: 5) {
title
postTime

thumbnailImage {
url

}

}

}
{

news(first: 1) {

summaryText

}

}
{

news(first: 5) {
title
postTime

thumbnailImage {
url

}

}

}
{

news(first: 5) {
title
postTime
writer {
fullName
role
}

thumbnailImage {
url

width

height

}

}

}
{

news(first: 1) {

summaryText

}

}
{

news(first: 5) {
title
postTime

thumbnailImage {
url

}

}

}
{

news(first: 5) {
title
postTime
writer {
fullName
role
}

thumbnailImage {
url

width

height

}

}

}
{

news(first: 1) {

summaryText

}

}
{

news(first: 5) {
title
postTime

thumbnailImage {
url

}

}

}
{

news(first: 5) {
title
postTime
writer {
fullName
role
}

thumbnailImage {
url

width

height

}

}

}
POST : /graphql
GraphiQL 시연
GraphQL 장점!
서버 코드 의존성이 API 문서에서
GraphQL 스키마로 이동한다.
GraphQL 장점!
REST API
“우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자
REST API
GET : /starships?pilotInfo=true서버 개발자
“우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자
REST API
GET : /starships?pilotInfo=true서버 개발자
UI 코드 수정…
클라 개발자
“우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자
REST API
GET : /starships?pilotInfo=true서버 개발자
UI 코드 수정…
클라 개발자
“우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자
‘어… 잠깐 웹에서는 고향 행성 이름까지 필요하다고 해서 구현해놨는데 모바일도?’서버 개발자
(가서 물어본다)
REST API
GET : /starships?pilotInfo=true서버 개발자
UI 코드 수정…
클라 개발자
“아니요~ 화면 작아서 고향 행성 이름은 표시 안하기로 했어요”클라 개발자
“우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자
‘어… 잠깐 웹에서는 고향 행성 이름까지 필요하다고 해서 구현해놨는데 모바일도?’서버 개발자
(가서 물어본다)
REST API
GET : /starships?pilotInfo=true서버 개발자
UI 코드 수정…
클라 개발자
“아니요~ 화면 작아서 고향 행성 이름은 표시 안하기로 했어요”클라 개발자
“우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자
‘어… 잠깐 웹에서는 고향 행성 이름까지 필요하다고 해서 구현해놨는데 모바일도?’서버 개발자
(가서 물어본다)
GET : /starships?
pilotInfo=true&homeworld=no
서버 개발자
REST API
GET : /starships?pilotInfo=true서버 개발자
UI 코드 수정…
클라 개발자
“아니요~ 화면 작아서 고향 행성 이름은 표시 안하기로 했어요”클라 개발자
“우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자
‘어… 잠깐 웹에서는 고향 행성 이름까지 필요하다고 해서 구현해놨는데 모바일도?’서버 개발자
(가서 물어본다)
GET : /starships?
pilotInfo=true&homeworld=no
서버 개발자 UI 코드 수정…
클라 개발자
REST API
GET : /starships?pilotInfo=true서버 개발자
UI 코드 수정…
클라 개발자
“아니요~ 화면 작아서 고향 행성 이름은 표시 안하기로 했어요”클라 개발자
“우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자
‘어… 잠깐 웹에서는 고향 행성 이름까지 필요하다고 해서 구현해놨는데 모바일도?’서버 개발자
(가서 물어본다)
GET : /starships?
pilotInfo=true&homeworld=no
서버 개발자
서버 개발자 (새로운 API parameter 문서 업데이트)
UI 코드 수정…
클라 개발자
REST API
GET : /starships?pilotInfo=true서버 개발자
UI 코드 수정…
클라 개발자
“아니요~ 화면 작아서 고향 행성 이름은 표시 안하기로 했어요”클라 개발자
“우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자
‘어… 잠깐 웹에서는 고향 행성 이름까지 필요하다고 해서 구현해놨는데 모바일도?’서버 개발자
(가서 물어본다)
서버 API 코드를 작성하는데 클라이언트에서 요청한 GET 요청 한 문장으로는 

어떠한 것도 결정할 수 없다.
input -> output 이 아니라 해당 URL을 때리면 사전에 개발자 끼리 약속한 결과를 주는 것 -> 

API 상세 의존성이 개발자 끼리의 대화, 문서에 있음
GET : /starships?
pilotInfo=true&homeworld=no
서버 개발자
서버 개발자 (새로운 API parameter 문서 업데이트)
UI 코드 수정…
클라 개발자
GraphQL API
“API에서 파일럿 정보가 필요하네?”클라 개발자
GraphQL API
“API에서 파일럿 정보가 필요하네?”클라 개발자
{

starship(id: $id) {

pilot(first: 3) {

name
profileImage
}

}

}
클라 개발자
GraphQL API
“API에서 파일럿 정보가 필요하네?”클라 개발자
{

starship(id: $id) {

pilot(first: 3) {

name
profileImage
}

}

}
클라 개발자
UI 코드 수정클라 개발자
GraphQL API
“API에서 파일럿 정보가 필요하네?”클라 개발자
{

starship(id: $id) {

pilot(first: 3) {

name
profileImage
}

}

}
클라 개발자
UI 코드 수정클라 개발자
우주선 파일럿은 몇명을 가져와야하는지,

고향 행성정보는 필요한지 아닌지 그 누구한테도 

일일히 말할 필요 없다.



UI 디자이너와 클라이언트 개발자만 이야기 끝나면 된다
GraphQL API
“API에서 파일럿 정보가 필요하네?”클라 개발자
{

starship(id: $id) {

pilot(first: 3) {

name
profileImage
}

}

}
클라 개발자
UI 코드 수정클라 개발자
서버 코드는 모델의 Schema만 작성하면 된다
우주선 파일럿은 몇명을 가져와야하는지,

고향 행성정보는 필요한지 아닌지 그 누구한테도 

일일히 말할 필요 없다.



UI 디자이너와 클라이언트 개발자만 이야기 끝나면 된다
GraphQL API
“API에서 파일럿 정보가 필요하네?”클라 개발자
서버에서는 리퀘스트로 오는 쿼리문만 있으면 된다.

GET url parameter를 보고 무엇을 줘야할지 추측할 필요가 없다

외부의 스펙이나 약속이나 문서에 의존적이지 않은 코드를 작성할 수 있다.

클라이언트에서도 수시로 업데이트되는 UI를 구현하는데 허들이 낮아진다.
{

starship(id: $id) {

pilot(first: 3) {

name
profileImage
}

}

}
클라 개발자
UI 코드 수정클라 개발자
서버 코드는 모델의 Schema만 작성하면 된다
우주선 파일럿은 몇명을 가져와야하는지,

고향 행성정보는 필요한지 아닌지 그 누구한테도 

일일히 말할 필요 없다.



UI 디자이너와 클라이언트 개발자만 이야기 끝나면 된다
API 네트워크 요청에서 “N + 1 Problem” 을 방지
GraphQL 장점!
{
users(first: 20) {
id
name
age

…

}
}
GET : /users/Syojd1Apx
GET : /users/rJeqtkA6g
GET : /users/HJoFt1Rpl
..
.
GET : /users/B1PFYyAax
GET : /users?limit=20
GET : /users/CyljpJxCT
11
N
API 네트워크 요청에서 “N + 1 Problem” 을 방지
GraphQL 장점!
{
users(first: 20) {
id
name
age

…

}
}
GET : /users/Syojd1Apx
GET : /users/rJeqtkA6g
GET : /users/HJoFt1Rpl
..
.
GET : /users/B1PFYyAax
GET : /users?limit=20
GET : /users/CyljpJxCT
11
N
API 네트워크 요청에서 “N + 1 Problem” 을 방지
GraphQL 장점!
{
users(first: 20) {
id
name
age

…

}
}
GET : /users/Syojd1Apx
GET : /users/rJeqtkA6g
GET : /users/HJoFt1Rpl
..
.
GET : /users/B1PFYyAax
GET : /users?limit=20
진짜?
GET : /users/CyljpJxCT
11
N
GraphQL 주의할 점
데이타베이스 요청에서 “N + 1 Problem” 발생
GraphQL 주의할 점!
..
.
SELECT * from ‘users’;
{
users(first: 20) {
id
name
age

…

}
SELECT * from ‘users’ WHERE id = ‘Syojd1Apx’;
SELECT * from ‘users’ WHERE id = ‘rJeqtkA6g’;
SELECT * from ‘users’ WHERE id = ‘HJoFt1Rpl’;
SELECT * from ‘users’ WHERE id = ‘CyljpJxCT’;
SELECT * from ‘users’ WHERE id = ‘B1PFYyAax’;
1
N
지수적으로 차수가 심각하게 증가한다
{
me {
name

age

}

}
GraphQL 더 주의할 점!
SELECT name, age FROM ‘users’ WHERE id=$token.user.id;
Database SQL Call Count : 1
1
지수적으로 차수가 심각하게 증가한다
{
me {
name

age
friends(first: N) {
name

}

}

}
GraphQL 더 주의할 점!
SELECT name, age FROM ‘users’ WHERE id=$token.user.id;
SELECT name FROM ‘users’ WHERE id=…;
SELECT name FROM ‘users’ WHERE id=…;
SELECT name FROM ‘users’ WHERE id=…;
..
.
SELECT name FROM ‘users’ WHERE id=…;
N
1
Database SQL Call Count : 1 + N
{
me {
name

age
friends(first: N) {
name

friends(first: N) {

name

}

}

}

}
GraphQL 더 주의할 점!
SELECT name, age FROM ‘users’ WHERE id=$token.user.id;
Database SQL Call Count : 1 + N + N
SELECT name FROM ‘users’ WHERE id=…;
2
1
N
..
.
SELECT name FROM ‘users’ WHERE id=…;
SELECT name FROM ‘users’ WHERE id=…;
SELECT name FROM ‘users’ WHERE id=…;
N
SELECT name FROM ‘users’ WHERE id=…;
..
.
SELECT name FROM ‘users’ WHERE id=…;
SELECT name FROM ‘users’ WHERE id=…;
SELECT name FROM ‘users’ WHERE id=…;
N
..
.
지수적으로 차수가 심각하게 증가한다
실제 사례
{

cells {

id
name

.. .
tasks {

id

name

endDate

.. .

members {

name
tasks {

name

endDate

}

}

}

}

}
/cells 페이지에서는 모든 셀의 간략한 정보가 필요해!

어떤일을 하는지 필요할 것 같아.



그런데 각 일마다 어떤 사람이 참여하는지 알면 좋을것 같애



근데 사람을 표시하는 프로필사진을 hover하면 

그 사람이 어떤일 하는지도 알 수 있으니 좋을것 같군!
실제 사례
{

cells {

id
name

.. .
tasks {

id

name

endDate

.. .

members {

name
tasks {

name

endDate

}

}

}

}

}
20
5
10
5
/cells 페이지에서는 모든 셀의 간략한 정보가 필요해!

어떤일을 하는지 필요할 것 같아.



그런데 각 일마다 어떤 사람이 참여하는지 알면 좋을것 같애



근데 사람을 표시하는 프로필사진을 hover하면 

그 사람이 어떤일 하는지도 알 수 있으니 좋을것 같군!
실제 사례
{

cells {

id
name

.. .
tasks {

id

name

endDate

.. .

members {

name
tasks {

name

endDate

}

}

}

}

}
20
5
10
5
/cells 페이지에서는 모든 셀의 간략한 정보가 필요해!

어떤일을 하는지 필요할 것 같아.



그런데 각 일마다 어떤 사람이 참여하는지 알면 좋을것 같애



근데 사람을 표시하는 프로필사진을 hover하면 

그 사람이 어떤일 하는지도 알 수 있으니 좋을것 같군!
20 + 20x5 + 20x5x10 + 20x5x10x5 = 6120
실제 사례
{

cells {

id
name

.. .
tasks {

id

name

endDate

.. .

members {

name
tasks {

name

endDate

}

}

}

}

}
20
5
10
5
/cells 페이지에서는 모든 셀의 간략한 정보가 필요해!

어떤일을 하는지 필요할 것 같아.



그런데 각 일마다 어떤 사람이 참여하는지 알면 좋을것 같애



근데 사람을 표시하는 프로필사진을 hover하면 

그 사람이 어떤일 하는지도 알 수 있으니 좋을것 같군!
20 + 20x5 + 20x5x10 + 20x5x10x5 = 6120
서비스 런칭 1시간 30분만에 서버 다운
시도했던 퍼포먼스 최적화 방법
• GraphQL query에서 Leaf 자르기
• Batch call로 한번에 resolve 하기
Leaf 자르기
{

cells {

id
name

.. .
tasks {

id

name

endDate

.. .

members {

name
tasks {

name

endDate

}

}

}

}

}
20
5
10
5
사람 프로필에 hover하면 하고 있는 일 목록 나오는 것

hover할때 리퀘스트를 따로 보내서 lazy loading 한다
20 + 20x5 + 20x5x10 + 20x5x10x5 = 6120
Leaf 자르기
{

cells {

id
name

.. .
tasks {

id

name

endDate

.. .

members {

name
tasks {

name

endDate

}

}

}

}

}
20
5
10
5
사람 프로필에 hover하면 하고 있는 일 목록 나오는 것

hover할때 리퀘스트를 따로 보내서 lazy loading 한다
20 + 20x5 + 20x5x10 + 20x5x10x5 = 6120
Leaf 자르기
{

cells {

id
name

.. .
tasks {

id

name

endDate

.. .

members {

name
tasks {

name

endDate

}

}

}

}

}
20
5
10
5
사람 프로필에 hover하면 하고 있는 일 목록 나오는 것

hover할때 리퀘스트를 따로 보내서 lazy loading 한다
20 + 20x5 + 20x5x10 + 20x5x10x5 = 6120
Leaf 자르기
{

cells {

id
name

.. .
tasks {

id

name

endDate

.. .

members {

name
tasks {

name

endDate

}

}

}

}

}
20
5
10
5
사람 프로필에 hover하면 하고 있는 일 목록 나오는 것

hover할때 리퀘스트를 따로 보내서 lazy loading 한다
20 + 20x5 + 20x5x10 + 20x5x10x5 =
Leaf 자르기
{

cells {

id
name

.. .
tasks {

id

name

endDate

.. .

members {

name
tasks {

name

endDate

}

}

}

}

}
20
5
10
5
사람 프로필에 hover하면 하고 있는 일 목록 나오는 것

hover할때 리퀘스트를 따로 보내서 lazy loading 한다
20 + 20x5 + 20x5x10 + 20x5x10x5 = 1120
SELECT name FROM ‘users’ WHERE id=$token.user.id;
1 + N + N
2
1
N
..
.
SELECT name FROM ‘users’ WHERE id=…;
SELECT name FROM ‘users’ WHERE id=…;
SELECT name FROM ‘users’ WHERE id=…;
N
SELECT name FROM ‘users’ WHERE id=…;
..
.
SELECT name FROM ‘users’ WHERE id=…;
SELECT name FROM ‘users’ WHERE id=…;
SELECT name FROM ‘users’ WHERE id=…;
N
..
.
Batch Call with SQL “IN”
Database SQL Call Count :
{
me {

name
friends(first: N) {

name

friends(first: N) {

name

}

}

}

}
1
N
N
2
SELECT name FROM ‘users’ WHERE id=…;
1
Batch Call with SQL “IN”
Database SQL Call Count :
SELECT name FROM ‘users’ WHERE id IN (

'r1R9Cx06x',
'HklRqCgCal',
‘BJ-AqAeCal’,

…
'C1fRqAeApx',
'S1XC9AeCpg'

);
1
N
1 + 11 + 1
1 SELECT name FROM ‘users’ WHERE id IN (



);
N x N
SELECT name FROM ‘users’ WHERE id=$token.user.id;
{
me {

name
friends(first: N) {

name

friends(first: N) {

name

}

}

}

}
1
1
1
1 + N + N
2
1 + 11 + 1
SQL query 6120개 SQL query 3개
GraphQL 주의할 점!
Batch Call을 하여서 데이터베이스 최적화를 하자!
중간 중간 Relation Table 쿼리는 생략
마무리
• GraphQL API를 한번 만들어 놓으니 클라이언트 개
발할때 훨씬 수월하고 개발 만족도가 높았다.
• 일하는 방식이 많이 개선됨
• 다음번 프로젝트에서도 데이터간 관계가 일정 수준
이상으로 얽혀있으면 GraphQL 적극 도입할 생각
• 팀의 다른 개발자분들께서도 도입 효과를 기대하시
고 공감하신다면 도입을 조심스레 추천
감사합니다!

More Related Content

Similar to Hello, GraphQL!

Open source engineering - 0.1
Open source engineering - 0.1Open source engineering - 0.1
Open source engineering - 0.1YoungSu Son
 
Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)
Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)
Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)Esun Kim
 
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GDG Korea
 
응답하라 반응형웹 - 4. angular
응답하라 반응형웹 - 4. angular응답하라 반응형웹 - 4. angular
응답하라 반응형웹 - 4. angularredribbon1307
 
spring.io를 통해 배우는 spring 개발사례
spring.io를 통해 배우는 spring 개발사례spring.io를 통해 배우는 spring 개발사례
spring.io를 통해 배우는 spring 개발사례Daehwan Lee
 
About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10흥배 최
 
Python server-101
Python server-101Python server-101
Python server-101Huey Park
 
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기Jaeseung Ha
 
Python on Android
Python on AndroidPython on Android
Python on Android용 최
 
Node.js 현재와 미래
Node.js 현재와 미래Node.js 현재와 미래
Node.js 현재와 미래JeongHun Byeon
 
요즘 유행하는 AI 나도 해보자 (feat. CoreML)
요즘 유행하는 AI 나도 해보자 (feat. CoreML)요즘 유행하는 AI 나도 해보자 (feat. CoreML)
요즘 유행하는 AI 나도 해보자 (feat. CoreML)Chiwon Song
 
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기현철 조
 
Role Of Server In Ajax Korean
Role Of Server In Ajax KoreanRole Of Server In Ajax Korean
Role Of Server In Ajax KoreanTerry Cho
 
Front-end Development Process - 어디까지 개선할 수 있나
Front-end Development Process - 어디까지 개선할 수 있나Front-end Development Process - 어디까지 개선할 수 있나
Front-end Development Process - 어디까지 개선할 수 있나JeongHun Byeon
 
20201121 코드 삼분지계
20201121 코드 삼분지계20201121 코드 삼분지계
20201121 코드 삼분지계Chiwon Song
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs기동 이
 
Javascript 교육자료 pdf
Javascript 교육자료 pdfJavascript 교육자료 pdf
Javascript 교육자료 pdfHyosang Hong
 

Similar to Hello, GraphQL! (20)

Open source engineering - 0.1
Open source engineering - 0.1Open source engineering - 0.1
Open source engineering - 0.1
 
Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)
Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)
Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)
 
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
 
응답하라 반응형웹 - 4. angular
응답하라 반응형웹 - 4. angular응답하라 반응형웹 - 4. angular
응답하라 반응형웹 - 4. angular
 
spring.io를 통해 배우는 spring 개발사례
spring.io를 통해 배우는 spring 개발사례spring.io를 통해 배우는 spring 개발사례
spring.io를 통해 배우는 spring 개발사례
 
About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10
 
Python server-101
Python server-101Python server-101
Python server-101
 
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
 
Mongo db 최범균
Mongo db 최범균Mongo db 최범균
Mongo db 최범균
 
Python on Android
Python on AndroidPython on Android
Python on Android
 
Node.js 현재와 미래
Node.js 현재와 미래Node.js 현재와 미래
Node.js 현재와 미래
 
요즘 유행하는 AI 나도 해보자 (feat. CoreML)
요즘 유행하는 AI 나도 해보자 (feat. CoreML)요즘 유행하는 AI 나도 해보자 (feat. CoreML)
요즘 유행하는 AI 나도 해보자 (feat. CoreML)
 
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
 
Role Of Server In Ajax Korean
Role Of Server In Ajax KoreanRole Of Server In Ajax Korean
Role Of Server In Ajax Korean
 
Front-end Development Process - 어디까지 개선할 수 있나
Front-end Development Process - 어디까지 개선할 수 있나Front-end Development Process - 어디까지 개선할 수 있나
Front-end Development Process - 어디까지 개선할 수 있나
 
딥러닝이 바꾸는 애자일 테스팅
딥러닝이 바꾸는 애자일 테스팅딥러닝이 바꾸는 애자일 테스팅
딥러닝이 바꾸는 애자일 테스팅
 
20201121 코드 삼분지계
20201121 코드 삼분지계20201121 코드 삼분지계
20201121 코드 삼분지계
 
Modern android
Modern androidModern android
Modern android
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs
 
Javascript 교육자료 pdf
Javascript 교육자료 pdfJavascript 교육자료 pdf
Javascript 교육자료 pdf
 

Hello, GraphQL!

  • 2. 발표 목차 • GraphQL이란? • GraphQL 도입으로 얻은 긍정적 효과 • 주의할 점 • 마무리
  • 10. GraphQL Schema type User {
 name: String friendsCount: Int
 friends(first: Int!): [User]
 } Default Scalar Types in GraphQL Schema Int Float String Boolean User-made Object Type
  • 11. { me { name friendsCount }
 } Basic Query type User {
 name: String friendsCount: Int
 friends(first: Int!): [User]
 }
  • 12. { me { name friendsCount }
 } Basic Query {
 “data”: { “me”: { “name”: “Minhwan Cho”, “friendsCount”: 2 }
 }
 } type User {
 name: String friendsCount: Int
 friends(first: Int!): [User]
 }
  • 13. { me { name friends {
 name } }
 } Basic Query type User {
 name: String friendsCount: Int
 friends(first: Int!): [User]
 }
  • 14. { me { name friends {
 name } }
 } Basic Query { "errors": [ { "message": "must provide first" } ] } type User {
 name: String friendsCount: Int
 friends(first: Int!): [User]
 }
  • 15. { me { name friends(first: 2) {
 name } }
 } Basic Query type User {
 name: String friendsCount: Int
 friends(first: Int!): [User]
 }
  • 16. { me { name friends(first: 2) {
 name } }
 } Basic Query type User {
 name: String friendsCount: Int
 friends(first: Int!): [User]
 } {
 “data”: { “me”: {
 “name”: “Minhwan Cho”, “friends”: [
 { “name”: “Naru Han” }, { “name”: “Woori Chae” }
 ] }
 }
 }
  • 17. { me { friends(first: 2) {
 name friendsCount } }
 } Basic Query type User {
 name: String friendsCount: Int
 friends(first: Int!): [User]
 }
  • 18. { me { friends(first: 2) {
 name friendsCount } }
 } Basic Query type User {
 name: String friendsCount: Int
 friends(first: Int!): [User]
 } {
 “data”: { “me”: { “friends”: [
 { “name”: “Naru Han”, “friendsCount”: 204 }, { 
 “name”: “Woori Chae”, “friendsCount”: 53
 }
 ] }
 }
 }
  • 22. 클라이언트마다 각각 다른 요구사항을 
 GraphQL 하나로 해결할 수 있다 GraphQL 장점!
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 29. GET : /home/news?platform=ios10 GET : /home/news?platform=apple-watch
  • 30. GET : /home/news?platform=ios10 GET : /home/news?platform=apple-watch GET : /home/news?platform=mobile-amp
  • 31. GET : /home/news?platform=ios10 GET : /home/news?platform=apple-watch GET : /home/news?platform=mobile-amp
  • 32.
  • 34. {
 news(first: 1) {
 summaryText
 }
 } {
 news(first: 5) { title postTime
 thumbnailImage { url
 }
 }
 }
  • 35. {
 news(first: 1) {
 summaryText
 }
 } {
 news(first: 5) { title postTime
 thumbnailImage { url
 }
 }
 } {
 news(first: 5) { title postTime writer { fullName role }
 thumbnailImage { url
 width
 height
 }
 }
 }
  • 36. {
 news(first: 1) {
 summaryText
 }
 } {
 news(first: 5) { title postTime
 thumbnailImage { url
 }
 }
 } {
 news(first: 5) { title postTime writer { fullName role }
 thumbnailImage { url
 width
 height
 }
 }
 }
  • 37. {
 news(first: 1) {
 summaryText
 }
 } {
 news(first: 5) { title postTime
 thumbnailImage { url
 }
 }
 } {
 news(first: 5) { title postTime writer { fullName role }
 thumbnailImage { url
 width
 height
 }
 }
 } POST : /graphql
  • 39. 서버 코드 의존성이 API 문서에서 GraphQL 스키마로 이동한다. GraphQL 장점!
  • 40. REST API “우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자
  • 41. REST API GET : /starships?pilotInfo=true서버 개발자 “우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자
  • 42. REST API GET : /starships?pilotInfo=true서버 개발자 UI 코드 수정… 클라 개발자 “우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자
  • 43. REST API GET : /starships?pilotInfo=true서버 개발자 UI 코드 수정… 클라 개발자 “우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자 ‘어… 잠깐 웹에서는 고향 행성 이름까지 필요하다고 해서 구현해놨는데 모바일도?’서버 개발자 (가서 물어본다)
  • 44. REST API GET : /starships?pilotInfo=true서버 개발자 UI 코드 수정… 클라 개발자 “아니요~ 화면 작아서 고향 행성 이름은 표시 안하기로 했어요”클라 개발자 “우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자 ‘어… 잠깐 웹에서는 고향 행성 이름까지 필요하다고 해서 구현해놨는데 모바일도?’서버 개발자 (가서 물어본다)
  • 45. REST API GET : /starships?pilotInfo=true서버 개발자 UI 코드 수정… 클라 개발자 “아니요~ 화면 작아서 고향 행성 이름은 표시 안하기로 했어요”클라 개발자 “우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자 ‘어… 잠깐 웹에서는 고향 행성 이름까지 필요하다고 해서 구현해놨는데 모바일도?’서버 개발자 (가서 물어본다) GET : /starships? pilotInfo=true&homeworld=no 서버 개발자
  • 46. REST API GET : /starships?pilotInfo=true서버 개발자 UI 코드 수정… 클라 개발자 “아니요~ 화면 작아서 고향 행성 이름은 표시 안하기로 했어요”클라 개발자 “우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자 ‘어… 잠깐 웹에서는 고향 행성 이름까지 필요하다고 해서 구현해놨는데 모바일도?’서버 개발자 (가서 물어본다) GET : /starships? pilotInfo=true&homeworld=no 서버 개발자 UI 코드 수정… 클라 개발자
  • 47. REST API GET : /starships?pilotInfo=true서버 개발자 UI 코드 수정… 클라 개발자 “아니요~ 화면 작아서 고향 행성 이름은 표시 안하기로 했어요”클라 개발자 “우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자 ‘어… 잠깐 웹에서는 고향 행성 이름까지 필요하다고 해서 구현해놨는데 모바일도?’서버 개발자 (가서 물어본다) GET : /starships? pilotInfo=true&homeworld=no 서버 개발자 서버 개발자 (새로운 API parameter 문서 업데이트) UI 코드 수정… 클라 개발자
  • 48. REST API GET : /starships?pilotInfo=true서버 개발자 UI 코드 수정… 클라 개발자 “아니요~ 화면 작아서 고향 행성 이름은 표시 안하기로 했어요”클라 개발자 “우주선 API에서 파일럿 정보도 주실 수 있나요?”클라 개발자 ‘어… 잠깐 웹에서는 고향 행성 이름까지 필요하다고 해서 구현해놨는데 모바일도?’서버 개발자 (가서 물어본다) 서버 API 코드를 작성하는데 클라이언트에서 요청한 GET 요청 한 문장으로는 
 어떠한 것도 결정할 수 없다. input -> output 이 아니라 해당 URL을 때리면 사전에 개발자 끼리 약속한 결과를 주는 것 -> 
 API 상세 의존성이 개발자 끼리의 대화, 문서에 있음 GET : /starships? pilotInfo=true&homeworld=no 서버 개발자 서버 개발자 (새로운 API parameter 문서 업데이트) UI 코드 수정… 클라 개발자
  • 49. GraphQL API “API에서 파일럿 정보가 필요하네?”클라 개발자
  • 50. GraphQL API “API에서 파일럿 정보가 필요하네?”클라 개발자 {
 starship(id: $id) {
 pilot(first: 3) {
 name profileImage }
 }
 } 클라 개발자
  • 51. GraphQL API “API에서 파일럿 정보가 필요하네?”클라 개발자 {
 starship(id: $id) {
 pilot(first: 3) {
 name profileImage }
 }
 } 클라 개발자 UI 코드 수정클라 개발자
  • 52. GraphQL API “API에서 파일럿 정보가 필요하네?”클라 개발자 {
 starship(id: $id) {
 pilot(first: 3) {
 name profileImage }
 }
 } 클라 개발자 UI 코드 수정클라 개발자 우주선 파일럿은 몇명을 가져와야하는지,
 고향 행성정보는 필요한지 아닌지 그 누구한테도 
 일일히 말할 필요 없다.
 
 UI 디자이너와 클라이언트 개발자만 이야기 끝나면 된다
  • 53. GraphQL API “API에서 파일럿 정보가 필요하네?”클라 개발자 {
 starship(id: $id) {
 pilot(first: 3) {
 name profileImage }
 }
 } 클라 개발자 UI 코드 수정클라 개발자 서버 코드는 모델의 Schema만 작성하면 된다 우주선 파일럿은 몇명을 가져와야하는지,
 고향 행성정보는 필요한지 아닌지 그 누구한테도 
 일일히 말할 필요 없다.
 
 UI 디자이너와 클라이언트 개발자만 이야기 끝나면 된다
  • 54. GraphQL API “API에서 파일럿 정보가 필요하네?”클라 개발자 서버에서는 리퀘스트로 오는 쿼리문만 있으면 된다.
 GET url parameter를 보고 무엇을 줘야할지 추측할 필요가 없다
 외부의 스펙이나 약속이나 문서에 의존적이지 않은 코드를 작성할 수 있다.
 클라이언트에서도 수시로 업데이트되는 UI를 구현하는데 허들이 낮아진다. {
 starship(id: $id) {
 pilot(first: 3) {
 name profileImage }
 }
 } 클라 개발자 UI 코드 수정클라 개발자 서버 코드는 모델의 Schema만 작성하면 된다 우주선 파일럿은 몇명을 가져와야하는지,
 고향 행성정보는 필요한지 아닌지 그 누구한테도 
 일일히 말할 필요 없다.
 
 UI 디자이너와 클라이언트 개발자만 이야기 끝나면 된다
  • 55. API 네트워크 요청에서 “N + 1 Problem” 을 방지 GraphQL 장점! { users(first: 20) { id name age
 …
 } } GET : /users/Syojd1Apx GET : /users/rJeqtkA6g GET : /users/HJoFt1Rpl .. . GET : /users/B1PFYyAax GET : /users?limit=20 GET : /users/CyljpJxCT 11 N
  • 56. API 네트워크 요청에서 “N + 1 Problem” 을 방지 GraphQL 장점! { users(first: 20) { id name age
 …
 } } GET : /users/Syojd1Apx GET : /users/rJeqtkA6g GET : /users/HJoFt1Rpl .. . GET : /users/B1PFYyAax GET : /users?limit=20 GET : /users/CyljpJxCT 11 N
  • 57. API 네트워크 요청에서 “N + 1 Problem” 을 방지 GraphQL 장점! { users(first: 20) { id name age
 …
 } } GET : /users/Syojd1Apx GET : /users/rJeqtkA6g GET : /users/HJoFt1Rpl .. . GET : /users/B1PFYyAax GET : /users?limit=20 진짜? GET : /users/CyljpJxCT 11 N
  • 59. 데이타베이스 요청에서 “N + 1 Problem” 발생 GraphQL 주의할 점! .. . SELECT * from ‘users’; { users(first: 20) { id name age
 …
 } SELECT * from ‘users’ WHERE id = ‘Syojd1Apx’; SELECT * from ‘users’ WHERE id = ‘rJeqtkA6g’; SELECT * from ‘users’ WHERE id = ‘HJoFt1Rpl’; SELECT * from ‘users’ WHERE id = ‘CyljpJxCT’; SELECT * from ‘users’ WHERE id = ‘B1PFYyAax’; 1 N
  • 60. 지수적으로 차수가 심각하게 증가한다 { me { name
 age
 }
 } GraphQL 더 주의할 점! SELECT name, age FROM ‘users’ WHERE id=$token.user.id; Database SQL Call Count : 1 1
  • 61. 지수적으로 차수가 심각하게 증가한다 { me { name
 age friends(first: N) { name
 }
 }
 } GraphQL 더 주의할 점! SELECT name, age FROM ‘users’ WHERE id=$token.user.id; SELECT name FROM ‘users’ WHERE id=…; SELECT name FROM ‘users’ WHERE id=…; SELECT name FROM ‘users’ WHERE id=…; .. . SELECT name FROM ‘users’ WHERE id=…; N 1 Database SQL Call Count : 1 + N
  • 62. { me { name
 age friends(first: N) { name
 friends(first: N) {
 name
 }
 }
 }
 } GraphQL 더 주의할 점! SELECT name, age FROM ‘users’ WHERE id=$token.user.id; Database SQL Call Count : 1 + N + N SELECT name FROM ‘users’ WHERE id=…; 2 1 N .. . SELECT name FROM ‘users’ WHERE id=…; SELECT name FROM ‘users’ WHERE id=…; SELECT name FROM ‘users’ WHERE id=…; N SELECT name FROM ‘users’ WHERE id=…; .. . SELECT name FROM ‘users’ WHERE id=…; SELECT name FROM ‘users’ WHERE id=…; SELECT name FROM ‘users’ WHERE id=…; N .. . 지수적으로 차수가 심각하게 증가한다
  • 63. 실제 사례 {
 cells {
 id name
 .. . tasks {
 id
 name
 endDate
 .. .
 members {
 name tasks {
 name
 endDate
 }
 }
 }
 }
 } /cells 페이지에서는 모든 셀의 간략한 정보가 필요해!
 어떤일을 하는지 필요할 것 같아.
 
 그런데 각 일마다 어떤 사람이 참여하는지 알면 좋을것 같애
 
 근데 사람을 표시하는 프로필사진을 hover하면 
 그 사람이 어떤일 하는지도 알 수 있으니 좋을것 같군!
  • 64. 실제 사례 {
 cells {
 id name
 .. . tasks {
 id
 name
 endDate
 .. .
 members {
 name tasks {
 name
 endDate
 }
 }
 }
 }
 } 20 5 10 5 /cells 페이지에서는 모든 셀의 간략한 정보가 필요해!
 어떤일을 하는지 필요할 것 같아.
 
 그런데 각 일마다 어떤 사람이 참여하는지 알면 좋을것 같애
 
 근데 사람을 표시하는 프로필사진을 hover하면 
 그 사람이 어떤일 하는지도 알 수 있으니 좋을것 같군!
  • 65. 실제 사례 {
 cells {
 id name
 .. . tasks {
 id
 name
 endDate
 .. .
 members {
 name tasks {
 name
 endDate
 }
 }
 }
 }
 } 20 5 10 5 /cells 페이지에서는 모든 셀의 간략한 정보가 필요해!
 어떤일을 하는지 필요할 것 같아.
 
 그런데 각 일마다 어떤 사람이 참여하는지 알면 좋을것 같애
 
 근데 사람을 표시하는 프로필사진을 hover하면 
 그 사람이 어떤일 하는지도 알 수 있으니 좋을것 같군! 20 + 20x5 + 20x5x10 + 20x5x10x5 = 6120
  • 66. 실제 사례 {
 cells {
 id name
 .. . tasks {
 id
 name
 endDate
 .. .
 members {
 name tasks {
 name
 endDate
 }
 }
 }
 }
 } 20 5 10 5 /cells 페이지에서는 모든 셀의 간략한 정보가 필요해!
 어떤일을 하는지 필요할 것 같아.
 
 그런데 각 일마다 어떤 사람이 참여하는지 알면 좋을것 같애
 
 근데 사람을 표시하는 프로필사진을 hover하면 
 그 사람이 어떤일 하는지도 알 수 있으니 좋을것 같군! 20 + 20x5 + 20x5x10 + 20x5x10x5 = 6120 서비스 런칭 1시간 30분만에 서버 다운
  • 67. 시도했던 퍼포먼스 최적화 방법 • GraphQL query에서 Leaf 자르기 • Batch call로 한번에 resolve 하기
  • 68. Leaf 자르기 {
 cells {
 id name
 .. . tasks {
 id
 name
 endDate
 .. .
 members {
 name tasks {
 name
 endDate
 }
 }
 }
 }
 } 20 5 10 5 사람 프로필에 hover하면 하고 있는 일 목록 나오는 것
 hover할때 리퀘스트를 따로 보내서 lazy loading 한다 20 + 20x5 + 20x5x10 + 20x5x10x5 = 6120
  • 69. Leaf 자르기 {
 cells {
 id name
 .. . tasks {
 id
 name
 endDate
 .. .
 members {
 name tasks {
 name
 endDate
 }
 }
 }
 }
 } 20 5 10 5 사람 프로필에 hover하면 하고 있는 일 목록 나오는 것
 hover할때 리퀘스트를 따로 보내서 lazy loading 한다 20 + 20x5 + 20x5x10 + 20x5x10x5 = 6120
  • 70. Leaf 자르기 {
 cells {
 id name
 .. . tasks {
 id
 name
 endDate
 .. .
 members {
 name tasks {
 name
 endDate
 }
 }
 }
 }
 } 20 5 10 5 사람 프로필에 hover하면 하고 있는 일 목록 나오는 것
 hover할때 리퀘스트를 따로 보내서 lazy loading 한다 20 + 20x5 + 20x5x10 + 20x5x10x5 = 6120
  • 71. Leaf 자르기 {
 cells {
 id name
 .. . tasks {
 id
 name
 endDate
 .. .
 members {
 name tasks {
 name
 endDate
 }
 }
 }
 }
 } 20 5 10 5 사람 프로필에 hover하면 하고 있는 일 목록 나오는 것
 hover할때 리퀘스트를 따로 보내서 lazy loading 한다 20 + 20x5 + 20x5x10 + 20x5x10x5 =
  • 72. Leaf 자르기 {
 cells {
 id name
 .. . tasks {
 id
 name
 endDate
 .. .
 members {
 name tasks {
 name
 endDate
 }
 }
 }
 }
 } 20 5 10 5 사람 프로필에 hover하면 하고 있는 일 목록 나오는 것
 hover할때 리퀘스트를 따로 보내서 lazy loading 한다 20 + 20x5 + 20x5x10 + 20x5x10x5 = 1120
  • 73. SELECT name FROM ‘users’ WHERE id=$token.user.id; 1 + N + N 2 1 N .. . SELECT name FROM ‘users’ WHERE id=…; SELECT name FROM ‘users’ WHERE id=…; SELECT name FROM ‘users’ WHERE id=…; N SELECT name FROM ‘users’ WHERE id=…; .. . SELECT name FROM ‘users’ WHERE id=…; SELECT name FROM ‘users’ WHERE id=…; SELECT name FROM ‘users’ WHERE id=…; N .. . Batch Call with SQL “IN” Database SQL Call Count : { me {
 name friends(first: N) {
 name
 friends(first: N) {
 name
 }
 }
 }
 } 1 N N 2 SELECT name FROM ‘users’ WHERE id=…;
  • 74. 1 Batch Call with SQL “IN” Database SQL Call Count : SELECT name FROM ‘users’ WHERE id IN (
 'r1R9Cx06x', 'HklRqCgCal', ‘BJ-AqAeCal’,
 … 'C1fRqAeApx', 'S1XC9AeCpg'
 ); 1 N 1 + 11 + 1 1 SELECT name FROM ‘users’ WHERE id IN (
 
 ); N x N SELECT name FROM ‘users’ WHERE id=$token.user.id; { me {
 name friends(first: N) {
 name
 friends(first: N) {
 name
 }
 }
 }
 } 1 1 1
  • 75. 1 + N + N 2 1 + 11 + 1 SQL query 6120개 SQL query 3개 GraphQL 주의할 점! Batch Call을 하여서 데이터베이스 최적화를 하자! 중간 중간 Relation Table 쿼리는 생략
  • 76. 마무리 • GraphQL API를 한번 만들어 놓으니 클라이언트 개 발할때 훨씬 수월하고 개발 만족도가 높았다. • 일하는 방식이 많이 개선됨 • 다음번 프로젝트에서도 데이터간 관계가 일정 수준 이상으로 얽혀있으면 GraphQL 적극 도입할 생각 • 팀의 다른 개발자분들께서도 도입 효과를 기대하시 고 공감하신다면 도입을 조심스레 추천