npm install @octokit/graphql
import { graphql } from "@octokit/graphql";
Settings > Developer settings > Personal access tokens
- Generate new token으로 토큰 발급
.env
REACT_APP_GHP_TOKEN=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
.env
파일은 수정 후에 반드시npm run start
를 껐다가 새로 해야 한다
App.js
function App() { const ghpToken = process.env.REACT_APP_GHP_TOKEN;
repository
, viewer
)와 그 안에 들어갈 수 있는 Field들, 인수(onwer
, name
, first
)Github GraphQL API 문서 > 참조 > 쿼리
- 요청할 수 있는 쿼리(
repository
,viewer
등) 목록이 나와있음Arguments
항목 : 해당 쿼리 요청할 때 인자로 들어갈 수 있는 것들
Type
항목 (Repository
또는User!
) 클릭하면 해당 쿼리 안에 들어갈 수 있는 Field 목록으로 이동 (또는 GraphQL API 문서 > 참조 > Object)
Github GraphQL API 문서 > 참조 > Object
- 해당 타입 안에 들어갈 수 있는 Fields 목록(과 그 Field의 인자(Argument))이 나와있다.
// 쿼리 요청 함수 async function getRepository() { const { repository } = await graphql( ` { repository(owner: "codestates-seb", name: "agora-states-fe") { discussions(first: 10) { edges { node { title url author { resourcePath } } } } } } `, { headers: { authorization: `token ${ghpToken}`, }, } ); return repository; } // 첫 렌더링 시 데이터 가져오기 useEffect(() => { getRepository().then((res) => { setData(res.discussions.edges); console.log(res); setIsLoading(false); }); }, []);
응답(res) 들어오는 형태
오퍼레이션 타입과 오퍼레이션 네임 작성
- 오퍼레이션 타입 :
query
- 오퍼레이션 네임 :
recentRepos
(👉🏽 임의로 지을 수 있음)
쿼리 : repository
, viewer
(2개)
인자들은 변수 이용
필드(인자) {...}
: 해당 필드
중 해당 인자(값)
에 부합하는 것만 가지고 오겠다는 의미... async function getRepository() { const { repository, viewer } = await graphql({ // 각 쿼리의 리턴값 각각 받아옴 headers: { authorization: `token ${ghpToken}`, }, owner: 'codestates-seb', name: 'agora-states-fe', num: 10, query: `query recentRepos($owner: String!, $name: String!, $num: Int!) { repository(name: $name, owner: $owner) { discussions(first: $num) { edges { node { category { name } author { login avatarUrl } createdAt title id url answer { author { login avatarUrl } bodyHTML createdAt id } } } } }, viewer { login avatarUrl } }`, }); return { repository, viewer }; } useEffect(() => { getRepository().then((res) => { setData(res.repository.discussions.edges); console.log(res); // res 어떻게 들어오는지 찍어보기 console.log(res.viewer); setIsLoading(false); }); }, []);
응답(res) 들어오는 형태
import { graphql } from '@octokit/graphql'; import { useState, useEffect } from 'react'; function App() { const [data, setData] = useState(); const [isLoading, setIsLoading] = useState(true); const ghpToken = process.env.REACT_APP_GHP_TOKEN; console.log(ghpToken); async function getRepository() { const { repository } = await graphql( ` { repository(owner: "codestates-seb", name: "agora-states-fe") { discussions(first: 10) { edges { node { title url author { resourcePath } } } } } } `, { headers: { authorization: `token ${ghpToken}`, }, } ); return repository; } useEffect(() => { getRepository().then((res) => { setData(res.discussions.edges); console.log(res.discussions.edges); setIsLoading(false); }); }, []); return ( <div className="App"> {isLoading ? 'Loading...' : data.map((el, index) => { return ( <li key={index}> <a href={el.node.url}>{el.node.title}</a> <span>{el.node.author.resourcePath}</span> </li> ); })} </div> ); } export default App;
import { graphql } from '@octokit/graphql'; import { useState, useEffect } from 'react'; function App() { const [data, setData] = useState(); const [isLoading, setIsLoading] = useState(true); const ghpToken = process.env.REACT_APP_GHP_TOKEN; console.log(ghpToken); async function getRepository() { const { repository, viewer } = await graphql({ headers: { authorization: `token ${ghpToken}`, }, owner: 'codestates-seb', name: 'agora-states-fe', num: 10, query: `query repository($owner: String!, $name: String!, $num: Int!) { repository(name: $name, owner: $owner) { discussions(first: $num) { edges { node { category { name } author { login avatarUrl } createdAt title id url answer { author { login avatarUrl } bodyHTML createdAt id } } } } }, viewer { login avatarUrl } }`, }); return { repository, viewer }; } useEffect(() => { getRepository().then((res) => { setData(res.repository.discussions.edges); console.log(res); console.log(res.viewer); setIsLoading(false); }); }, []); return ( <div className="App"> {isLoading ? 'Loading...' : data.map((el, index) => { return ( <li key={index}> <a href={el.node.url}>{el.node.title}</a> <span>{el.node.author.resourcePath}</span> </li> ); })} </div> ); } export default App;