GraphQL에서 인터페이스(interface)란 무엇인가요?
_____A1. GraphQL 인터페이스는 스키마에 정의되는 추상 타입(abstract type)의 한 종류로, 공통 필드(field)를 미리 선언하고 이를 여러 객체 타입(object type)이 구현(implements)하게 하는 구조입니다. 클라이언트는 인터페이스 타입으로 질의(query)를 보낸 뒤, 실제 리턴된 객체가 어떤 구현체인지 구분하여 공통 필드와 고유 필드를 함께 사용할 수 있습니다.
Q2. 인터페이스와 유니온(union)의 차이점은 무엇인가요?
A2.
- 인터페이스(interface): 공통 필드 집합을 정의하고, 모든 구현 타입이 해당 필드를 반드시 제공해야 함.
- 유니온(union): 서로 관계가 없거나 공통 필드가 없어도 여러 타입을 묶을 수 있음. 구현 타입이 공통 필드를 가질 필요는 없으며, 각기 다른 필드만 제공 가능.
Q3. 왜 인터페이스를 사용하나요?
A3.
- 다형성 제공: 클라이언트 입장에서 여러 타입을 하나의 엔드포인트로 다룰 수 있음.
- 코드 재사용성: 공통 필드를 인터페이스에 모아 중복을 줄임.
- 타입 안전성 강화: 스키마 레벨에서 구현 타입이 가져야 할 필드를 강제하여 일관성 유지.
- 문서화 & IDE 지원: 스키마가 명확해지므로 자동 완성 및 문서 생성에 유리.
Q4. 스키마에 인터페이스를 정의하는 방법은?
A4.
```
interface Character {
id: ID!
name: String!
}
```
위 예시에서 `Character` 인터페이스는 `id`, `name` 필드를 공통으로 갖습니다.
Q5. 인터페이스를 구현하는 객체 타입 작성 예시는?
A5.
```
type Human implements Character {
id: ID!
name: String!
totalCredits: Int
}
type Droid implements Character {
id: ID!
name: String!
primaryFunction: String
}
```
각 타입은 `Character`가 정의한 `id`, `name` 필드를 반드시 포함하고, 자신만의 필드(`totalCredits`, `primaryFunction`)를 추가합니다.
Q6. 인터페이스를 활용한 쿼리 예시
A6.
```
query {
characters { 반환 타입이 [Character!]!
id
name
... on Human {
totalCredits
}
... on Droid {
primaryFunction
}
}
}
```
클라이언트는 `... on Type` 형태의 fragment 문법으로 구체 타입별 추가 필드를 요청할 수 있습니다.
Q7. 구현 시 주의사항은 무엇인가요?
A7.
1. 구현 타입은 인터페이스가 정의한 모든 필드를 같은 이름·타입으로 제공해야 합니다.
2. 반환 타입 공변성(covariant): 구현체가 인터페이스보다 더 구체적인(non-nullable → nullable) 타입 또는 서브타입을 반환하도록 허용됩니다.
3. 런타임 리졸버가 `__resolveType`(또는 원본 데이터의 타입 식별 로직)을 제공하여 쿼리 시 올바른 구현체로 매핑해야 합니다.
Q8. GraphQL 인터페이스의 주요 장점
A8.
- 스키마의 응집도 향상: 관련 타입 간 공통 계약(Contract)을 명확히 정의.
- 클라이언트 코드 단순화: 호출하는 쿼리에서 하나의 인터페이스 타입만 염두에 두면 됨.
- 유지보수성 강화: 공통 필드 변경 시 인터페이스만 수정하면, 구현체가 일괄적으로 따라감.
Q9. 인터페이스 필드 타입 제약은 어떻게 되나요?
A9.
- 구현체의 필드 타입은 인터페이스에 선언된 타입 혹은 그 서브타입(더 구체적인 타입)이어야 합니다.
- 예를 들어 인터페이스에 `String`이면 구현체에서 `String!`(nonnull)으로 더 엄격하게 지정 가능.
Q10. 인터페이스 활용을 위한 팁
A10.
- Relay 환경: `Node` 인터페이스로 모든 엔티티에 `id` 필드를 통일해 사용.
- 필터링 & 페이징: 인터페이스 리스트를 공통 인덱스로 다루면 구현체별 페이징 로직 통합 관리 용이.
- 모듈화: 각 도메인별 공통 계약을 인터페이스로 분리해 스키마 규모가 커져도 가독성 유지.
- 문서화 자동화: GraphQL 도구(graphql-codegen, GraphiQL 등)이 인터페이스 정보를 활용해 클라이언트 코드 및 문서를 자동 생성.
인터페이스는 객체 지향 프로그래밍에서의 인터페이스와 유사한 개념으로, 특정 필드와 메서드를 정의하고 이를 구현하는 다양한 타입들이 이 인터페이스를 통해 일관된 방식으로 상호작용할 수 있도록 합니다.
인터페이스의 주요 특징 1. 공통 필드 정의 : 인터페이스는 여러 타입이 공유하는 필드를 정의합니다.
이를 통해 클라이언트는 다양한 타입의 객체를 동일한 방식으로 처리할 수 있습니다.
2. 구현 타입 : 인터페이스는 하나 이상의 타입에 의해 구현될 수 있습니다.
각 구현 타입은 인터페이스에서 정의된 필드를 반드시 포함해야 하며, 추가적인 필드를 가질 수도 있습니다.
3. 유연성 : 인터페이스를 사용하면 클라이언트가 다양한 타입의 데이터를 요청할 수 있으며, 서버는 이를 통해 다양한 데이터 구조를 제공할 수 있습니다.
이는 API의 유연성을 높이고, 클라이언트의 요구에 맞춰 다양한 응답을 생성할 수 있게 합니다.
4. 타입 안전성 : GraphQL의 타입 시스템 덕분에 인터페이스를 사용하면 타입 안전성을 유지할 수 있습니다.
클라이언트는 인터페이스를 통해 어떤 타입이 반환될지 예측할 수 있으며, GraphQL 스키마를 통해 이러한 타입의 구조를 명확히 정의할 수 있습니다.
인터페이스의 사용 예 예를 들어, `Character`라는 인터페이스를 정의하고, 이를 구현하는 `Human`과 `Droid`라는 두 개의 타입을 생각해볼 수 있습니다.
```graphql interface Character { id: ID! name: String! } type Human implements Character { id: ID! name: String! homePlanet: String } type Droid implements Character { id: ID! name: String! primaryFunction: String } ``` 위의 예에서 `Character` 인터페이스는 `id`와 `name` 필드를 정의하고 있습니다.
`Human`과 `Droid` 타입은 이 인터페이스를 구현하여 각각의 고유한 필드(`homePlanet`, `primaryFunction`)를 추가합니다.
쿼리에서의 인터페이스 사용 클라이언트는 인터페이스를 통해 다양한 타입의 데이터를 요청할 수 있습니다.
예를 들어, 다음과 같은 쿼리를 작성할 수 있습니다.
```graphql { characters { id name ... on Human { homePlanet } ... on Droid { primaryFunction } } } ``` 이 쿼리는 `characters` 필드를 통해 여러 타입의 캐릭터를 요청하며, 각 캐릭터의 타입에 따라 추가적인 필드를 요청합니다.
`... on` 구문을 사용하여 각 타입에 맞는 필드를 선택적으로 요청할 수 있습니다.
결론 GraphQL의 인터페이스는 API 설계에서 중요한 역할을 하며, 다양한 타입 간의 일관성을 유지하고 클라이언트의 요구에 맞춘 유연한 데이터 구조를 제공합니다.
이를 통해 개발자는 더 나은 API를 설계할 수 있으며, 클라이언트는 다양한 데이터 타입을 효과적으로 처리할 수 있습니다.
인터페이스를 활용하면 코드의 재사용성을 높이고, API의 확장성을 개선할 수 있습니다.
작성자:
이서우 [비회원]
| 작성일자: 1년 전
2024-12-08 10:01:48
조회수: 136 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
조회수: 136 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
내용이 부정확하다면 싫어요를 클릭해주세요.