Code-first GraphQL 서버
GraphQL 스키마는 서비스에 대해 실행할 수 있는 타입, 필드, 뮤테이션의 집합을 공개함으로써 GraphQL 서비스의 계약을 정의합니다. GraphQL 서비스를 만들 때 다음 두 가지 중 하나를 선택할 수 있습니다.
- 스키마를 신뢰할 수 있는 유일한 정보 출처로 삼고, 모든 구현 코드가 그 정의를 따르도록 하는 방식
- 코드를 신뢰할 수 있는 유일한 정보 출처로 삼고, 스키마를 코드에서 생성되는 아티팩트로 만드는 방식
어느 쪽이든 완전히 동작하는 GraphQL 서비스를 만들 수 있지만, 선택하는 접근 방식에 따라 앞으로 구현할 수 있는 기능의 다양성과 구현 난이도가 달라집니다. 이 두 가지 접근 방식은 각각 "schema-first"(더 정확히는 "SDL-first")와 "code-first"라고 불립니다.
Gato GraphQL은 code-first 접근 방식을 채택하고 있습니다. 그 이유를 살펴보겠습니다.
Gato GraphQL이 code-first를 채택하는 이유
code-first 접근 방식에서는 먼저 리졸버를 코딩하고, 코드를 유일한 정보 출처로 삼아 스키마를 아티팩트로 생성합니다. 즉, 스키마는 스크립트를 실행하여 생성되며, SDL-first처럼 수동으로 작성되지 않습니다. code-first에도 스키마가 존재하므로 SDL-first가 제공하는 중요한 기능은 어느 것도 빠지지 않습니다.
하지만 code-first는 SDL-first에 비해 중요한 기능을 하나 더 제공합니다. 바로 "동적 스키마"입니다. 동적 스키마는 컨텍스트에 따라 형태와 속성을 변경할 수 있으며, 런타임에 코드를 통해 제어됩니다. 실제로 Gato GraphQL이 제공하는 모든 뛰어난 기능은 code-first 채택으로 인한 직접적인 결과입니다.
code-first의 장점
동적 스키마는 다음을 비롯한 다양한 이점을 제공합니다.
스키마의 신뢰할 수 있는 정보 출처는 GraphQL이 요구하는 것의 상위 집합입니다. 추가 속성(글로벌 필드, 글로벌 연결, 글로벌 디렉티브, 영속화된 프래그먼트 등)은 GraphQL 사양에 추가되기를 기다리지 않고도 이미 API에서 사용할 수 있습니다(사양에 추가될지 여부와 관계없이).
신뢰할 수 있는 정보 출처가 스키마에 묶여 있지 않기 때문에, 다른 시스템을 위한 스키마도 생성할 수 있습니다. GraphQL은 대상 중 하나일 뿐입니다. 예를 들어, 동일한 정보 출처에서 REST 서비스용 JSON 스키마를 생성하는 것도 가능합니다.
API는 사용자의 로그인 여부와 로그인된 사용자의 역할에 따라 동시에 퍼블릭 및 프라이빗 성격을 가질 수 있으며, PRO 멤버십 결제 여부와 같은 다른 속성에 따라 제공하는 필드의 수를 조정할 수도 있습니다.
타입은 어떤 필드를 해결할지 미리 알지 못합니다. 대신 필드 리졸버는 publish-subscribe 패턴을 사용하여 타입 리졸버에 자신을 연결하며, 필드 리졸버가 다른 필드 리졸버를 재정의할 수 있습니다. 이 기능 덕분에 API는 매우 확장하기 쉬워지며, API에 대한 범용 코드를 유지하면서 특정 클라이언트나 프로젝트에 맞게 애플리케이션 수준에서 커스터마이징할 수 있습니다.
하나의 필드는 단일 필드 리졸버만이 아니라 여러 필드 리졸버에 의해 처리될 수 있습니다. 체인의 각 필드 리졸버는 런타임에 어떤 속성을 기반으로 필드를 처리할지 여부를 결정하거나 체인을 따라 넘길 수 있습니다. 예를 들어, 필드 인수 "source: testing"이 전달된 경우에만 사용되는 특수 필드 리졸버를 두어, 일반 출시 전에 프로덕션 환경의 일부 사이트에서 테스트할 수 있습니다. 동일한 전략을 통해 다른 곳에 의도치 않은 부작용을 발생시키지 않으면서 특정 클라이언트나 환경을 위한 빠른 버그 수정을 제공하는 것도 가능합니다.
타입과 인터페이스는 서드파티와의 충돌을 방지하기 위해 자동으로 네임스페이스가 부여될 수 있습니다.