graphql 라이브러리 spqr 를 이용한 GraphQL 실습해보기
graphql 라이브러리 spqr 를 이용한 GraphQL 실습해보기
회사에서 백오피스를 구축해야 하는데, 여러면에 있어
graphQL를 적용시키면 좋을 것 같아 학습해보았다.
👾 GraphQL 이란
GraphQL은 페이스북이 2012년에 개발하여 2015년에 공개적으로 발표된 데이터 질의어이다. 클라이언트(프론트)는 필요한 데이터의 구조를 지정할 수 있으며, 서버는 정확히 동일한 구조로 데이터를 반환한다.
- 클라이언트에서 작성하는 쿼리의 예시이다.
1
2
3
4
5
6
7
8
9
query {
book(id: "1") {
title
author {
firstName
lastName
}
}
}
- 응답은 이렇게 오게 된다.
1
2
3
4
5
6
7
{
"title": "Harry Porter ",
"author": {
"firstName": "J.K",
"lastName": "Rowling"
}
}
📝 실습
⚙️ 환경
- spqr (GraphQL 라이브러리)
- Java 11
- Spring boot 2.6.2
- Gradle
- Feign client
- MySql(docker)
- JPA
- MapStruct
⛳ 목표
select테스트 (조건에 맞춰 값을 잘 가져오는지)insert,update,delete테스트- 다른 서비스(msa)에
graphQL로 받은 요청을 보낼 수 있는지
1️⃣ ReceiverProject 만들기
요청을 받아 DB CRUD 하는 서비스를 만든다.
1. DB 스키마 설계
테이블 구조는 아래와 같다.
상품정보테이블상품에 대한 태그테이블
2. Controller 작성
일반적인 Rest 구조로 되어있다.
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
@RestController
public class LoanController {
private final LoanService loanService;
public LoanController(LoanService loanService) {
this.loanService = loanService;
}
@GetMapping("/loans")
public List<LoanModel> loans() {
return loanService.getLoans();
}
@GetMapping("/loan/{id}")
public LoanModel getLoanById(@PathVariable Long id) {
return loanService.getLoanById(id);
}
@PostMapping("/loan")
public LoanModel saveLoan(@RequestBody LoanModel post) {
return loanService.saveLoan(post);
}
@PostMapping("/delete-loan")
public void deleteLoan(Long id) {
loanService.deleteLoan(id);
}
}
2️⃣ SenderProject 만들기
이번에는 GraphQL(spqr)로 요청을 받아 ReceiverProject로 보내는 서비스를 만든다.
spqr이란
스키마를 정의하여 매핑하는 방식이 아닌 어노테이션을 사용하여 매핑을 해주는 방식이다. 따로 스키마와 resolver를 구현하지 않아도 GraphQL을 사용할 수 있어 편리하다는 장점이 있지만 단점으로 Multipart 를 이용한 파일 업로드 구현이 어렵다는 점이 있다.
1. Service 작성
여기서 Service 는 클라이언트의 요청을 받는 컨트롤러와 같은 역할을 한다.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
@GraphQLApi
@RequiredArgsConstructor
public class LoanService {
private final TestClient testClient;
@GraphQLQuery(name = "loans")
public List<LoanModel> getLoans() {
return testClient.loans();
}
// {
// post(id:1){
// id
// title
// }
// }
@GraphQLQuery(name = "loan")
public LoanModel getLoanById(Long id) {
return testClient.getLoanById(id);
}
// mutation{
// saveLoan(post:
// {
// id: 343
// name :"sss",
// loanTagList:[
// {
// type: "test1",
// description :"xxx"
// }
// {
// type: "test2",
// description :"yyy"
// }
// {
// type: "test3",
// description :"zzz"
// }
// ]
// })
// }
@GraphQLMutation(name = "saveLoan")
public LoanModel saveLoan(LoanModel post) {
return testClient.saveLoan(post);
}
// mutation{
// deletePost(id:1)
// }
@GraphQLMutation(name = "deleteLoan")
public void deleteLoan(Long id) {
testClient.deleteLoan(id);
}
}
2. Feign Client 작성
graphQL 로 클라이언트에서 받는 요청을 ReceiverProject(8070)에 보낸다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@FeignClient(name = "feign", url = "http://localhost:8070")
public interface TestClient {
@GetMapping("/loans")
List<LoanModel> loans();
@GetMapping("/loan/{id}")
LoanModel getLoanById(@PathVariable Long id);
@PostMapping("/loan")
LoanModel saveLoan(LoanModel post);
@PostMapping("/delete-loan")
void deleteLoan(Long id);
}
3. 실행
실행 후 http://localhost:8080/gui 로 접속하면 해당 화면을 볼 수 있다.
🎬 결론
graphQL로 클라이언트에서 요청을 받고, 다른 서비스로REST하게 전송할 때 별다른 문제점은 찾지 못했다.- 페이징, 파일 전송 등은 연구 필요
This post is licensed under CC BY 4.0 by the author.


