티스토리 뷰
SpringBoot 에서 JPA 와 GraphQL 을 연동하는 방법에 대해 간략히 소개하겠습니다. 해당 포스팅에선 PostgeSQL 을 사용하였습니다.
1. 의존성 추가
// GraphQL
implementation 'org.springframework.boot:spring-boot-starter-graphql'
implementation 'com.graphql-java-kickstart:graphql-spring-boot-starter:15.1.0'
// PostgreSQL
runtimeOnly 'org.postgresql:postgresql'
// JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
- GraphQL, PostgreSQL, JPA 의존성을 추가합니다.
2. App설정(application.yml)
spring:
graphql:
path: /api/query
schema:
locations: classpath:graphql/
graphql:
playground:
enabled: true
endpoint: /api/query
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: myuser
password: 1234
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: none
show-sql: true
- GraphQL : 엔드포인트 '/api/query' 로 지정하고 schema 파일은 resources/graphql/*.graphqls 형태로 관리합니다. playground 를 활성해 웹으로 테스트 및 스키마를 확인할 수 있습니다.
- PostgreSQL : 접속 정보를 작성합니다.
- JPA : Hibernate 가 스키마를 관리하지 않도록하고, SQL 쿼리를 콘솔에 출력합니다.
3. User 도메인 작성
#User.java
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
private String userId;
@Column(nullable = false)
private String userName;
private String email;
@Column(nullable = false)
private String password;
private LocalDateTime createdAt = LocalDateTime.now();
private LocalDateTime updatedAt = LocalDateTime.now();
@ManyToOne
@JoinColumn(name = "team_id", referencedColumnName = "teamId", insertable = false, updatable = false)
private Team team;
@Column(name = "team_id")
private String teamId; // 단순 컬럼 매핑용 필드
}
#UserRepository.java
public interface UserRepository extends JpaRepository<User, String> {
List<User> findAll(Sort sort);
}
- users 테이블과 맵핑하고, team_id 로 teams 테이블과 조인합니다.
- save 시, team_id 도 맵핑하기 위해 insert/update 를 false 로 작성하고, 단순 컬럼 매핑용 필드도 생성합니다.
4. Team 도메인 작성
#Team.java
@Entity
@Getter
@Setter
@Table(name = "teams")
public class Team {
@Id
private String teamId;
@Column(nullable = false, unique = true)
private String teamName;
private String description;
private LocalDateTime createdAt = LocalDateTime.now();
private LocalDateTime updatedAt = LocalDateTime.now();
@OneToMany(mappedBy = "team")
private List<User> users;
}
#TeamRepository.java
public interface TeamRepository extends JpaRepository<Team, String> {
}
- users 테이블과 조인하여 팀에 속한 사용자를 조회합니다.
5. 컨트롤러 작성
TeamController.java
@Controller
@RequiredArgsConstructor
public class TeamController {
private final TeamService _teamService;
/**
* 팀 전체 조회
*/
@QueryMapping
public List<Team> getAllTeams() {
return _teamService.getAllTeams();
}
/**
* 팀 등록
*/
@MutationMapping
public Team createTeam(@Argument TeamRequest teamRequest) {
return _teamService.createTeam(teamRequest);
}
}
UserController.java
@Controller
@RequiredArgsConstructor
public class UserController {
private final UserService _userService;
/**
* 전체 사용자 조회
*/
@QueryMapping
public List<User> getAllUsers(@Argument SortRequest sortRequest) {
return _userService.getAllUsers(sortRequest);
}
/**
* 사용자 조회 By Id
*/
@QueryMapping
public User getUserById(@Argument String id) {
return _userService.getUserById(id);
}
/**
* 사용자 추가
*/
@MutationMapping
public User createUser(@Argument UserRequest userRequest) {
return _userService.createUser(userRequest);
}
/**
* 사용자 삭제
*/
@MutationMapping
public DeleteResponse deleteUser(@Argument String id) {
return _userService.deleteUser(id);
}
/**
* 사용자 수정
*/
@MutationMapping
public User updateUser(@Argument UserRequest userRequest) {
return _userService.updateUser(userRequest);
}
}
- GraphQL 은 @Controller 를 사용하고, 조회엔 @QueryMapping, 등록/수정/삭제엔 @MutationMapping 을 사용합니다.
6. 스키마 작성
/resources/
└─graphql
└─mutations.graphqls
└─queries.graphqls
└─request.graphqls
└─response.graphqls
* requet.graphqls
input SortRequest {
sortBy: String
order: String
}
input UserRequest {
userId: String
userName: String
email: String
password: String
teamId: String
}
input TeamRequest {
teamId: String
teamName: String
description: String
}
- 클라이언트로부터 입력받는 파라미터 스키마를 정의합니다.
* response.graphqls
# User 타입
type UserResponse {
userId: ID!
userName: String!
email: String!
password: String!
team: TeamResponse!
}
# Team 타입
type TeamResponse {
teamId: ID!
teamName: String!
description: String
users: [UserResponse!]!
}
# DeleteResponse.java
type DeleteResponse {
successYn: String
message: String
}
- 반환받을 스키마를 지정합니다.
*queries.graphqls
type Query {
# 사용자 전체조회
getAllUsers(sortRequest: SortRequest): [UserResponse!]!
# ID로 사용자 조회
getUserById(id: ID!): UserResponse
# 팀 전체조회
getAllTeams: [TeamResponse!]!
}
- 조회 메서드의 파라미터와 리턴타입을 맵핑합니다.
*Mutations.graphqls
type Mutation {
# 사용자 등록
createUser(userRequest: UserRequest): UserResponse
# 사용자 삭제
deleteUser(id: ID!): DeleteResponse
# 사용자 수정
updateUser(userRequest: UserRequest): UserResponse
# 팀 등록
createTeam(teamRequest: TeamRequest): TeamResponse
}
- 등록/수정/삭제 메서드의 파라미터와 리턴타입을 맵핑합니다.
7. 테스트(playground)
SpringBoot 서버를 실행후 /playground 로 접근합니다.

