Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Hello, GraphQL!

430 views

Published on

9XD X Devsisters 발표 자료

Published in: Software
  • Be the first to comment

Hello, GraphQL!

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

×