open:graphql-best-practices

GraphQL Best Practices

GraphQL 사양은 네트워크 처리, 권한 부여 및 페이지 매김과 같이 API가 직면한 몇 가지 중요한 문제에 대해 의도적으로 침묵합니다. 이것은 GraphQL을 사용할 때 이러한 문제에 대한 솔루션이 없다는 것을 의미하는 것이 아니라 GraphQL이 무엇인지에 대한 설명을 벗어나 일반적인 관행일 뿐입니다.1)

이 섹션의 기사는 복음으로 간주되어서는 안 되며 어떤 경우에는 다른 접근 방식을 위해 정당하게 무시될 수 있습니다. 일부 기사에서는 GraphQL 서비스 설계 및 배포와 관련하여 Facebook 내에서 개발된 철학 중 일부를 소개하는 반면, 다른 기사에서는 HTTP를 통한 서비스 및 인증 수행과 같은 일반적인 문제를 해결하기 위한 보다 전술적인 제안을 제공합니다.2)

다음은 GraphQL 서비스가 보유하는 보다 일반적인 모범 사례 및 의견이 있는 입장에 대한 간략한 설명이지만 이 섹션의 각 기사에서는 이러한 주제와 기타 주제에 대해 더 깊이 있게 설명합니다.3)

GraphQL은 일반적으로 서비스의 전체 기능 세트를 표현하는 단일 끝점을 통해 HTTP를 통해 제공됩니다. 이는 각각 단일 리소스를 노출하는 URL 모음을 노출하는 REST API와 대조됩니다. GraphQL은 리소스 URL 모음과 함께 사용할 수 있지만 GraphiQL과 같은 도구와 함께 사용하기가 더 어려워질 수 있습니다.4)

HTTP를 통한 검색에서 이에 대해 자세히 읽어보세요.5)

GraphQL 서비스는 일반적으로 JSON을 사용하여 응답하지만 GraphQL 사양에는 JSON이 필요하지 않습니다. JSON은 더 나은 네트워크 성능을 약속하는 API 계층에 대한 이상한 선택처럼 보일 수 있지만 대부분 텍스트이기 때문에 GZIP으로 매우 잘 압축됩니다.6)

모든 프로덕션 GraphQL 서비스에서 GZIP을 활성화하고 클라이언트가 헤더를 보내도록 권장합니다.7)

Accept-Encoding: gzip

JSON은 클라이언트 및 API 개발자에게도 매우 친숙하며 읽기 및 디버그하기 쉽습니다. 사실, GraphQL 구문은 부분적으로 JSON 구문에서 영감을 받았습니다.8)

GraphQL 서비스가 다른 REST API처럼 버전 관리되는 것을 막는 것은 없지만 GraphQL은 GraphQL 스키마의 지속적인 발전을 위한 도구를 제공하여 버전 관리를 피하는 데 강한 의견을 가지고 있습니다.9)

대부분의 API 버전을 사용하는 이유는 무엇입니까? API 엔드포인트에서 반환된 데이터에 대한 제어가 제한되어 있는 경우 모든 변경은 주요 변경으로 간주될 수 있으며 주요 변경에는 새 버전이 필요합니다. API에 새로운 기능을 추가하는 데 새 버전이 필요한 경우, 자주 릴리스하고 많은 증분 버전을 보유하는 것과 API의 이해도 및 유지 관리 가능성 사이에서 절충안이 발생합니다.10)

대조적으로, GraphQL은 명시적으로 요청된 데이터만 반환하므로 주요 변경 사항을 생성하지 않고 새 유형 및 해당 유형에 대한 새 필드를 통해 새로운 기능을 추가할 수 있습니다. 이로 인해 항상 주요 변경 사항을 피하고 버전 없는 API를 제공하는 일반적인 관행이 생겼습니다.11)

“null”을 인식하는 대부분의 유형 시스템은 공통 유형과 해당 유형의 nullable 버전을 모두 제공하므로 명시적으로 선언되지 않는 한 기본 유형에는 “null”이 포함되지 않습니다. 그러나 GraphQL 유형 시스템에서 모든 필드는 기본적으로 null을 허용합니다. 이는 데이터베이스 및 기타 서비스가 지원하는 네트워크 서비스에서 문제가 발생할 수 있는 많은 일이 있기 때문입니다. 데이터베이스가 다운될 수 있고 비동기 작업이 실패할 수 있으며 예외가 throw될 수 있습니다. 단순한 시스템 오류를 넘어 승인은 종종 세분화될 수 있습니다. 요청 내의 개별 필드는 다른 승인 규칙을 가질 수 있습니다.12)

모든 필드를 null 허용으로 기본 설정하면 이러한 이유로 인해 요청에 대한 완전한 실패가 아니라 해당 필드만 “null”을 반환할 수 있습니다. 대신, GraphQL은 요청되는 경우 필드가 “null”을 반환하지 않을 것임을 클라이언트에 보장하는 null이 아닌 유형의 변형을 제공합니다. 대신 오류가 발생하면 이전 상위 필드가 대신 “null”이 됩니다.13))

GraphQL 스키마를 설계할 때 잘못될 수 있는 모든 문제와 “null”이 실패한 필드에 적절한 값인지를 염두에 두는 것이 중요합니다. 일반적으로 그렇지 않은 경우가 있습니다. 이러한 경우에는 null이 아닌 유형을 사용하여 보장하십시오.14)

GraphQL 유형 시스템에서는 일부 필드가 값 목록을 반환할 수 있지만 더 긴 값 목록의 페이지 매김은 API 디자이너에게 맡깁니다. 페이지 매김을 위한 가능한 API 디자인은 다양하며 각각 장단점이 있습니다.15)

