일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Bastion Server
- AWS
- gitops
- 윈도우키보드
- goland
- body size
- 대규모 시스템 설계
- Kubernetes
- Golines
- golang
- Buffered channel
- Logrus
- System Design
- notification system
- go
- intellij ide
- GoF 디자인패턴
- 배포 파이프라인
- tenneling
- AWS Infra
- Helm V3
- 배포 프로세스
- 컴포지트패턴
- apollo router
- Intellij
- UnBuffered channel
- GoF
- http 413
- 디자인패턴
- Infra
- Today
- Total
Fall in IT.
GraphQL 보안과 성능 개선 방법 본문
안녕하세요.
오늘은 GraphQL 보안과 성능 개선 방법에 대해서 알아보겠습니다.
GraphQL 보안과 성능 개선 방법
- 타임아웃 설정
- 데이터 개수 제한
- 쿼리 깊이 제한
- 쿼리 복잡도 제한
- Filed Collection
GraphQL로 서버를 만들경우 클라이언트쪽 구현에 더 많은 자유도와 유연성을 부여할 수 있습니다.
여러개의 데이터를 조회할때도 한번의 쿼리로 조회(UnderFetching 해결)가 가능하고, 원하는 필드만 조회할 수 있습니다. (OverFetching 해결)
그러나, 자유도가 높은 만큼 한번의 쿼리에 너무 많은 데이터를 요청하여 문제가 발생할 수 있습니다.
한번에 너무 많은 데이터를 요청할 경우 서버 성능이 떨어질 뿐만 아니라 서비스가 다운 될 수 있습니다. 이런 경우를 대비해서 GraphQL 서비스의 보안과 성능을 개선할 수 있는 방법을 알아보겠습니다.
타임아웃 설정
각각의 요청에 처리하는 시간을 제한하는 방법입니다.
악성 혹은 대량의 쿼리가 들어올 경우를 대비해 타임아웃 시간을 설정해두고 일정시간 이상 걸리는 쿼리는 에러를 던지도록 처리하여 서버의 상태를 유지할 수 있습니다.
서버로 들어오는 모든 요청에 타임아웃을 설정할 수도 있고, 리졸버에 개별적으로 설정할 수도 있습니다.
데이터 개수 제한
쿼리가 반환하는 개수를 제한하는 방법입니다.
페이지네이션 처리를 할 경우 한 페이지에 가져올 데이터의 수(ex. first: 50)를 설정할 수 있는데, 이 숫자의 최대값을 지정해두는 방식입니다.
input으로 들어오는 인자값의 설정값의 제한만 걸어두면 되므로 간단하게 설정할 수 있습니다.
쿼리 깊이 제한
GraphQL은 관계된 데이터들을 타고들어가면서 조회가 가능한데, 제한이 없을 경우 무한히 조회할 수도 있습니다.
예를들면, User와 Post의 관계에서 하나의 포스트에는 올린 유저의 정보가 있고 유저의 정보에는 올린 포스트들이 있고 포스트들 안에는 태그된 유저들의 정보가 있고.. 이런식으로 매우 깊이가 깊은 복잡한 쿼리가 생성될 수 있습니다.
특히, 배열 형태의 오브젝트가 쿼리되는 경우 데이터의 양은 기하급수적으로 증가하게 됩니다.
query getPhoto($id: ID!) {
Photo(id: $id) { // 1 depth
name
url
...(생략)...
postedBy { // 2 depth
name
age
...(생략)...
postedPhotos { // 3 depth
name
url
...(생략)...
taggedUsers { // 4 depth
name
age
...(생략)...
}
}
}
}
}
이런 경우를 대비해서 쿼리 깊이의 제한을 설정할 수 있습니다.
만약, 깊이 제한(depth limit)을 3으로 설정할 경우 위와 같은 쿼리가 발생했을때 서버는 쿼리 실행을 중단하고 에러를 반환하여 서버의 안정성을 높여줍니다.
쿼리 복잡도 제한
쿼리 복잡도를 측정하여 설정한 복잡도를 넘어설 경우 에러를 반환하는 방법입니다.
쿼리의 깊이가 깊지 않더라도 쿼리에 포함된 필드가 많고 연산 비용이 높은 필드가 있을 경우 쿼리 복잡도는 높아질 수 있습니다.
쿼리 복잡도는 각 필드에 복잡도(weight) 값을 매겨 놓고 복잡도 값의 전체 합을 계산합니다. 쿼리 복잡도를 매길 때 수행 비용이 높은 리졸버가 있다면 해당하는 필드에 높은 복잡도 값을 매기면 됩니다.
Filed Collection
Field Collection은 클라이언트 측에서 요청한 필드를 확인하고 원하는 필드에 대한 정보만 조회할 수 있도록 하는 기능입니다.
GraphQL은 클라이언트 측에서 원하는 필드만 조회해서 사용할 수 있는 장점이 있습니다. 서버 또한 하나의 endpoint만 만들어두면 되기 때문에 개발 효율이 높아지게 됩니다.
그러나, 문제는 클라이언트 측에서 요청하지 않은 필드값을 만들기위해 연산비용이 높은 로직도 매번 동작한다는 사실입니다.
이를 해결하기 위해서 field collection을 사용하여 클라이언트 측에서 요청한 필드를 확인하고 연산이 높은 필드를 요청하지 않았다면 해당 연산은 제외하도록 코드를 작성하여 성능을 높일 수 있습니다.
참조
- https://gqlgen.com/reference/field-collection/
- https://entgo.io/docs/tutorial-todo-gql-field-collection/
- 도서, 웹 앱 API 개발을 위한 GraphQL
'기타' 카테고리의 다른 글
GoLand(IntelliJ) 라이브 템플릿 사용방법 (0) | 2023.02.07 |
---|---|
TLS에 대하여 (SSL, HTTPS랑 다른건가?) (0) | 2023.01.25 |
Helm 간단히 알아보기(Kubernetes) (0) | 2021.06.24 |
vscode 자동완성 단축키 설정방법 (2) | 2021.06.06 |
SSH 공개키 간단하게 만드는 방법 (0) | 2021.04.18 |