GraphQL은 클라이언트가 필요한 데이터를 정확하게 요청하고, 때로는 서버의 데이터를 변경할 수 있게 해주는 API언어이다. GraphQL에서 가장 핵심적인 두 가지 작업은 바로 쿼리(Query)뮤테이션(Mutation)이다.

  • 쿼리(Query): 서버의 데이터를 조회할 때 사용
  • 뮤테이션(Mutation): 서버의 데이터를 변경할 때 사용 (생성, 수정, 삭제 포함)

 


GraphQL 쿼리(Query)란?


GraphQL의 쿼리(Query)는 서버로부터 데이터를 조회(read)하기 위한 작업이다.

클라이언트는 필요한 데이터만 선택적으로 요청할 수 있고, 서버는 해당 요청에 맞춰 데이터를 응답한다.

 

📌 쿼리는 읽기 전용이다. 서버의 데이터를 변경하지 않는다.

 

예시: 사용자 정보 조회
query {
  user(id: 1) {
    id
    name
    email
  }
}

 

응답 결과
{
  "data": {
    "user": {
      "id": 1,
      "name": "Alice",
      "email": "alice@example.com"
    }
  }
}

 

✅ 쿼리는 REST의 GET 요청과 유사하지만, 반환 필드를 클라이언트가 직접 선택할 수 있다는 점에서 더 유연하다.

 


GraphQL 뮤테이션(Mutation)이란?


Mutation은 서버의 데이터를 생성, 수정, 삭제(wtire) 하기 위한 작업이다. 즉, 서버의 상태를 변경할 수 있는 요청이다.

 

⚠️ 서버의 상태를 바꾸기 때문에, 반드시 주의해서 다뤄야 한다.

 

예시: 사용자 등록
mutation {
  createUser(input: {
    name: "Bob",
    email: "bob@example.com"
  }) {
    id
    name
  }
}

 

응답 결과
{
  "data": {
    "createUser": {
      "id": 2,
      "name": "Bob"
    }
  }
}

 

✅ 뮤테이션은 POST 요청에 가깝고, 입력값을 통해 서버에 직접적인 변경 요청을 전달한다.

 

 Query vs. Mutation: 무엇이 다를까?

항목 쿼리(Query) 뮤테이션(Mutation)
목적 데이터 조회 (Read) 데이터 변경 (Create, Update, Delete)
서버 상태 변경되지 않음 변경됨
실행 순서 병렬 실행 순차 실행
캐싱 가능 (결과 동일) 일반적으로 불가 (결과가 바뀜)
권한 체크 비교적 간단 꼭 필요 (쓰기 작업)

 


사용 시 주의할 점


GraphQL은 매우 유연한 쿼리 언어지만, 개발 시 아래와 같은 사항들을 꼭 고려해야 한다.

 

1. 데이터의 읽기와 쓰기 구분

  • Query는 읽기 전용으로 서버 상태에 영향을 주지 않음
  • Mutation은 데이터를 변경하므로 부작용(Side Effect)이 생길 수 있음
    • ex) 사용자 추가, 게시글 삭제 등

📝  뮤테이션을 작성할 때는 트랜잭션 처리, 에러 핸들링, 권한 체크 등을 고려해야 한다.

 

2. 병렬 실행 vs. 순차 실행

  • GraphQL의 쿼리는 병렬로 실행되어, 빠른 응답이 가능하지만
  • 뮤테이션은 의도된 순서대로 순차적으로 실행된다.
mutation {
  stepOne: updateUser(id: 1, name: "Alice")
  stepTwo: deleteUser(id: 2)
}
  • 위 요청은 stepOne이 먼저 실행되고, 그 다음 stepTwo가 실행된다.

 

3. 캐싱 (Caching)

  • Query는 동일한 요청에 대. 해결과가 같기 때문에 캐싱 가능
  • Mutation은 서버 상태를 바꾸므로 캐싱을 피해야 함

예를 들어, 사용자 조회 쿼리는 캐시하여 성능을 높일 수 있지만, 사용자 등록 요청은 매번 서버에서 처리해야 정확한 결과를 얻을 수 있다.

 

4. 보안과 권한 관리

뮤테이션은 서버 데이터를 직접 바꾸기. 때문에 다음과 같은 보안 검증이 필요하다.

  • 인증(Authentictaion): 누가 요청했는가?
  • 권한(Authorization): 해당 사용자가 이 작업을 수행할 권한이 있는가?
public User deleteUser(Long id, AuthUser user) {
    if (!user.hasRole("ADMIN")) {
        throw new UnauthorizedException("삭제 권한 없음");
    }
    return userRepository.deleteById(id);
}

 

📌 중요한 데이터 변경 작업에는 반드시 권한 체크 로직을 추가해야 한다.