InfoGrab DocsInfoGrab Docs

GraphQL 배열 인수

요약

GitLab GraphQL API의 모든 배열 인수에는 남용 방지 및 성능 문제 예방을 위한 크기 유효성 검사가 있어야 합니다. validates 옵션을 사용하여 배열 크기 제한을 명시적으로 선언합니다: GraphQL-Ruby의 내장 유효성 검사 활용

GraphQL에서 배열 인수 유효성 검사#

개요#

GitLab GraphQL API의 모든 배열 인수에는 남용 방지 및 성능 문제 예방을 위한 크기 유효성 검사가 있어야 합니다.

유효성 검사 방법#

권장 방법: 명시적 유효성 검사 (목표 상태)#

validates 옵션을 사용하여 배열 크기 제한을 명시적으로 선언합니다:

argument :assignee_usernames, [GraphQL::Types::String],
  required: false,
  validates: { length: { maximum: Types::BaseArgument::MAX_ARRAY_SIZE } },
  description: "Usernames of users assigned to the merge request " \
    "(maximum is #{Types::BaseArgument::MAX_ARRAY_SIZE} usernames)."

장점:

  • 명확하고 명시적

  • 인수 정의에서 직접 확인 가능

  • 기존 코드베이스 패턴과 일관성 유지

  • GraphQL-Ruby의 내장 유효성 검사 활용

자동 유효성 검사 (전환 기간)#

전환 기간 동안, 명시적인 validates: { length: { maximum: ... } }없는 배열 인수는 BaseArgument에 의해 자동으로 100개 항목으로 제한됩니다.

# 이 인수는 자동으로 100개 항목으로 제한됩니다
argument :items, [GraphQL::Types::String],
  required: false,
  description: 'List of items.'

동작 방식#

BaseArgument 클래스는 스마트 감지를 구현합니다:

  • 명시적 유효성 검사가 있는 경우: 명시된 제한값 사용 (자동 유효성 검사 없음)

  • 명시적 유효성 검사가 없는 경우: 자동으로 100개 항목 제한 적용

# 명시적 유효성 검사 - 50을 제한값으로 사용
argument :limited_items, [GraphQL::Types::String],
  validates: { length: { maximum: 50 } },
  description: 'Limited to 50 items.'

# 명시적 유효성 검사 없음 - 자동으로 100개 항목으로 제한
argument :auto_limited_items, [GraphQL::Types::String],
  description: 'Automatically limited to 100 items.'

마이그레이션 경로#

1단계: 자동 보호 (현재)#

모든 배열 인수는 자동으로 100개 항목 제한으로 보호됩니다.

2단계: 명시적 유효성 검사 추가#

모든 배열 인수에 명시적인 validates 선언을 점진적으로 추가합니다:

# 변경 전 (자동 유효성 검사에 의존)
argument :assignee_usernames, [GraphQL::Types::String],
  required: false,
  description: 'Usernames of users assigned to the merge request.'

# 변경 후 (명시적 유효성 검사)
argument :assignee_usernames, [GraphQL::Types::String],
  required: false,
  validates: { length: { maximum: Types::BaseArgument::MAX_ARRAY_SIZE } },
  description: "Usernames of users assigned to the merge request " \
    "(maximum is #{Types::BaseArgument::MAX_ARRAY_SIZE} usernames)."

3단계: 자동 유효성 검사 제거#

모든 배열 인수에 명시적 유효성 검사가 추가되면, BaseArgument에서 자동 유효성 검사를 제거할 수 있습니다.

상수#

Types::BaseArgument::MAX_ARRAY_SIZE#

배열 인수의 기본 최대 크기입니다 (현재 100).

일관성을 위해 이 상수를 사용하세요:

validates: { length: { maximum: Types::BaseArgument::MAX_ARRAY_SIZE } }

사용자 정의 제한#

특정 사용 사례에 대해 다른 제한값을 사용할 수 있습니다:

# 모듈 상수 사용
module WorkItems
  module SharedFilterArguments
    MAX_FIELD_LIMIT = 100
  end
end

argument :ids, [::Types::GlobalIDType[::WorkItem]],
  validates: { length: { maximum: WorkItems::SharedFilterArguments::MAX_FIELD_LIMIT } },
  description: "Filter by global IDs (maximum is #{WorkItems::SharedFilterArguments::MAX_FIELD_LIMIT} IDs)."

