[React] 게시판 만들기 #8 : Apollo & GraphQL 설치 및 사용
- 리액트로 게시판 만들기
React 소스코드는 여기 에서 확인 가능합니다.
개발에 사용한 Restful API 는 여기 에서 확인 가능합니다.
- 참고사이트
Apollo 설치
1
npm install --save @apollo/client apollo-link-rest graphql qs
Apollo Query 가 Restful API의 Get Method 역할을 한다고 한다.
하지만, Query 를 이용해도 별도의 설정을 해주지 않으면 Method 의 Default 값이 Post 로 넘어가는 걸 확인했다.
나는 Apollo GQL
을 이용해 React
에서 REST API
에 요청을 넣고 응답을 받고 싶기에, apollo-link-rest
의 RestLink
를 사용했다.
메뉴 생성
🛠 /components/Navbar.js
1
2
3
4
5
6
7
8
9
10
<li className='nav-item'>
<Link to='/apollo/station' className='nav-links' onClick = {closeMobileMenu}>
Apollo Station
</Link>
</li>
<li className='nav-item'>
<Link to='/apollo/voc' className='nav-links' onClick = {closeMobileMenu}>
Apollo Voc
</Link>
</li>
🛠 /components/Navbar.css
1
2
3
4
5
.nav-menu {
...
grid-template-columns: repeat(6, auto); # 4 -> 6 으로 수정
...
}
Route 설정
- 작성 페이지로 이동 할 수 있도록 Route 설정과 매개변수명을 지정한다.
🛠 App.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 추가내용
import ApolloStation from './pages/apollo/station/ApolloStation';
function App() {
return (
<>
<Router>
<Navbar />
<Routes>
<Route exact path='/' element={<Home />} />
<Route path='/station' element={<Station />} />
<Route path='/voc' element={<Voc />} />
<Route path='/voc/:vocId' element={<VocView />} />
<Route path='/voc/question' element={<VocQuestion />} />
// 추가 내용
<Route path='/apollo/station' element={<ApolloStation />} />
</Routes>
</Router>
</>
);
}
export default App;
Apollo Component 생성
🛠 pages/apollo/station/ApolloStation.js
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import React, {useState } from 'react';
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
import { RestLink } from 'apollo-link-rest';
// Set `RestLink` with your endpoint
const restLink = new RestLink({ uri: "http://127.0.0.1:8000/toyseven" });
// Setup your client
const client = new ApolloClient({
cache: new InMemoryCache(),
link: restLink
});
const query = gql`
query getStations {
stations
@rest(
type: "Station"
path: "/stations"
method: "GET"
) {
stationId
stationName
}
}
`;
function GetData() {
const [stations, setStations] = useState({});
client.query({ query }).then(response => {
setStations(response.data.stations);
});
const item = stations && Object.values(stations).map((item) => (
<li key={item.stationId}>
{item.stationName}
</li>
));
return item;
}
function ApolloStation() {
const item = GetData();
return (<div><ul>
{item}
</ul>
</div>);
}
export default ApolloStation;
에러 해결
- Module not found: Error: Can’t resolve ‘graphql-anywhere/lib/async’ 에러 발생 시 아래 문서에 내용을 추가 한다.
🛠 package.json
1
2
3
4
5
"dependencies": {
...
"graphql-anywhere": "4.1.0",
...
}
- Error: ENOENT: no such file or directory, open ‘C:\ymk\toynumber\toyseven-react\node_modules\@apollo\client\node_modules\ts-invariant\src\invariant.ts’ 에러 발생 시 아래 명령어를 터미널에 입력한다.
- 참고사이트
1
2
3
4
5
npm i node-sass
# Install from mirror in China
npm install -g mirror-config-china --registry=http://registry.npm.taobao.org
npm install node-sass
node-sass 는 Node 버전에 의존적이니 아래 내용 참고.
NodeJS | Supported node-sass version | Node Module |
---|---|---|
Node 17 | 7.0+ | 102 |
Node 16 | 6.0+ | 93 |
Node 15 | 5.0+,<7.0 | 88 |
Node 14 | 4.14+ | 83 |
Node 13 | 4.13+, <5.0 | 79 |
Node 12 | 4.12+ | 72 |
Node 11 | 4.10+, <5.0 | 67 |
Node 10 | 4.9+, <6.0 | 64 |
Node 8 | 4.5.3+, <5.0 | 57 |
Node <8 | <5.0 | <57 |
Axios 와 Apollo GQL 과의 차이점
REST API(요청을 위해서 End point(url)을 가지고 API call을 생성해서 호출) 의 단점을 보완하기 위해 나온게 GraphQL 을 기반으로 한 Apollo Client 라고 한다.
- REST API의 단점
- 오버패칭(과도한 데이터를 로딩)의 문제점
ex) 글목록을 조회하려하면 글쓴 회원정보들의 정보도 같이 가지고 오게 된다던지 등 - 언더패칭(부족한 조회)의 문제점
ex) 게시글 내용을 조회 했더니 게시글의 사진의 저장주소는 안나와서 다시 API 요청을 보여야 하는 경우등 - UI요구사항이 늘어날때마다 end Point가 계속 늘어나는데, 여기에 버전이 나뉠경우 버전관리가 매우 힘들다
- 존의 API의 End point가 삭제될 경우 기존의 사용자가 문제가 발생할 위험이 있다.
1) Axios (endpoint 의 데이터가 모두 response 된다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
{ "data": [ { "stationId":"4", "stationName":"102. 망원역 1번출구 앞", "stationLatitude":37.5556488, "stationLongitude":126.91062927, "rackTotCnt":22, "parkingBikeTotCnt":8, "shared":0 }, ... ], "status":200, "headers": { ... }, ... }
2) Apollo (GQL을 이용해 내가 원하는 값만 받아 올 수 있다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
{ "data":{ "stations":[ { "__typename":"Station", "stationId":"4", "stationName":"102. 망원역 1번출구 앞" }, ... ] }, "loading":false, "networkStatus":7 }
위 Response 는 GQL 에 따라 정해진다
1 2 3 4 5 6 7 8 9 10 11 12 13
const query = gql` query getStations { station # 이 부분이 data 안의 key @rest( type: "Station" # 이 부분이 __typename 에 해당 path: "/stations" method: "GET" ) { stationId stationName } } `;
- 오버패칭(과도한 데이터를 로딩)의 문제점
Leave a comment