Programing/GraphQL

세무민의 코딩일기 : Spring Boot + GraphQL ScalarType 사용하기

세기루민 2023. 3. 28. 11:08
728x90

안녕하세요. 세기무민입니다.

이번 포스팅의 프로젝트 기반은 아래의 포스팅의 연장선이라고 보시면 될 것 같습니다.

 

세무민의 코딩일기 : Spring Boot + GraphQL 연결하기

안녕하세요 세기무민입니다. 이번 포스팅에서는 Spring Boot와 GraphQL을 사용해보도록 하겠습니다. GraphQL? GraphQL은 페이스북에서 만든 쿼리 언어입니다. GrahpQl은 웹 클라이언트가 데이터를 서버로부

sg-moomin.tistory.com

포스팅의 주제는 ScalarType과 graphql-scalar를 spring boot에서 사용하는 방법에 대해 정리하였습니다.

(생각했던 것보다 잘 안풀려서 나름 삽질 엄청했네요...ㅠㅠ)


1. Scalar Type?

  • GraphQL은 공식적으로 지원하는 자료형은 5개이며 아래와 같습니다.

  • 스칼라 타입은 객체가 아님으로 필드를 가지지 않습니다.
  • 따라서 5개의 기본 타입을 사용하는 것이 아닌 Date/Long과 같은 타입을 사용하기 위해서는 선언해줘야 합니다.

2. Scalar Type Setting

2.1 build.gradle 설정

2.1.1 graphql-java 라이브러리 이용

// gradle
// graphql 기본 설정 파일
implementation 'com.graphql-java:graphql-java:19.2'
// graphql 스칼라 선언 
implementation 'com.graphql-java:graphql-java-extended-scalars:20.0'
  • 주의 사항
    • graphql-java의 버전은 scalars 버전과 연관관계가 있음graphql-java 20.x 이상에 20.0 이상 사용
    • graphql-java 19.x 이상에 19.0 이상 사용
    • 위의 버전대로 처리하였으나 작동 오류로 아래와 같이 재 설정했다.

2.1.2 graphql-kickstart 라이브러리 이용

// gradle
// graphql 기본 설정 파일
implementation 'com.graphql-java-kickstart:graphql-spring-boot-starter:11.1.0'
// graphql 스칼라 선언 
implementation 'com.graphql-java:graphql-java-extended-scalars:20.0'
  • kickstart 11 버전을 이용하였으며 해당 버전이 scalars 20.0 버전과 충돌이 안나는 것으로 확인

 

2.2 schema.graphqls 파일

# *.graphqls

# 스키마 선언 
schema {
    query: Query,
}

# 스칼라 선언
scalar Date

# 쿼리 선언
type Query{
	getMemberEpisode: MemberEpisode
}

# MemberEpisode 유형 선언
type MemberEpisode {
	mepisNo: ID!
	title: String
	regDate: Date
}
  • Date Type을 사용하기 위해 graphqls 파일에 커스텀 스칼라를 선언했다.
  • 현재 포스팅에서는 Query만 사용했으나 Mutation을 이용하는 경우라면 schema와 Mutation을 추가해주면 된다.

2.3 Config

@Configuration
public class GraphQlConfig {

    // graphql-kickStart 사용
    @Bean
    public GraphQLScalarType Date(){
        return ExtendedScalars.Date;
    }
    
    // graphql-java 사용
    @Bean 
    public RuntimeWiringConfigurer runtimeWiringConfigurer() { 
        return wiringBuilder -> wiringBuilder.scalar(ExtendedScalars.Date); 
    }
}
  • Config 파일을 생성하고 해당 파일에서 Date Type에 대해 선언해준다. 
  • GraphQLScalarType과 RuntimeWiringConfigurer 2개를 현재 사용했으나 1개만 사용해도 된다는 말들이 많다.
  • 그러나 내가 테스트를 했을 때 GraphQLScalarType만 사용했을 때 DateType에 대해 인식을 하지 못하는 문제에 따라런타임 오류가 발생했고 이에 따라 RuntimeWiringConfigurer에 스칼라 타입으로 Date를 넣어줬다. 

2.3.1 (번외) RuntimeWiringConfigurer?

https://docs.spring.io/spring-graphql/docs/current/reference/html/#execution.graphqlsource.runtimewiring-configurer

  • Spring-graphql 문서에 따르면 아래와 같습니다.
    • 사용자 정의 스칼라 유형, 지시문 처리 코드, defaultTypeResolver 등. 변경 사항을 등록 가능
    • 따라서 다른 유형에 해당하는 스칼라 타입을 Entity 및 DTO에 담아 전달하여 설정 가능할 것으로 생각됨

2.4 Query, Object

2.4.1 *.Query.java

@Component
@RequiredArgsConstructor
public class MemberQuery implements GraphQLQueryResolver{
    /**
    * 맴버 에피소드 조회
    * history : 해당 method는 Scalar Type 테스트 용
    *
    */
    public MemberEpisode getMemberEpisode() {
        int seq = 1;
        String title = "Scalar 사용하는거 겁나 어렵네....ㅠㅠ";
        LocalDate nowDate = LocalDate.now();
        Instant instant = nowDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
        Date date = Date.from(instant);
		
        return new MemberEpisode(seq, title, nowDate);
    }
}
  • graphqls 파일 Query로 선언한 내용에 대해 리졸버로 연결해줍니다. 
  • 현재 코드는 스칼라 타입 테스트를 위한 코드이며 실제 DB에 데이터를 가지고 사용해도 무관합니다. 
    • 테스트 코드를 이용해도 무관
  • QueryResolver를 복수개로 사용 가능할 것으로 보이나 

2.4.2 Object

@Builder
@Value
@Getter
@Setter
@AllArgsConstructor
@Entity(name="memberepisode")
public class MemberEpisode{
    @Id
    private int mepisNo;
    private String title;
    private LocalDate regDate;
}
  • MemberEpisode에 해당하는 객체를 생성해준다.
  • (번외) 해당 객체는 graphqls 파일이 실행되었을 때 존재 유무를 체크하고 존재할 경우 정상 작동(내부 로직에 따라 작동되는 것으로 보임)

3. 결과

  • 정상적으로 scalar type에 대한 값을 return 해주는 것을 확인할 수 있다. 
  • 참고로 scalar type을 정의하지 않으면 애플리케이션 자체 실행에서 런타임처리 되기 때문에 graphqls 파일과 관련 설정들을 재대로 했는지 검토해야 한다. 

 


이번 포스팅에서는 graphql scalar type 사용 방법에 대해 알아봤습니다.

하면서 삽질했던 포인트가 있는데 이 부분은 따로 포스팅 하도록 하겠습니다.

다음 포스팅에서는 graphql 이론 포스팅 혹은 spring-graphqls 심화로 돌아오겠습니다.

 

 

728x90