InfoGrab DocsInfoGrab Docs

GraphQL 배열 인수

요약

GitLab GraphQL API의 모든 배열 인수에는 남용과 성능 문제를 방지하기 위한 크기 유효성 검사가 있어야 합니다. validates 옵션을 사용해 배열 크기 제한을 명시적으로 선언합니다. 전환 기간에는 명시적인 validates: { length: { maximum: ...

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개 항목으로 제한됩니다.

# This will automatically be limited to 100 items
argument :items, [GraphQL::Types::String],
  required: false,
  description: 'List of items.'

동작 방식#

BaseArgument 클래스는 다음과 같이 지능적으로 감지합니다.

  1. 명시적 유효성 검사가 있는 경우: 명시적 제한값을 사용합니다(자동 유효성 검사 없음)
  2. 명시적 유효성 검사가 없는 경우: 자동으로 100개 항목 제한을 적용합니다
# Explicit validation - uses 50 as the limit
argument :limited_items, [GraphQL::Types::String],
  validates: { length: { maximum: 50 } },
  description: 'Limited to 50 items.'

# No explicit validation - automatically limited to 100 items
argument :auto_limited_items, [GraphQL::Types::String],
  description: 'Automatically limited to 100 items.'

마이그레이션 경로#

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

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

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

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

# Before (relies on automatic validation)
argument :assignee_usernames, [GraphQL::Types::String],
  required: false,
  description: 'Usernames of users assigned to the merge request.'

# After (explicit validation)
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 } }

사용자 정의 제한#

특정 사용 사례에서는 다른 제한값을 사용할 수 있습니다.

# Using a module constant
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"

예시#

올바른 예시#

# Example 1: Using the default constant
argument :user_ids, [GraphQL::Types::ID],
  validates: { length: { maximum: Types::BaseArgument::MAX_ARRAY_SIZE } },
  description: "User IDs (maximum is #{Types::BaseArgument::MAX_ARRAY_SIZE})."

# Example 2: Using a custom constant
argument :label_names, [GraphQL::Types::String],
  validates: { length: { maximum: WorkItems::SharedFilterArguments::MAX_FIELD_LIMIT } },
  description: "Label names (maximum is #{WorkItems::SharedFilterArguments::MAX_FIELD_LIMIT})."

# Example 3: Custom limit for specific use case
argument :vulnerability_ids, [GraphQL::Types::ID],
  validates: { length: { minimum: 1, maximum: 50 } },
  description: "Vulnerability IDs (minimum 1, maximum 50)."

잘못된 예시#

# Bad: No validation and no description of limit
argument :items, [GraphQL::Types::String],
  description: 'List of items.'

# Bad: Hardcoded number without constant
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.4
원문 보기

요약

GitLab GraphQL API의 모든 배열 인수에는 남용과 성능 문제를 방지하기 위한 크기 유효성 검사가 있어야 합니다. validates 옵션을 사용해 배열 크기 제한을 명시적으로 선언합니다. 전환 기간에는 명시적인 validates: { length: { maximum: ...

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개 항목으로 제한됩니다.

# This will automatically be limited to 100 items
argument :items, [GraphQL::Types::String],
  required: false,
  description: 'List of items.'

동작 방식#

BaseArgument 클래스는 다음과 같이 지능적으로 감지합니다.

  1. 명시적 유효성 검사가 있는 경우: 명시적 제한값을 사용합니다(자동 유효성 검사 없음)
  2. 명시적 유효성 검사가 없는 경우: 자동으로 100개 항목 제한을 적용합니다
# Explicit validation - uses 50 as the limit
argument :limited_items, [GraphQL::Types::String],
  validates: { length: { maximum: 50 } },
  description: 'Limited to 50 items.'

# No explicit validation - automatically limited to 100 items
argument :auto_limited_items, [GraphQL::Types::String],
  description: 'Automatically limited to 100 items.'

마이그레이션 경로#

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

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

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

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

# Before (relies on automatic validation)
argument :assignee_usernames, [GraphQL::Types::String],
  required: false,
  description: 'Usernames of users assigned to the merge request.'

# After (explicit validation)
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 } }

사용자 정의 제한#

특정 사용 사례에서는 다른 제한값을 사용할 수 있습니다.

# Using a module constant
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"

예시#

올바른 예시#

# Example 1: Using the default constant
argument :user_ids, [GraphQL::Types::ID],
  validates: { length: { maximum: Types::BaseArgument::MAX_ARRAY_SIZE } },
  description: "User IDs (maximum is #{Types::BaseArgument::MAX_ARRAY_SIZE})."

# Example 2: Using a custom constant
argument :label_names, [GraphQL::Types::String],
  validates: { length: { maximum: WorkItems::SharedFilterArguments::MAX_FIELD_LIMIT } },
  description: "Label names (maximum is #{WorkItems::SharedFilterArguments::MAX_FIELD_LIMIT})."

# Example 3: Custom limit for specific use case
argument :vulnerability_ids, [GraphQL::Types::ID],
  validates: { length: { minimum: 1, maximum: 50 } },
  description: "Vulnerability IDs (minimum 1, maximum 50)."

잘못된 예시#

# Bad: No validation and no description of limit
argument :items, [GraphQL::Types::String],
  description: 'List of items.'

# Bad: Hardcoded number without constant
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

관련 주제#