오류 메시지#

유효성 검사가 실패하면, 사용자에게 명확한 오류 메시지가 표시됩니다:

"assigneeUsernames cannot accept more than 100 items"

예시#

올바른 예시#

# 예시 1: 기본 상수 사용
argument :user_ids, [GraphQL::Types::ID],
  validates: { length: { maximum: Types::BaseArgument::MAX_ARRAY_SIZE } },
  description: "User IDs (maximum is #{Types::BaseArgument::MAX_ARRAY_SIZE})."

# 예시 2: 사용자 정의 상수 사용
argument :label_names, [GraphQL::Types::String],
  validates: { length: { maximum: WorkItems::SharedFilterArguments::MAX_FIELD_LIMIT } },
  description: "Label names (maximum is #{WorkItems::SharedFilterArguments::MAX_FIELD_LIMIT})."

# 예시 3: 특정 사용 사례에 대한 사용자 정의 제한
argument :vulnerability_ids, [GraphQL::Types::ID],
  validates: { length: { minimum: 1, maximum: 50 } },
  description: "Vulnerability IDs (minimum 1, maximum 50)."

잘못된 예시#

# 잘못됨: 유효성 검사 없고 제한에 대한 설명도 없음
argument :items, [GraphQL::Types::String],
  description: 'List of items.'

# 잘못됨: 상수 없이 하드코딩된 숫자 사용
argument :items, [GraphQL::Types::String],
  validates: { length: { maximum: 100 } },
  description: 'List of items (maximum is 100).'

테스트#

배열 인수가 있는 리졸버 또는 뮤테이션을 테스트할 때는 유효성 검사를 테스트합니다:

RSpec.describe Resolvers::MyResolver do
  it 'accepts arrays within the limit' do
    items = Array.new(50, 'item')
    expect { resolve(items: items) }.not_to raise_error
  end

  it 'rejects arrays exceeding the limit' do
    items = Array.new(101, 'item')
    expect { resolve(items: items) }.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
  end
end

관련 문서#

GraphQL 배열 인수

GitLab v19.1
원문 보기
요약

GitLab GraphQL API의 모든 배열 인수에는 남용 방지 및 성능 문제 예방을 위한 크기 유효성 검사가 있어야 합니다. validates 옵션을 사용하여 배열 크기 제한을 명시적으로 선언합니다: GraphQL-Ruby의 내장 유효성 검사 활용

GraphQL에서 배열 인수 유효성 검사#

개요#

GitLab GraphQL API의 모든 배열 인수에는 남용 방지 및 성능 문제 예방을 위한 크기 유효성 검사가 있어야 합니다.

유효성 검사 방법#

권장 방법: 명시적 유효성 검사 (목표 상태)#

validates 옵션을 사용하여 배열 크기 제한을 명시적으로 선언합니다:

argument :assignee_usernames, [GraphQL::Types::String],
  required: false,
  validates: { length: { maximum: Types::BaseArgument::MAX_ARRAY_SIZE } },
  description: "Usernames of users assigned to the merge request " \
    "(maximum is #{Types::BaseArgument::MAX_ARRAY_SIZE} usernames)."

장점:

  • 명확하고 명시적

  • 인수 정의에서 직접 확인 가능

  • 기존 코드베이스 패턴과 일관성 유지

  • GraphQL-Ruby의 내장 유효성 검사 활용

자동 유효성 검사 (전환 기간)#

전환 기간 동안, 명시적인 validates: { length: { maximum: ... } }없는 배열 인수는 BaseArgument에 의해 자동으로 100개 항목으로 제한됩니다.

# 이 인수는 자동으로 100개 항목으로 제한됩니다
argument :items, [GraphQL::Types::String],
  required: false,
  description: 'List of items.'

동작 방식#

BaseArgument 클래스는 스마트 감지를 구현합니다:

  • 명시적 유효성 검사가 있는 경우: 명시된 제한값 사용 (자동 유효성 검사 없음)

  • 명시적 유효성 검사가 없는 경우: 자동으로 100개 항목 제한 적용

