사양에서 :
GraphQL 객체 유형 (ObjectTypeDefinition) ...은 [입력으로] 재사용하기에 부적절합니다. 객체 유형은 인수를 정의하는 필드를 포함하거나 인터페이스 및 공용체에 대한 참조를 포함 할 수 있기 때문에 입력 인수로 사용하기에 적합하지 않습니다. . 이러한 이유로 입력 개체는 시스템에서 별도의 유형을 갖습니다.
이것이 "공식적인 이유"이지만, 객체 유형을 입력 객체 유형으로 사용하거나 객체 유형을 입력 객체 유형으로 사용할 수없는 몇 가지 실용적인 이유가 있습니다.
기능성
객체 유형과 입력 객체 유형에는 모두 필드가 있지만 이러한 필드에는 스키마에서 이러한 유형이 사용되는 방식을 반영하는 다른 속성이 있습니다. 스키마는 잠재적 인수 및 개체 유형의 필드에 대한 해결 기능의 어떤 종류를 정의하지만, 이러한 속성 (즉, 당신이 할 수없는 입력 맥락에서 이해가되지 않습니다 해결 - 이미 명시 적 값을 갖는 입력 오브젝트의 필드) . 마찬가지로 기본값은 개체 유형 필드가 아닌 입력 개체 유형 필드에만 제공 될 수 있습니다.
즉, 이것은 중복처럼 보일 수 있습니다.
type Student {
name: String
grade: Grade
}
input StudentInput {
name: String
grade: Grade
}
그러나 객체 유형 또는 입력 객체 유형에 특정한 기능을 추가하면 서로 다르게 작동 함을 분명히 알 수 있습니다.
type Student {
name(preferred: Boolean): String
grade: Grade
}
input StudentInput {
name: String
grade: Grade = F
}
유형 시스템 제한
GraphQL의 유형은 출력 유형 과 입력 유형 으로 그룹화됩니다 .
출력 유형은 GraphQL 서비스에서 생성 된 응답의 일부로 반환 될 수있는 유형입니다. 입력 유형은 필드 또는 지시문 인수에 대한 유효한 입력 유형입니다.
이 두 그룹 (예 : 스칼라, 열거 형, 목록 및 Null이 아닌)간에 겹치는 부분이 있습니다. 그러나 공용체 및 인터페이스와 같은 추상 유형 은 입력 컨텍스트에서 의미가 없으며 입력으로 사용할 수 없습니다. 객체 유형과 입력 객체 유형을 분리하면 입력 유형이 예상되는 곳에 추상 유형이 사용되지 않도록 할 수 있습니다.
스키마 디자인
스키마에서 항목을 나타낼 때 일부 항목은 실제로 각각의 입력 및 출력 유형간에 "필드를 공유"할 가능성이 있습니다.
type Student {
firstName: String
lastName: String
grade: Grade
}
input StudentInput {
firstName: String
lastName: String
grade: Grade
}
그러나 객체 유형은 매우 복잡한 데이터 구조를 모델링 할 수 있으며 실제로는 자주 수행합니다.
type Student {
fullName: String!
classes: [Class!]!
address: Address!
emergencyContact: Contact
# etc
}
이러한 구조 는 적절한 입력으로 변환 될 수 있지만 (Student를 생성하므로 해당 주소를 나타내는 객체도 전달 함) 종종 그렇지 않습니다. 목적. 마찬가지로, 반환하고 싶지만 변경하고 싶지 않은 필드가있을 수 있으며, 그 반대도 마찬가지입니다 ( password
필드 처럼 ).
더욱이 비교적 단순한 엔터티의 경우에도 개체 유형과 "상대"입력 개체 간의 null 허용 여부에 대한 요구 사항이 다른 경우가 많습니다. 종종 우리는 응답에서 필드도 반환되도록 보장하고 싶지만 입력에 필요한 동일한 필드를 만들고 싶지 않습니다. 예를 들면
type Student {
firstName: String!
lastName: String!
}
input StudentInput {
firstName: String
lastName: String
}
마지막으로, 많은 스키마에서 주어진 엔터티에 대한 개체 유형과 입력 개체 유형간에 일대일 매핑이없는 경우가 많습니다. 일반적인 패턴은 서로 다른 작업에 대해 별도의 입력 개체 유형을 활용하여 스키마 수준 입력 유효성 검사를 더욱 세부적으로 조정하는 것입니다.
input CreateUserInput {
firstName: String!
lastName: String!
email: String!
password: String!
}
input UpdateUserInput {
email: String
password: String
}
이 모든 예제는 중요한 점을 보여줍니다. 입력 개체 유형이 개체 유형을 언젠가 미러링 할 수 있지만 비즈니스 요구 사항으로 인해 프로덕션 스키마에서이를 볼 가능성이 훨씬 적습니다.