
추석연휴 포함해서 약 2주일동안 정말 삽질을 많이 한 것 같다.
사실 아직 파야할 곳이 많아 막막하지만 그래도 물꼬가 트여서 써본다.
삽질 포인트는 아래와 같다.
1. Apollo Client와 Apollo Server는 둘다 있어야 되는건가? -> Yes
2. NextJs는 Server Render 방식인데, Server에 Apollo Server 설정을 할 수 있나? -> Yes
3. Typescript, NextJs, Apollo Server/Client을 모두 한 프로젝트에서 사용할 수 있나? -> Yes
1번 포인트에서 많이 헷갈렸던게 나는 Apollo Client가 Query을 실행하면 쿼리로 요청한 값만 전달되어 서버측 Model VO에서 해당부분만 값이 셋팅할거라고 생각했다. 그래서 Apollo Server는 필요없다고 판단했는데, 공식 사이트를 열심히 독해하면서 생각해보니
아예 GraphQL은 별도의 프로토콜로 통신하는 것 같았다. 설령 Apollo Server 없이 바로 API에서 받을 수 있다고 해도 Method는 Get, Post 따위가 아닌 GraphQL일 가능성도 있다. (이 부분은 테스트를 해보고 좀 더 스터디가 필요하다. 정말 Server가 필요한지!)
2번 포인트는 한 일주일 정도 다양하게 테스트를 해봤다.
GraphQL을 처리하는 서버는 아예 별개로 두고 NextJS 내에 API 서버와 React을 두는 방안,
GraphQL을 새로운 서버리스로 만들고 API랑 연동하는 방안,
GraphQL을 API 서버처럼 사용하는 방안 등등 시행착오를 격었다.
구글에 NextJS + Apollo Server 조합을 찾아보면 대부분 express을 통해 새로운 서버리스를 만든다.
그런데 내가 원했던건 NextJS 자체 한 통에서 한 포트로 프론트엔드-백엔드를 관리하는 거였다.
이렇게 한 통으로 관리가 안되면 NextJS을 사용하는 이유가 없다고 생각한다.
Apollo는 꽤 다양한 서버 구성이 가능했다. 그 중 나는 <React> - <GraphQL> - <DB> 구성으로 결정했다.
Redux처럼 충분히 데이터를 조합할 수 있는 구조라고 판단했다.
Beter 프로젝트는 상대적으로 해야되는 요건이 적어 가능할 것 같긴 한데 API을 구성하는 방안은 좀 더 연구를 해봐야 될 것 같다.
결과적으로 3번 포인트까지 테스트를 완료했다. 다행히 별도의 서버가 없어도 NextJS 안에서 모두 해결이 가능했다.
아래에는 내가 했던 셋팅 순서대로 정리해봤다.
1. NextJS로 프로젝트 생성하고 실행해보기
npx create-next-app <프로젝트 명>
cd <프로젝트 명>
rm yarn.lock
yarn -- 노파심에 한번더
yarn dev
2. 필요한 모듈 설치하기
3. Typescript 설정하기
<프로젝트명>/pages/index.js -> index.tsx
<프로젝트명>/pages/_app.js -> _app.tsx
touch tsconfig.json
yarn build
여기까지 진행하고 브라우저에서 localhost:3000로 접속하면 NextJS(index.tsx) 웰컴 페이지가 나온다.
4. Apollo Server 스키마 만들기
# /pages/api/graphql.ts
import { ApolloServer } from 'apollo-server-micro'
import { makeSchema, objectType, stringArg } from '@nexus/schema'
const User = objectType({
name: 'User',
definition(t) {
t.string('id')
t.string('email')
t.string('name')
}
})
const Query = objectType({
name: 'Query',
definition(t) {
t.list.field('user', {
type: 'User',
resolve: (_, args) => {
return [
{
id: 'abc1',
name: 'ABC1',
email: 'abc1@naver.com'
},
{
id: 'abc2',
name: 'ABC2',
email: 'abc2@naver.com'
},
{
id: 'abc3',
name: 'ABC3',
email: 'abc3@naver.com'
}
]
}
})
}
})
const schema = makeSchema({
types: [
Query,
User
]
})
const server = new ApolloServer({ schema })
const handler = server.createHandler({ path: '/api/graphql' })
export const config = {
api: {
bodyParser: false
}
}
export default handler
5. Apollo Client
# /pages/_app.tsx
import type { AppProps } from 'next/app'
import '../styles/globals.css'
function MyApp ({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
export default MyApp
# /pages/index.ts
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client'
import { UserList } from '../src/components'
const Home = () => {
const client = new ApolloClient({
uri: 'http://localhost:3000/api/graphql',
cache: new InMemoryCache()
})
return (
<ApolloProvider client={client}>
<div>
<UserList />
</div>
</ApolloProvider>
)
}
export default Home
# /src/components/UserList.tsx
import { useQuery } from "@apollo/react-hooks"
import { useState } from "react"
import { gql } from "@apollo/client"
const Q_USERLIST = gql`
query {
user {
id
email
name
}
}
`
function UserList () {
const { loading, error, data } = useQuery(Q_USERLIST)
const users = data ? data.user : []
return (
<div>
{users && users.map(user => <div key={user.id}>{user.name}({user.email})</div>)}
</div>
)
}
export default UserList
# /src/components/index.ts
export { default as UserList } from './UserList'
막 시작할때는 어려웠는데 한번 해보고, 블로그 포스팅을 위해 다시 복습해보니 설정이 쉬운 것 같다.
아무리 봐도 신기한 GraphQL,,
| Material-UI html2canvas SVG 안나오는 문제 (0) | 2021.01.14 |
|---|---|
| #5 Apollo 환경에 Prisma 끼얹기 (0) | 2020.11.10 |
| #3 NextJS에 PostgreSQL 연동하기 (0) | 2020.09.25 |
| #2 NextJS 기본 사용법 (0) | 2020.09.25 |
| PostgreSQL Mac에서 시작하기 (0) | 2020.09.24 |