일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Next.js
- UI
- Til
- useState
- superstarjypnation
- web
- html
- 백준
- level1
- 프로그래머스
- 해시테이블
- 자바스크립트
- 생활코딩
- vercel
- 코드스테이츠
- 카카오
- 자료구조
- UX
- 큐
- mysemester
- CSS
- React
- javascript
- 스택
- 운영체제
- 30daysdowoonchallenge
- 프로토타입
- 회고
- REST_API
- redux
- Today
- Total
데굴데굴
TIL: 2022-12-01 본문
⚙️ 오늘 배운 주제
GraphQL
🐹 오늘의 기분
벌써 한 해의 마지막 달이 다가왔다. 계속 같은 말만 하는 것 같지만..ㅋㅋ 시간 정말 빠르다!! 다다음주에 섹션 4가 끝나면 진짜 이제 프로젝트다... 미쳤다 정말... 😱
오늘은 graphql을 배웠다. 주말에 유튜브에서 어쩌다가 관련 영상을 보게 되어서 대충 어떤 식으로 데이터를 받아오는지는 알고 있던 상태였다. 근데 이제 코드로는 어떻게 쓰는지 전혀 몰랐던... octokit을 이용해서 github에서 제공하는 graphQL api를 받아오는 연습을 했는데 처음에는 쿼리 받아오는 코드를 리액트 앱에 어떻게 적용시켜야할지 도저히 모르겠어서 많이 헤맸다. 구글링해가면서 겨우 마무리했다. 아무래도 낯설다보니 마냥 쉽다고는 할 수 없었다. 그나마 제출이 없는 과제라 약간 부담을 덜 수 있었다.
🗝 키워드
graphql, tree, graph, query, mutation, schema, operation name, field, resolver
🗣 스스로에게 설명
페이스북에서 개발한 쿼리 언어
Graph + Query Language
API를 위한 쿼리 언어
모든 데이터가 그래프 형태로 연결되어 있다고 전제
클라이언트 요청에 따라 유연하게 트리구조의 JSON 데이터를 응답으로 전송한다.
고정된 자원이 아니라는 점에서 이점을 갖는다.
GraphQL로 트리 추출
비순환 그래프
http로 API 서버에 요청을 보내고 응답을 JSON 형태로 받는다
resolver 함수로 필드의 데이터 조회 가능
GraphQL은 조회 대상 schema가 유효한지 검사한다
REST API의 한계
- Overfetch: 필요없는 데이터까지 제공함.
- Underfetch: 필요한 요청을 모두 확보하기 위해 추가적인 요청 필요 (각각의 엔드포인트에 요청을 보내야 한다)
- 데이터의 형태를 클라이언트가 직접 결정할 수 없음. 필요한 경우 수정을 거쳐야 함
GraphQL의 장단점
GraphQL에서는 필요한 데이터의 크기와 형태는 모두 클라이언트가 결정한다.
Schema가 Resource를 나타내고 Query, Mutation이 작업의 유형을 나타냄.
한 번의 요청에서 여러 리소스에 접근 가능
query, mutation을 resolver 함수로 전달해서 요청에 응답
클라이언트 구조 변경에도 지장이 없음. 요구사항만 쿼리에 잘 작성해주면 된다
단점
학습하는데 시간이 필요함
캐싱이 REST보다 훨씬 복잡하다
고정된 요청과 응답만 필요할 경우에는 Query로 인해 요청의 크기가 RESTful API의 경우보다 더 커진다
query로 원하는 데이터 요청, mutation으로 저장된 데이터 수정
구독 개념으로 실시간 업데이트 구현 가능
과제
octokit을 이용해 아고라스테이츠의 discussions 목록을 불러오는 것이 최소 요구 사항이었다.
과제 전에 https://docs.github.com/en/graphql/overview/explorer 여기서 여러 필드들을 눌러보면서 이것저것 받아오는 연습을 미리 해보았다.
쿼리 작성은 octokit 깃헙 레포지토리 https://github.com/octokit/graphql.js/ 를 참고하였다.
graphql 요청은 비동기로 이루어지기 때문에 async/await을 이용해야 했다.
이 때문에 요청받는 코드는 getData라는 async 함수로 감싸주었다. (이 함수를 아예 다른 파일로 빼서 import해올 수도 있다.)
받아온 데이터와 로딩 여부를 나타내는 상태를 선언해놓은 후 useEffect로 getData 함수를 호출한 후에 상태 변경 함수로 각각의 상태를 업데이트해주었다.
로딩 여부는 굳이 필요한가? 싶을 수 있지만 이게 없으면 return문에서 데이터를 map으로 렌더링할 때 차마 데이터가 다 오지 않은 상태에서 렌더링을 시도할 수 있기 때문에 에러가 날 수 있다. (내가 이렇게 생각했어서 계속 삽질했었다)
그래서 삼항연산자로 loading이 false일 때만 받아온 데이터가 화면에 렌더링되도록 짜주는 것이다.
function App () {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const getData = async () => {
const graphqlWithAuth = graphql.defaults({
headers: {
authorization: `token `발급받은 토큰 번호``,
},
});
const { repository } = await graphqlWithAuth(
`
{
repository(name: "agora-states-fe", owner: "codestates-seb") {
discussions(first: 10) {
edges {
node {
id
author {
avatarUrl
login
}
createdAt
title
}
}
}
}
}
`
);
return repository;
};
useEffect(() => {
getData().then((res) => {
setData(res.discussions.edges);
setIsLoading(false);
});
}, []);
return (
<div className="App">
<h1>agora states graphql로 받아오기</h1>
{isLoading ? (
<div>loading...</div>
) : (
data.map((el, index) => {
return (
<li key={index}>
<div>{el.node.title}</div>
</li>
);
})
)}
</div>
);
}
일단 질문 제목만 간단하게 렌더링해보았는데 npm run start로 앱을 실행해보면 이렇게 나온다
이거 활용해서 전에 만들었던 아고라스테이츠 프로젝트도 더미데이터 말고 실제 데이터를 받아오도록 수정해봐야겠다 (할 일 +1)
❓ 막히는 or 막혔던 부분
토큰을 코드 자체에 작성하는 건 보안상 문제가 있을 것 같아서 환경변수에 집어넣었었는데 이렇게 하니 콘솔에 'bad credentials' 오류가 떴었다. 뭐가 문젤까 계속 검색하고 또 삽질했는데... 그냥 리액트 서버를 껐다 켜지 않아서 수정사항이 반영되지 않았던 것이었다 ㅎㅎ .... 아이고 허무해라
.env 파일에 변수명을 지정할 때 앞에 REACT_APP_을 붙이고 불러와야 한다.
// getData 함수의 맨 첫 부분에 이렇게 써주면 된다
const GHP_TOKEN = process.env.REACT_APP_GHP_TOKEN;
const graphqlWithAuth = graphql.defaults({
headers: {
authorization: `token ${GHP_TOKEN}`,
},
});
🔍 공부가 더 필요한 부분
레퍼런스 코드 주석에 있던 링크인데 환경변수 관련 글이니 한 번 읽어보면 좋을 것 같다.
env.local과 그냥 env의 차이가 궁금했는데 env.local은 테스트 때 포함되지 않는다는 차이가 있었다.
Adding Custom Environment Variables | Create React App
Note: this feature is available with react-scripts@0.2.3 and higher.
create-react-app.dev
'Lesson > TIL' 카테고리의 다른 글
TIL: 2022-12-05 (0) | 2022.12.05 |
---|---|
TIL: 2022-12-02 (0) | 2022.12.02 |
TIL: 2022-11-30 (0) | 2022.11.30 |
TIL: 2022-11-29 (0) | 2022.11.29 |
TIL: 2022-11-28 (0) | 2022.11.28 |