GraphQL은 API에 필요한 데이터만 정확히 요청할 수 있는 쿼리 언어입니다. Over-fetching과 Under-fetching 문제를 해결합니다.

면접에서 "REST와 GraphQL의 차이"를 물어보면, 각각의 장단점과 적합한 사용 시나리오 를 설명할 수 있어야 합니다.


Vue Apollo 설정

TYPESCRIPT
// 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()
})
TYPESCRIPT
// 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)

VUE
<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)

VUE
<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

항목RESTGraphQL
엔드포인트리소스마다 다름단일 엔드포인트
응답 데이터서버가 결정클라이언트가 결정
Over-fetching발생 가능필요한 것만 요청
러닝 커브낮음중간~높음
캐싱HTTP 캐시 활용 용이전용 캐시 필요

면접 팁

  • GraphQL이 항상 REST보다 좋은 것은 아닙니다. 데이터 관계가 복잡하고 클라이언트마다 다른 데이터가 필요할 때 적합합니다
  • Apollo Client의 ** 정규화된 캐시(InMemoryCache)**가 어떻게 동작하는지 알고 있으면 좋습니다
  • N+1 문제와 DataLoader 패턴은 백엔드 면접에서도 나올 수 있는 GraphQL 관련 질문입니다

요약

Vue에서 GraphQL은 @vue/apollo-composable의 useQuery/useMutation으로 선언적으로 사용합니다. GraphQL은 필요한 데이터만 요청하여 Over-fetching을 방지하고, Apollo의 정규화된 캐시로 상태를 효율적으로 관리합니다.

댓글 로딩 중...