GraphQL
GraphQL은 API에 필요한 데이터만 정확히 요청할 수 있는 쿼리 언어입니다. Over-fetching과 Under-fetching 문제를 해결합니다.
면접에서 "REST와 GraphQL의 차이"를 물어보면, 각각의 장단점과 적합한 사용 시나리오 를 설명할 수 있어야 합니다.
Vue Apollo 설정
// plugins/apollo.ts
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client/core'
import { DefaultApolloClient } from '@vue/apollo-composable'
const httpLink = createHttpLink({
uri: 'https://api.example.com/graphql'
})
export const apolloClient = new ApolloClient({
link: httpLink,
cache: new InMemoryCache()
})
// main.ts
import { createApp, provide, h } from 'vue'
import { DefaultApolloClient } from '@vue/apollo-composable'
import { apolloClient } from './plugins/apollo'
const app = createApp({
setup() {
provide(DefaultApolloClient, apolloClient)
},
render: () => h(App)
})
쿼리 (useQuery)
<script setup lang="ts">
import { useQuery } from '@vue/apollo-composable'
import gql from 'graphql-tag'
// GraphQL 쿼리 정의
const GET_USERS = gql`
query GetUsers($limit: Int) {
users(limit: $limit) {
id
name
email
avatar
}
}
`
const { result, loading, error, refetch } = useQuery(GET_USERS, {
limit: 10
})
// result는 반응형 — 데이터가 오면 자동 업데이트
const users = computed(() => result.value?.users ?? [])
</script>
<template>
<div v-if="loading">로딩 중...</div>
<div v-else-if="error">에러: {{ error.message }}</div>
<ul v-else>
<li v-for="user in users" :key="user.id">
{{ user.name }} — {{ user.email }}
</li>
</ul>
<button @click="refetch()">새로고침</button>
</template>
뮤테이션 (useMutation)
<script setup lang="ts">
import { useMutation } from '@vue/apollo-composable'
import gql from 'graphql-tag'
const CREATE_USER = gql`
mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) {
id
name
email
}
}
`
const { mutate: createUser, loading: creating, error: createError } = useMutation(CREATE_USER, {
// 캐시 자동 업데이트
update(cache, { data: { createUser } }) {
const existing = cache.readQuery({ query: GET_USERS })
cache.writeQuery({
query: GET_USERS,
data: { users: [...existing.users, createUser] }
})
}
})
const handleSubmit = async () => {
await createUser({ input: { name: '새 사용자', email: 'new@test.com' } })
}
</script>
REST vs GraphQL
| 항목 | REST | GraphQL |
|---|---|---|
| 엔드포인트 | 리소스마다 다름 | 단일 엔드포인트 |
| 응답 데이터 | 서버가 결정 | 클라이언트가 결정 |
| Over-fetching | 발생 가능 | 필요한 것만 요청 |
| 러닝 커브 | 낮음 | 중간~높음 |
| 캐싱 | HTTP 캐시 활용 용이 | 전용 캐시 필요 |
면접 팁
- GraphQL이 항상 REST보다 좋은 것은 아닙니다. 데이터 관계가 복잡하고 클라이언트마다 다른 데이터가 필요할 때 적합합니다
- Apollo Client의 ** 정규화된 캐시(InMemoryCache)**가 어떻게 동작하는지 알고 있으면 좋습니다
- N+1 문제와 DataLoader 패턴은 백엔드 면접에서도 나올 수 있는 GraphQL 관련 질문입니다
요약
Vue에서 GraphQL은 @vue/apollo-composable의 useQuery/useMutation으로 선언적으로 사용합니다. GraphQL은 필요한 데이터만 요청하여 Over-fetching을 방지하고, Apollo의 정규화된 캐시로 상태를 효율적으로 관리합니다.
댓글 로딩 중...