일반적으로 긴 목록을 반환할 수 있는 필드는 목록의 특정 영역을 지정할 수 있도록 “first” 및 “after” 인수를 허용합니다. 여기서 “after”는 목록에 있는 각 값의 고유 식별자입니다.16)

궁극적으로 기능이 풍부한 페이지 매김으로 API를 설계하면서 “연결”이라는 모범 사례 패턴이 탄생했습니다. Relay와 같은 일부 GraphQL용 클라이언트 도구는 연결 패턴을 알고 있으며 GraphQL API가 이 패턴을 사용할 때 클라이언트 측 페이지 매김을 자동으로 지원할 수 있습니다.17)

Read more about this in the article on Pagination.

GraphQL은 서버에서 깨끗한 코드를 작성할 수 있도록 설계되었습니다. 여기서 모든 유형의 모든 필드에는 해당 값을 해결하기 위한 단일 목적에 초점을 맞춘 기능이 있습니다. 그러나 추가 고려 없이 순진한 GraphQL 서비스는 매우 “수다스럽거나” 데이터베이스에서 데이터를 반복적으로 로드할 수 있습니다.18)

이는 일반적으로 백엔드에서 데이터에 대한 여러 요청을 짧은 기간 동안 수집한 다음 Facebook의 DataLoader와 같은 도구를 사용하여 기본 데이터베이스 또는 마이크로 서비스에 단일 요청으로 전달하는 일괄 처리 기술로 해결됩니다.19)


1)
The GraphQL specification is intentionally silent on a handful of important issues facing APIs such as dealing with the network, authorization, and pagination. This doesn't mean that there aren't solutions for these issues when using GraphQL, just that they're outside the description about what GraphQL is and instead just common practice.
2)
The articles in this section should not be taken as gospel, and in some cases may rightfully be ignored in favor of some other approach. Some articles introduce some of the philosophy developed within Facebook around designing and deploying GraphQL services, while others are more tactical suggestions for solving common problems like serving over HTTP and performing authorization.
3)
Following are brief descriptions of some of the more common best practices and opinionated stances held by GraphQL services, however each article in this section will go into more depth on these and other topics.
4)
GraphQL is typically served over HTTP via a single endpoint which expresses the full set of capabilities of the service. This is in contrast to REST APIs which expose a suite of URLs each of which expose a single resource. While GraphQL could be used alongside a suite of resource URLs, this can make it harder to use with tools like GraphiQL.
5)
Read more about this in Serving over HTTP.
6)
GraphQL services typically respond using JSON, however the GraphQL spec does not require it. JSON may seem like an odd choice for an API layer promising better network performance, however because it is mostly text, it compresses exceptionally well with GZIP.
7)
It's encouraged that any production GraphQL services enable GZIP and encourage their clients to send the header:
8)
JSON은 클라이언트 및 API 개발자에게도 매우 친숙하며 읽기 및 디버그하기 쉽습니다. 사실, GraphQL 구문은 부분적으로 JSON 구문에서 영감을 받았습니다.
9)
GraphQL 서비스가 다른 REST API처럼 버전 관리되는 것을 막는 것은 없지만 GraphQL은 GraphQL 스키마의 지속적인 발전을 위한 도구를 제공하여 버전 관리를 피하는 데 강한 의견을 가지고 있습니다.
10)
Why do most APIs version? When there's limited control over the data that's returned from an API endpoint, any change can be considered a breaking change, and breaking changes require a new version. If adding new features to an API requires a new version, then a tradeoff emerges between releasing often and having many incremental versions versus the understandability and maintainability of the API.
11)
In contrast, GraphQL only returns the data that's explicitly requested, so new capabilities can be added via new types and new fields on those types without creating a breaking change. This has led to a common practice of always avoiding breaking changes and serving a versionless API.
12)
Most type systems which recognise “null” provide both the common type and the nullable version of that type, whereby default types do not include “null” unless explicitly declared. However, in a GraphQL type system, every field is nullable by default. This is because there are many things that can go awry in a networked service backed by databases and other services. A database could go down, an asynchronous action could fail, an exception could be thrown. Beyond simply system failures, authorization can often be granular, where individual fields within a request can have different authorization rules.
13)
(By defaulting every field to nullable, any of these reasons may result in just that field returned “null” rather than having a complete failure for the request. Instead, GraphQL provides non-null variants of types which make a guarantee to clients that if requested, the field will never return “null”. Instead, if an error occurs, the previous parent field will be “null” instead.
14)
When designing a GraphQL schema, it's important to keep in mind all the problems that could go wrong and if “null” is an appropriate value for a failed field. Typically it is, but occasionally, it's not. In those cases, use non-null types to make that guarantee.
15)
The GraphQL type system allows for some fields to return lists of values, but leaves the pagination of longer lists of values up to the API designer. There are a wide range of possible API designs for pagination, each of which has pros and cons.
16)
Typically fields that could return long lists accept arguments “first” and “after” to allow for specifying a specific region of a list, where “after” is a unique identifier of each of the values in the list.
17)
Ultimately designing APIs with feature-rich pagination led to a best practice pattern called “Connections”. Some client tools for GraphQL, such as Relay, know about the Connections pattern and can automatically provide support for client-side pagination when a GraphQL API employs this pattern.
18)
GraphQL is designed in a way that allows you to write clean code on the server, where every field on every type has a focused single-purpose function for resolving that value. However without additional consideration, a naive GraphQL service could be very “chatty” or repeatedly load data from your databases.
19)
This is commonly solved by a batching technique, where multiple requests for data from a backend are collected over a short period of time and then dispatched in a single request to an underlying database or microservice by using a tool like Facebook's DataLoader.
  • open/graphql-best-practices.txt
  • 마지막으로 수정됨: 2022/09/02 06:28
  • 저자 127.0.0.1