일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- Spring
- 클라우드
- 자료구조
- feign
- Intellj
- PL/SQL
- 코딩
- golang
- aws
- Spring Boot
- 백준
- db
- 자바
- SQL
- 오라클
- MST
- 디자인 패턴
- Jenkins
- 운영체제
- DP
- Kafka
- Spring Cloud
- 페이징
- JPA
- MVC
- Spring Cloud Feign
- retry
- 데이터베이스
- 알고리즘
- 쿼리
- Today
- Total
justgo_developer
GraphQL(Graph + Query Language) with Spring-boot 본문
GraphQL(Graph + Query Language) with Spring-boot
목차
- GraphQL 개념
- GraphQL 배경
- GraphQL 원리
- GraphQL 구조
- GraphQL 적용 예제
- GraphQL 단점
개요
MSA 기반 프로젝트를 진행하면서, 한 서비스에 테이블 갯수가 50~60종이고 각 테이블 항목수가 500개 이상으로 관리되는 항목들이여서 실제 타서비스에서 요청하는 테이블, 항목 들이 모두 달랐다.
따라서, 타 서비스에 API를 제공하기에는 너무 많은 EndPoint를 개발하여야 했다.
이 문제를 해결하기 위해 GraphQL이라는 언어를 사용하여 개발을 진행했었다.
이직 성공 후 새로운 직장에 가기 전,
이전 직장에서 사용했던 GraphQL 언어에 대해서 다시 한번 복습해보며 적용해보려고 합니다.
- Spring-boot, maven, jpa, h2 기반으로 예제 작성하였습니다.
상세
1. GraphQL 개념
GraphQL이란 페이스북에서 개발하여 발표한 내용으로 Graph + Query Language의 약자로 정확하게는 언어입니다. SQL(Structured Query Language)과 마찬가지로 기본적으로 데이터를 쿼리하기 위하여 만들어졌으나 SQL은 데이터베이스에 직접 질의를 하기 위해 만들어졌고 GraphQL은 서비스에 데이터를 질의하기 위해서 제작 되었습니다.
2. GraphQL 배경
GraphQL이 등장한 배경은 REST API의 한계 때문에 등장하게 되었습니다.
REST API는 Over-Fetching과 Under-Fetching 2가지 문제를 가지고 있습니다.
- Over-Fetching
: 사용하지 않는 데이터까지 많이 가져오는 것 - Under-Fetching
: EndPoint가 달라 여러번 API를 호출해 데이터를 가져오는 것
GraphQL은 이러한 문제점들을 해결하기 위해
EndPoint 하나로 한번에 호출하고 한번에 응답받기 위해 개발되었습니다.
3. GraphQL 원리
GraphQL 파이프라인
GraphQL vs REST API
REST API는 다양한 EndPoint가 존재하지만,
GraphQL은 하나의 EndPoint가 존재하여 한번의 네트워크 호출로 처리가 가능하다.
4. GraphQL 구조
- Schema : 데이터 타입의 집합으로 API 문서 역할을 합니다.
- Operation : Operation에는 쿼리(query), 뮤테이션(mutation), 구독(subscription) 세 가지 종류가 있습니다.
- query : 데이터 조회(Read)
- mutation : 데이터 조작(Create, Update, Delete)
- subscription : 구독/발행 모델을 기반으로 WebSocket을 통해 실시간 양방향 통신 기능을 제공
- Resolver : Operation으로 들어온 내용을 어떻게 해결할지를 정의하는 역할입니다.
- Instrospection : 간단하게 문서화라고 표현할 수 있습니다. 대부분의 GraphQL 프레임워크들이 문서화 도구가 내장이 되어 있습니다.
5. GraphQL 적용 예제
Spring boot에서 GraphQL을 이용하려면 아래 2가지 denpendency를 추가하여야합니다.
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>5.0.2</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>5.2.4</version>
</dependency>
GraphQL schema에 대한 정의 파일은 .graphqls 확장자로 저장하여야 합니다.
spring-boot-graphql-starter는 graphql 스키마 파일을 자동으로 찾습니다.
메서드의 이름은 다음 중 하나여야하는 약속을 가지고 있습니다.
- <필드>
- is – 필드가 Boolean 유형 인 경우에만
- get <필드>
위의 3가지 네이밍 규칙이 맞다면 자동으로 .graphqls 정의된 schema와 매핑됩니다.
- query(R) 일경우 GraphQLQueryResolver을 implements 하여 로직 구현합니다.
- mutation(CUD) 일경우 GraphQLMutationResolver를 implments하여 로직 구현합니다.
type Query {
paymentByProductId(productId : ID) : Payment
existenceProductId(productId : ID) : Boolean
}
type Mutation {
savePayment(productId: ID, title: String) : Payment
}
type Payment {
productId : ID!
title : String
totalInvestingAmount : Int
currentInvestingAmount : Int
investerCnt : Int
startedAt : String
finishedAt : String
investmentStatus : String
}
GrahphQL schema에 대한 정의
: 3가지 API 정의
- Query : ID로 조회, ID 존재 확인
- Mutation : 신규 저장
package com.server.danal.graphql.domain;
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import com.server.danal.graphql.domain.entity.Payment;
import com.server.danal.graphql.store.PaymentStore;
import org.springframework.stereotype.Component;
@Component
public class PaymentGraphQLQuery implements GraphQLQueryResolver {
private PaymentStore paymentStore;
public PaymentGraphQLQuery(PaymentStore paymentStore) {
this.paymentStore = paymentStore;
}
public Payment getPaymentByProductId(int productId) {
return paymentStore.findById(productId);
}
public boolean isExistenceProductId(int productId) {
return paymentStore.existProductId(productId);
}
}
- Query : GraphQLQueryResolver, get<필드>, is<필드> Naming 규칙 사용
[ GraphQL 호출 결과 ]
package com.server.danal.graphql.domain;
import com.coxautodev.graphql.tools.GraphQLMutationResolver;
import com.server.danal.graphql.domain.entity.Payment;
import com.server.danal.graphql.store.PaymentStore;
import org.springframework.stereotype.Component;
@Component
public class PaymentGraphQLMutation implements GraphQLMutationResolver {
private PaymentStore paymentStore;
public PaymentGraphQLMutation(PaymentStore paymentStore){
this.paymentStore = paymentStore;
}
public Payment savePayment(int productId, String title) {
return paymentStore.savePayment(productId, title);
}
}
- Mutation : GraphQLMutationResolver, <필드> Naming 규칙 사용[ GraphQL 호출 결과 ]
6, GraphQL 단점
GraphQL은 REST API와 달리 1개의 EndPoint로 모두 해결할 수 있으며,HTTP 요청 횟수를 줄일 수 있다.
그렇다면 단점은 무엇일까?
구글링을 해본 결과 크게 3가지 단점이 있다고 한다.
- HTTP 캐싱 : 캐싱이 복잡(하나의 EndPoint)
- 완성된 명세가 존재하지 않는다.(ex. 파일 업로드)
- 잘못된 요청 필터링 어려움
'IT > Spring-boot' 카테고리의 다른 글
[Spring] Spring Bean 주입 + 팩토리 메소드 디자인 패턴 (0) | 2023.10.10 |
---|---|
Spring Data Envers (0) | 2023.10.03 |
RESTFul API란? (0) | 2021.01.30 |
Spring 기본 개념 및 이해 (0) | 2021.01.13 |
Spring Boot 소개 (0) | 2020.04.01 |