# 명시적 유효성 검사 - 50을 제한값으로 사용
argument :limited_items, [GraphQL::Types::String],
  validates: { length: { maximum: 50 } },
  description: 'Limited to 50 items.'

# 명시적 유효성 검사 없음 - 자동으로 100개 항목으로 제한
argument :auto_limited_items, [GraphQL::Types::String],
  description: 'Automatically limited to 100 items.'

마이그레이션 경로#

1단계: 자동 보호 (현재)#

모든 배열 인수는 자동으로 100개 항목 제한으로 보호됩니다.

2단계: 명시적 유효성 검사 추가#

모든 배열 인수에 명시적인 validates 선언을 점진적으로 추가합니다:

# 변경 전 (자동 유효성 검사에 의존)
argument :assignee_usernames, [GraphQL::Types::String],
  required: false,
  description: 'Usernames of users assigned to the merge request.'

# 변경 후 (명시적 유효성 검사)
argument :assignee_usernames, [GraphQL::Types::String],
  required: false,
  validates: { length: { maximum: Types::BaseArgument::MAX_ARRAY_SIZE } },
  description: "Usernames of users assigned to the merge request " \
    "(maximum is #{Types::BaseArgument::MAX_ARRAY_SIZE} usernames)."

3단계: 자동 유효성 검사 제거#

모든 배열 인수에 명시적 유효성 검사가 추가되면, BaseArgument에서 자동 유효성 검사를 제거할 수 있습니다.

상수#

Types::BaseArgument::MAX_ARRAY_SIZE#

배열 인수의 기본 최대 크기입니다 (현재 100).

일관성을 위해 이 상수를 사용하세요:

validates: { length: { maximum: Types::BaseArgument::MAX_ARRAY_SIZE } }

사용자 정의 제한#

특정 사용 사례에 대해 다른 제한값을 사용할 수 있습니다:

# 모듈 상수 사용
module WorkItems
  module SharedFilterArguments
    MAX_FIELD_LIMIT = 100
  end
end

argument :ids, [::Types::GlobalIDType[::WorkItem]],
  validates: { length: { maximum: WorkItems::SharedFilterArguments::MAX_FIELD_LIMIT } },
  description: "Filter by global IDs (maximum is #{WorkItems::SharedFilterArguments::MAX_FIELD_LIMIT} IDs)."

오류 메시지#

유효성 검사가 실패하면, 사용자에게 명확한 오류 메시지가 표시됩니다:

"assigneeUsernames cannot accept more than 100 items"

예시#

올바른 예시#

# 예시 1: 기본 상수 사용
argument :user_ids, [GraphQL::Types::ID],
  validates: { length: { maximum: Types::BaseArgument::MAX_ARRAY_SIZE } },
  description: "User IDs (maximum is #{Types::BaseArgument::MAX_ARRAY_SIZE})."

# 예시 2: 사용자 정의 상수 사용
argument :label_names, [GraphQL::Types::String],
  validates: { length: { maximum: WorkItems::SharedFilterArguments::MAX_FIELD_LIMIT } },
  description: "Label names (maximum is #{WorkItems::SharedFilterArguments::MAX_FIELD_LIMIT})."

# 예시 3: 특정 사용 사례에 대한 사용자 정의 제한
argument :vulnerability_ids, [GraphQL::Types::ID],
  validates: { length: { minimum: 1, maximum: 50 } },
  description: "Vulnerability IDs (minimum 1, maximum 50)."

잘못된 예시#

# 잘못됨: 유효성 검사 없고 제한에 대한 설명도 없음
argument :items, [GraphQL::Types::String],
  description: 'List of items.'

# 잘못됨: 상수 없이 하드코딩된 숫자 사용
argument :items, [GraphQL::Types::String],
  validates: { length: { maximum: 100 } },
  description: 'List of items (maximum is 100).'

테스트#

배열 인수가 있는 리졸버 또는 뮤테이션을 테스트할 때는 유효성 검사를 테스트합니다:

RSpec.describe Resolvers::MyResolver do
  it 'accepts arrays within the limit' do
    items = Array.new(50, 'item')
    expect { resolve(items: items) }.not_to raise_error
  end

  it 'rejects arrays exceeding the limit' do
    items = Array.new(101, 'item')
    expect { resolve(items: items) }.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
  end
end

관련 문서#