GraphQL Best Practices
GraphQL 사양은 네트워크 처리, 권한 부여 및 페이지 매김과 같이 API가 직면한 몇 가지 중요한 문제에 대해 의도적으로 침묵합니다. 이것은 GraphQL을 사용할 때 이러한 문제에 대한 솔루션이 없다는 것을 의미하는 것이 아니라 GraphQL이 무엇인지에 대한 설명을 벗어나 일반적인 관행일 뿐입니다.1)
이 섹션의 기사는 복음으로 간주되어서는 안 되며 어떤 경우에는 다른 접근 방식을 위해 정당하게 무시될 수 있습니다. 일부 기사에서는 GraphQL 서비스 설계 및 배포와 관련하여 Facebook 내에서 개발된 철학 중 일부를 소개하는 반면, 다른 기사에서는 HTTP를 통한 서비스 및 인증 수행과 같은 일반적인 문제를 해결하기 위한 보다 전술적인 제안을 제공합니다.2)
다음은 GraphQL 서비스가 보유하는 보다 일반적인 모범 사례 및 의견이 있는 입장에 대한 간략한 설명이지만 이 섹션의 각 기사에서는 이러한 주제와 기타 주제에 대해 더 깊이 있게 설명합니다.3)
HTTP
GraphQL은 일반적으로 서비스의 전체 기능 세트를 표현하는 단일 끝점을 통해 HTTP를 통해 제공됩니다. 이는 각각 단일 리소스를 노출하는 URL 모음을 노출하는 REST API와 대조됩니다. GraphQL은 리소스 URL 모음과 함께 사용할 수 있지만 GraphiQL과 같은 도구와 함께 사용하기가 더 어려워질 수 있습니다.4)
HTTP를 통한 검색에서 이에 대해 자세히 읽어보세요.5)
JSON (with GZIP)
GraphQL 서비스는 일반적으로 JSON을 사용하여 응답하지만 GraphQL 사양에는 JSON이 필요하지 않습니다. JSON은 더 나은 네트워크 성능을 약속하는 API 계층에 대한 이상한 선택처럼 보일 수 있지만 대부분 텍스트이기 때문에 GZIP으로 매우 잘 압축됩니다.6)
모든 프로덕션 GraphQL 서비스에서 GZIP을 활성화하고 클라이언트가 헤더를 보내도록 권장합니다.7)
Accept-Encoding: gzip
JSON은 클라이언트 및 API 개발자에게도 매우 친숙하며 읽기 및 디버그하기 쉽습니다. 사실, GraphQL 구문은 부분적으로 JSON 구문에서 영감을 받았습니다.8)
Versioning
GraphQL 서비스가 다른 REST API처럼 버전 관리되는 것을 막는 것은 없지만 GraphQL은 GraphQL 스키마의 지속적인 발전을 위한 도구를 제공하여 버전 관리를 피하는 데 강한 의견을 가지고 있습니다.9)
대부분의 API 버전을 사용하는 이유는 무엇입니까? API 엔드포인트에서 반환된 데이터에 대한 제어가 제한되어 있는 경우 모든 변경은 주요 변경으로 간주될 수 있으며 주요 변경에는 새 버전이 필요합니다. API에 새로운 기능을 추가하는 데 새 버전이 필요한 경우, 자주 릴리스하고 많은 증분 버전을 보유하는 것과 API의 이해도 및 유지 관리 가능성 사이에서 절충안이 발생합니다.10)
대조적으로, GraphQL은 명시적으로 요청된 데이터만 반환하므로 주요 변경 사항을 생성하지 않고 새 유형 및 해당 유형에 대한 새 필드를 통해 새로운 기능을 추가할 수 있습니다. 이로 인해 항상 주요 변경 사항을 피하고 버전 없는 API를 제공하는 일반적인 관행이 생겼습니다.11)
Nullability
“null”을 인식하는 대부분의 유형 시스템은 공통 유형과 해당 유형의 nullable 버전을 모두 제공하므로 명시적으로 선언되지 않는 한 기본 유형에는 “null”이 포함되지 않습니다. 그러나 GraphQL 유형 시스템에서 모든 필드는 기본적으로 null을 허용합니다. 이는 데이터베이스 및 기타 서비스가 지원하는 네트워크 서비스에서 문제가 발생할 수 있는 많은 일이 있기 때문입니다. 데이터베이스가 다운될 수 있고 비동기 작업이 실패할 수 있으며 예외가 throw될 수 있습니다. 단순한 시스템 오류를 넘어 승인은 종종 세분화될 수 있습니다. 요청 내의 개별 필드는 다른 승인 규칙을 가질 수 있습니다.12)
모든 필드를 null 허용으로 기본 설정하면 이러한 이유로 인해 요청에 대한 완전한 실패가 아니라 해당 필드만 “null”을 반환할 수 있습니다. 대신, GraphQL은 요청되는 경우 필드가 “null”을 반환하지 않을 것임을 클라이언트에 보장하는 null이 아닌 유형의 변형을 제공합니다. 대신 오류가 발생하면 이전 상위 필드가 대신 “null”이 됩니다.13))
GraphQL 스키마를 설계할 때 잘못될 수 있는 모든 문제와 “null”이 실패한 필드에 적절한 값인지를 염두에 두는 것이 중요합니다. 일반적으로 그렇지 않은 경우가 있습니다. 이러한 경우에는 null이 아닌 유형을 사용하여 보장하십시오.14)
Pagination
GraphQL 유형 시스템에서는 일부 필드가 값 목록을 반환할 수 있지만 더 긴 값 목록의 페이지 매김은 API 디자이너에게 맡깁니다. 페이지 매김을 위한 가능한 API 디자인은 다양하며 각각 장단점이 있습니다.15)
일반적으로 긴 목록을 반환할 수 있는 필드는 목록의 특정 영역을 지정할 수 있도록 “first” 및 “after” 인수를 허용합니다. 여기서 “after”는 목록에 있는 각 값의 고유 식별자입니다.16)
궁극적으로 기능이 풍부한 페이지 매김으로 API를 설계하면서 “연결”이라는 모범 사례 패턴이 탄생했습니다. Relay와 같은 일부 GraphQL용 클라이언트 도구는 연결 패턴을 알고 있으며 GraphQL API가 이 패턴을 사용할 때 클라이언트 측 페이지 매김을 자동으로 지원할 수 있습니다.17)
Read more about this in the article on Pagination.
Server-side Batching & Caching
GraphQL은 서버에서 깨끗한 코드를 작성할 수 있도록 설계되었습니다. 여기서 모든 유형의 모든 필드에는 해당 값을 해결하기 위한 단일 목적에 초점을 맞춘 기능이 있습니다. 그러나 추가 고려 없이 순진한 GraphQL 서비스는 매우 “수다스럽거나” 데이터베이스에서 데이터를 반복적으로 로드할 수 있습니다.18)
이는 일반적으로 백엔드에서 데이터에 대한 여러 요청을 짧은 기간 동안 수집한 다음 Facebook의 DataLoader와 같은 도구를 사용하여 기본 데이터베이스 또는 마이크로 서비스에 단일 요청으로 전달하는 일괄 처리 기술로 해결됩니다.19)