GraphQL은 API를 위한 쿼리 언어이자 기존 데이터로 이러한 쿼리를 실행하는 런타임입니다. API에서 사용할 수 있는 데이터에 대한 포괄적이고 명확한 설명을 제공하며, 클라이언트가 불필요한 요청 없이 필요한 정보를 정확하게 요청할 수 있게 하고, 시간이 지남에 따라 API의 발전을 용이하게 하며, 강력한 개발자 도구를 지원합니다.
GraphQL 접근 제어 및 쿼리 최적화
접근 제어
인증은 사용자, 세션 또는 컨텍스트가 특정 작업을 수행하거나 특정 데이터를 볼 수 있는 접근 제어 목록(ACL)을 가지고 있는지를 결정하는 규칙 또는 비즈니스 로직의 집합입니다.
이러한 행동은 비즈니스 로직 계층에서 시행되어야 합니다. 인증 로직을 GraphQL 계층 내에 직접 배치하는 것이 유혹적일 수 있지만, 일반적으로는 다른 곳에서 처리하는 것이 더 적절합니다.
쿼리 최적화
GraphQL 쿼리 최적화는 응답 시간을 개선하고 서버 부하를 줄이기 위해 불필요한 데이터 가져오기 및 처리를 최소화하는 기술을 포함합니다. 이는 더 효율적인 애플리케이션을 제공하여 사용자 경험을 향상시키고, 사용자 참여 및 유지율을 높이며, 서버 확장성을 증가시킵니다.
GraphQL 쿼리 최적화 방법
- N+1 (배치 로딩)
- 과도 과다 가져오기 및 과소 가져오기
- 지연 시간을 줄이기 위한 캐싱
- 페이지네이션
GraphQL 접근 제어 및 GraphQL 쿼리 최적화 향상
권한 엔진은 ACL(접근 제어 목록)을 사용하여 노드 및 필드 권한을 검증하고 권한에 따라 GraphQL 쿼리를 최적화합니다. 또한 N+1 리졸버는 쿼리를 통합하여 성능을 향상시킵니다. 이 접근 방식은 N+1 문제를 해결합니다.
행위자
- GraphQL 쿼리: 클라이언트가 특정 데이터를 가져오기 위해 GraphQL 서버에 보내는 요청입니다.
- GraphQL 엔진: GraphQL 쿼리를 실행할 수 있게 해주는 서비스를 의미합니다.
- 권한 엔진: ACL을 사용하여 노드 및 필드의 권한을 검증하고 필드 권한에 따라 GraphQL 쿼리를 최적화합니다.
- N+1 리졸버: 여러 데이터베이스 쿼리와 관련된 오버헤드와 지연을 줄여 성능과 효율성을 향상시킵니다.
접근 제어 강화
기존 구현
앱에 제품, 공급업체 및 주소가 있다고 가정해 보겠습니다. 공급업체 및 주소 데이터에 접근하려면 사용자 인증이 필요하며, 이는 리졸버에서 쉽게 처리할 수 있습니다.
그러나 공급업체 데이터는 관리자 사용자에게만 제한되며, 일부 공급업체 필드는 특정 역할에만 접근할 수 있습니다. 반면, 제품은 공개되어 있으며 제품 소유자 역할로 볼 수 있습니다. 언급된 쿼리(그림 3)를 실행하면 제품 데이터와 관련된 공급업체 및 주소 데이터가 반환되어 보안 문제가 발생할 수 있습니다.
강화된 구현
쿼리의 노드 및 필드는 사용자의 권한에 따라 검증되며 최적화된 GraphQL 쿼리가 생성됩니다.
그림 4는 Node.js를 사용하여 GraphQL API에서 사용자 정의 인증을 구현하는 방법의 예입니다. 이 코드에서는 역할이 Authorization 헤더에서 추출된 후 쿼리와 함께 사용되어 권한을 검증합니다.
이 예에서는 세션이나 요청에서 사용자의 역할과 권한을 사용하여 GraphQL 스키마의 특정 쿼리 및 변형에 대한 접근을 제어하고 있습니다. 우리는 모든 사용자에 대한 GraphQL 스키마에서 역할 및 권한 규칙을 정의했습니다.
이 방법은 모든 노드 및 필드에서 역할과 권한을 재귀적으로 확인합니다. 노드나 필드가 허용되지 않으면 구성에 따라 다음 작업 중 하나를 수행합니다:
- 노드 또는 필드를 제거합니다.
- 오류 메시지가 있는 필드 또는 노드를 반환합니다.
- 예외를 발생시킵니다.
GraphQL 쿼리가 스키마에 대해 검증되면 이 방법은 최적화된 GraphQL 쿼리를 반환합니다.
N+1을 사용한 ORM 쿼리 최적화 강화
기존 구현
쿼리의 성능에 영향을 미치는 기술적 문제입니다. 데이터베이스에 액세스하기 위해 ORM(Object-Relational Mapping) 프레임워크를 사용하는 애플리케이션에서 발생할 수 있습니다.일반적으로 애플리케이션이 데이터베이스에서 관련된 엔티티 컬렉션을 로드해야 할 때 발생합니다.
2개의 제품이 있다고 가정해 봅시다. 제품을 검색하려면 1개의 쿼리를 수행하고 각 제품에 대해 개별적으로 공급업체를 가져 오기 위해 2개의 추가 쿼리를 실행해야 합니다.
하나는 제품 목록을 검색하고 별도의 쿼리가 각 제품의 공급업체를 가져옵니다. 공급업체 쿼리 수는 제품 수와 같습니다.
향상된 구현
요청이 N+1 리졸버에 도달하면 N+1 리졸버가 주요 데이터에 대한 단일 쿼리로 데이터베이스 요청 수를 최소화하는 쿼리 최적화를 수행하여 관련 데이터에 대한 추가 쿼리를 효과적으로 줄여 N+1 문제를 완화합니다.
- 주요 데이터 쿼리: 애플리케이션에 필요한 주요 데이터 집합을 검색하는 단일 쿼리입니다.
- 관련 데이터 쿼리: 데이터 집합을 완성하는 데 필요한 관련 데이터를 가져오는 추가 쿼리입니다.
모든 쿼리 리졸버가 완료되면 서버는 최적화된 데이터를 JSON 형식으로 클라이언트에 반환합니다.
결론
우리는 GraphQL API를 보호하기 위해 세밀한 인가 메커니즘을 구현하는 것이 중요하다는 것을 강조했습니다. 이는 노드 수준 및 필드 수준 보안을 모두 포함합니다.
이 기사에서 설명한 대로, N+1 문제는 최적화되지 않은 쿼리로 인해 GraphQL에서 과도한 데이터베이스 호출이 발생할 때 발생합니다. 우리는 N+1 문제를 극복하기 위한 해결책을 제공했습니다. 이는 데이터베이스 서버 리소스 사용을 줄이고 비용 절감 및 더 나은 확장성을 가져옵니다. 또한 쿼리 성능을 향상시킴으로써 쿼리 응답 시간을 줄이는 것을 통해 사용자 경험을 향상시킵니다.
Source:
https://dzone.com/articles/optimizing-fine-grained-graphql-access-control-and-queries