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.