API ๋ ผ๋ฆฌ์ ์ฐจ์ด์
GitHub์(๋) REST API์ GraphQL API๋ผ๋ ๋ ๊ฐ์ง API๋ฅผ ์ ๊ณตํฉ๋๋ค. GitHub์ API์ ๋ํ ์์ธํ ๋ด์ฉ์ GitHub์ REST API ๋ฐ GraphQL API ๋น๊ต์(๋ฅผ) ์ฐธ์กฐํ์ธ์.
REST์์ GraphQL๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ๋ ๊ฒ์ API ๋ ผ๋ฆฌ์ ์๋นํ ๋ณํ๋ฅผ ๋ํ๋ ๋๋ค. ์คํ์ผ๋ก์์ REST์ ์ฌ์์ผ๋ก์์ GraphQL ๊ฐ์ ์ฐจ์ด๋ก ์ธํด REST API ํธ์ถ์ ์ผ๋์ผ ๊ธฐ์ค์ผ๋ก GraphQL API ์ฟผ๋ฆฌ๋ก ๋ฐ๊พธ๋ ๊ฒ์ ์ด๋ ต๊ณ ์ข ์ข ๋ฐ๋์งํ์ง๋ ์์ต๋๋ค. ์๋์๋ ๋ง์ด๊ทธ๋ ์ด์ ์ ํน์ ์์ ๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
REST API์์ GraphQL API๋ก ์ฝ๋๋ฅผ ๋ง์ด๊ทธ๋ ์ด์ ํ๋ ค๋ฉด ๋ค์์ ์ํํฉ๋๋ค.
- GraphQL ์ฌ์ ๊ฒํ
- GitHub์ GraphQL ์คํค๋ง ๊ฒํ
- ํ์ฌ ๊ธฐ์กด ์ฝ๋๊ฐ GitHub REST API์ ์ํธ ์์ฉํ๋ ๋ฐฉ์ ๊ณ ๋ ค
- ์ ์ญ ๋ ธ๋ ID๋ฅผ ์ฌ์ฉํ์ฌ API ๋ฒ์ ๊ฐ ๊ฐ์ฒด ์ฐธ์กฐ
GraphQL์ ์ค์ํ ์ด์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋ค์์ ๊ฐ๊ฐ์ ์์ ์ ๋๋ค.
์์ : ํ์ํ ๋ฐ์ดํฐ๋ง ๊ฐ์ ธ์ค๊ธฐ
๋จ์ผ REST API ํธ์ถ์ ์กฐ์ง ๊ตฌ์ฑ์์ ๋ชฉ๋ก์ ๊ฒ์ํฉ๋๋ค.
curl -v https://api.github.com/orgs/:org/members
๊ตฌ์ฑ์ ์ด๋ฆ ๋ฐ ์๋ฐํ์ ๋ํ ๋งํฌ๋ง ๊ฒ์ํ๋ ๊ฒ์ด ๋ชฉํ์ธ ๊ฒฝ์ฐ REST ํ์ด๋ก๋์๋ ๊ณผ๋ํ ๋ฐ์ดํฐ๊ฐ ํฌํจ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ GraphQL ์ฟผ๋ฆฌ๋ ์ฌ์ฉ์๊ฐ ์ง์ ํ ํญ๋ชฉ๋ง ๋ฐํํฉ๋๋ค.
query {
organization(login:"github") {
membersWithRole(first: 100) {
edges {
node {
name
avatarUrl
}
}
}
}
}
๋์ด์ค๊ธฐ ์์ฒญ ๋ชฉ๋ก์ ๊ฒ์ํ๊ณ ๊ฐ ์์ฒญ์ด ๋ณํฉ ๊ฐ๋ฅํ์ง ํ์ธํ๋ ๋ ๋ค๋ฅธ ์์ ๋ฅผ ๊ณ ๋ คํฉ๋๋ค. REST API์ ๋ํ ํธ์ถ์ ๋์ด์ค๊ธฐ ์์ฒญ ๋ชฉ๋ก๊ณผ ํด๋น ์์ฝ ํํ์ ๊ฒ์ํฉ๋๋ค.
curl -v https://api.github.com/repos/:owner/:repo/pulls
๋์ด์ค๊ธฐ ์์ฒญ์ ๋ณํฉํ ์ ์๋์ง ํ์ธํ๋ ค๋ฉด ๊ฐ ๋์ด์ค๊ธฐ ์์ฒญ์ ์ธ๋ถ ํํ(ํฐ ํ์ด๋ก๋)์ ๋ํด ๊ฐ๋ณ์ ์ผ๋ก ๊ฒ์ํ๊ณ ํด๋น mergeable
ํน์ฑ์ด true์ธ์ง false์ธ์ง ํ์ธํด์ผ ํฉ๋๋ค.
curl -v https://api.github.com/repos/:owner/:repo/pulls/:number
GraphQL์ ์ฌ์ฉํ๋ฉด ๊ฐ ๋์ด์ค๊ธฐ ์์ฒญ์ ๋ํ number
๋ฐ mergeable
ํน์ฑ๋ง ๊ฒ์ํ ์ ์์ต๋๋ค.
query {
repository(owner:"octocat", name:"Hello-World") {
pullRequests(last: 10) {
edges {
node {
number
mergeable
}
}
}
}
}
์์ : ์ค์ฒฉ
์ค์ฒฉ๋ ํ๋๋ฅผ ์ฌ์ฉํ์ฌ ์ฟผ๋ฆฌํ๋ฉด ์ฌ๋ฌ REST ํธ์ถ์ ๋ ์ ์ ์์ GraphQL ์ฟผ๋ฆฌ๋ก ๋ฐ๊ฟ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด REST API๋ฅผ ์ฌ์ฉํ์ฌ ์ปค๋ฐ, ๋น ๊ฒํ ์ฃผ์, ๊ฒํ ์ ํจ๊ป ๋์ด์ค๊ธฐ ์์ฒญ์ ๊ฒ์ํ๋ ค๋ฉด ๋ค์ ๋ค ๊ฐ์ง ํธ์ถ์ด ํ์ํฉ๋๋ค.
curl -v https://api.github.com/repos/:owner/:repo/pulls/:number
curl -v https://api.github.com/repos/:owner/:repo/pulls/:number/commits
curl -v https://api.github.com/repos/:owner/:repo/issues/:number/comments
curl -v https://api.github.com/repos/:owner/:repo/pulls/:number/reviews
GraphQL API๋ฅผ ์ฌ์ฉํ๋ฉด, ์ค์ฒฉ๋ ํ๋๋ฅผ ์ฌ์ฉํ์ฌ ๋จ์ผ ์ฟผ๋ฆฌ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ํ ์ ์์ต๋๋ค.
{
repository(owner: "octocat", name: "Hello-World") {
pullRequest(number: 1) {
commits(first: 10) {
edges {
node {
commit {
oid
message
}
}
}
}
comments(first: 10) {
edges {
node {
body
author {
login
}
}
}
}
reviews(first: 10) {
edges {
node {
state
}
}
}
}
}
}
๋์ด์ค๊ธฐ ์์ฒญ ๋ฒํธ์ ๋ํ ๋ณ์๋ฅผ ๋์ฒดํ์ฌ ์ด ์ฟผ๋ฆฌ์ ์ฑ๋ฅ์ ํ์ฅํ ์๋ ์์ต๋๋ค.
์์ : ๊ฐ๋ ฅํ ์ ๋ ฅ
GraphQL ์คํค๋ง๋ ๊ฐ๋ ฅํ ํ์์ด๋ฏ๋ก ๋ฐ์ดํฐ ์ฒ๋ฆฌ๊ฐ ๋ ์์ ํฉ๋๋ค.
GraphQL ๋ณํ์ ์ฌ์ฉํ์ฌ ์ด์ ๋๋ ๋์ด์ค๊ธฐ ์์ฒญ์ ์ฃผ์์ ์ถ๊ฐํ๊ณ , ์ค์๋ก clientMutationId
์ ๊ฐ์ ๋ฌธ์์ด์ด ์๋๋ผ ์ ์๋ฅผ ์ง์ ํ๋ ์์ ๋ฅผ ๊ณ ๋ คํฉ๋๋ค.
mutation {
addComment(input:{clientMutationId: 1234, subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "Looks good to me!"}) {
clientMutationId
commentEdge {
node {
body
repository {
id
name
nameWithOwner
}
issue {
number
}
}
}
}
}
์ด ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ฉด ์์ ์ ๋ํ ์์๋๋ ํ์์ ์ง์ ํ๋ ์ค๋ฅ๊ฐ ๋ฐํ๋ฉ๋๋ค.
{
"data": null,
"errors": [
{
"message": "Argument 'input' on Field 'addComment' has an invalid value. Expected type 'AddCommentInput!'.",
"locations": [
{
"line": 3,
"column": 3
}
]
},
{
"message": "Argument 'clientMutationId' on InputObject 'AddCommentInput' has an invalid value. Expected type 'String'.",
"locations": [
{
"line": 3,
"column": 20
}
]
}
]
}
1234
๋ฅผ ๋ฐ์ดํ๋ก ๋ฌถ์ผ๋ฉด ๊ฐ์ด ์ ์์์ ๋ฌธ์์ด(์์๋๋ ํ์)๋ก ๋ณํ๋ฉ๋๋ค.
mutation {
addComment(input:{clientMutationId: "1234", subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "Looks good to me!"}) {
clientMutationId
commentEdge {
node {
body
repository {
id
name
nameWithOwner
}
issue {
number
}
}
}
}
}