- playground 로 테스트를 진행합니다.
#getAllUsers
{
query { getAllUsers(sortRequest: {sortBy: "userName", order: "DESC"}) { userId userName email } }
}
#getAllTeams
{
query { getAllTeams { teamId teamName description users { userId userName } } }
}
#getUserById
{
query { getUserById(id: "USER001") { userId userName email team{ teamName }} }
}
#getUserById & getAllUsers
{
query { getUserById(id: "USER001") { userId userName email team { teamName } } getAllUsers(sortRequest: {sortBy: "userName", order: "DESC"}) { userId userName email } }
}
#createUser
{
mutation { createUser(userRequest: { userId: "USER007", userName: "자유저", email: "user-007@test.co.kr", password: "7777", teamId: "TEAM004" }) { userId } }
}
#updateUser
{
mutation { updateUser(userRequest: { userId: "USER008", userName: "유저7", password: "7777", teamId: "TEAM003" }) { userId userName email } }
}
#deleteUser
{
mutation { deleteUser(id: "USER006") {successYn message} }
}
- GraphQL 를 이용해 조회/등록/수정/삭제 테스트를 할 수 있습니다.
감사합니다.
'프레임워크 > SpringBoot' 카테고리의 다른 글
[SpringBoot] RestErrorAdvice 설정하는 방법(SpringSecurity+JWT) (0) | 2025.01.16 |
---|---|
[SpringBoot] Docker 배포 가이드 (2) | 2024.12.30 |
[Spring] AOP 의 주요 사용처 (1) | 2024.12.03 |
[Spring] 스프링 어노테이션 동작 원리 (2) | 2024.12.03 |
[SpringBoot] Tesseract OCR 이미지 글자 추출 예제 (1) | 2024.11.26 |
최근에 올라온 글
- Total
- Today
- Yesterday