본문 바로가기

Spring boot - GraphQL 적용하기 본문

개발/Spring boot

Spring boot - GraphQL 적용하기

자전하는명왕성 2025. 5. 16. 20:26
반응형

오늘 포스팅에서는 graphQL을 스프링 부트에 적용하는 방법에 대해 다룬다.

 

먼저 아래를 참고하여 의존성을 추가한다.

// build.gradle

// graphql 스타터 라이브러리
implementation 'org.springframework.boot:spring-boot-starter-graphql' 
// GraphQL Java에서 제공하지 않는 추가 스칼라 타입들을 사용할 수 있도록 해주는 라이브러리
implementation 'com.graphql-java:graphql-java-extended-scalars:21.0'
// application.yml

	graphql:
        schema:
            printer: // 서버 구동 시 실제 graphQL 스키마 파일 출력
                enabled: true
                location: classpath:graphql/schema.graphqls
        graphiql: // 웹 UI
            enabled: true
            path: /graphiql
        schema-location-pattern: "**/*.graphqls"
        tools: // 스키마 정보조회 허용
            introspection:
                enabled: true
            schema-location-pattern: "**/*.graphqls"

 

여기까지 마치면 초기 설정은 끝났다.

 

이제, 실제 사용하기 위한 스키마와 DTO를 정의한다.

// schema.graphqls
type Query {
    fetchUser(userId: ID): User
    fetchUsers: [User]
}

type Mutation {
    createUser(createUserDTO: CreateUserDTO!): User
}

input CreateUserDTO {
    nickName: String!
    password: String!
}

 

// CreateUserDTO.java

@Data
public class CreateUserDTO {
    private String nickName;
    private String password;
}

nest.js와 굉장히 흡사하다.

// UserResolver

package com.chessy.resolver;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.MutationMapping;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;

import com.chessy.domain.Users;
import com.chessy.dto.userDTO.UserDTO;
import com.chessy.dto.userDTO.CreateUserDTO;
import com.chessy.service.UserService;

@Controller
public class UserResolver {

  @Autowired
  private UserService userService;

  @MutationMapping
  public UserDTO createUser(
      @Argument("createUserDTO") CreateUserDTO createUserDTO) {
    Users user = userService.createUser(createUserDTO);
    return convertToDTO(user);
  }
 
// 중략 
}
// UserService

  public Users createUser(CreateUserDTO createUserDTO) {
    if (createUserDTO == null) {
      throw new CustomException(ErrorCode.INVALID_INPUT_VALUE, "사용자 정보는 필수입니다.");
    }

    Users user = new Users();
    user.setNickName(createUserDTO.getNickName());
    user.setPassword(passwordEncoder.encode(createUserDTO.getPassword()));
    user.setRole(Role.USER);
    return userRepository.save(user);
  }

 

이러면 graphQL 사용을 테스트 해볼 수 있다.

localhost:8080/graphiql 로 접속하면, 아래와 같은 화면이 뜨는데, 내게는 익숙치 않은 편.

 

그래서, 익숙한 Sandbox의 플레이그라운드를 사용해주기로 했다.

이와 같은 페이지를 만들어서 접속할 수 있다.

// resources/static/sandbox.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>GraphQL Sandbox</title>
        <style>
            html,
            body {
                margin: 0;
                padding: 0;
                width: 100vw;
                height: 100vh;
                overflow: hidden;
            }
            #sandbox {
                width: 100vw;
                height: 100vh;
            }
        </style>
    </head>
    <body>
        <script src="https://embeddable-sandbox.cdn.apollographql.com/_latest/embeddable-sandbox.umd.production.min.js"></script>
        <div id="sandbox"></div>
        <script>
            new window.EmbeddedSandbox({
                target: "#sandbox",
                initialEndpoint: window.location.origin + "/graphql",
                includeCookies: true,
                initialState: {
                    document: `query {
                        fetchUser(id: 1) {
                            id
                            role
                            nickName
                            createdAt
                            updatedAt
                        }
                    }`,
                },
            });
        </script>
    </body>
</html>

 

다만, 매번 sandbox.html 을 입력하는 건 번거로우니까,

지난번 swagger 를 사용했던 방식을 응용하여 아래와 같은 방식을 채택했다.

이제 localhost:8080/sandbox로 플레이그라운드에 접근이 가능해졌다.

package com.chessy.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class DocsController {

  @GetMapping("/api")
  public String redirectSwagger() {
    return "redirect:/swagger-ui/index.html";
  }

  @GetMapping("/sandbox")
  public String redirectSandbox() {
    return "forward:/sandbox.html";
  }
}

 

테스트까지 하면 끝!

반응형
Comments