일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Tomcat DBCP
- Open Close Principal
- Java Rest
- Jndi DataSource
- Java Singleton
- mTLS
- HandlerMethodArgumentResolver
- 데이터 압축
- Sub Bytes
- graphql
- tomcat jndi
- requestheaderdto
- Checked Exception
- Reading HttpServletRequest Multiple Times
- 개방 폐쇄 원칙
- try - with - resources
- java
- WildFly
- AfterMapping
- 상호 인증
- NoUniqueBeanDefinitionException
- Java Graphql
- 이중정렬
- 바이트 절삭
- Srping MVC
- Request Body 여러 번 사용
- Socket is closed
- Unchecked Exception
- mapstruct
- Graphql Client
- Today
- Total
Developer Sang Guy
Java Graphql Client 구현 본문
이번에 일하다가 Graphql을 사용해야 할 일이 생겼었다.
Graphql이라는걸 이번에 처음들었는데 FaceBook에서 개발한 어플리케이션 쿼리 언어란다.
애플리케이션 쿼리 언어가 뭔진 난 잘 모르겠고 그냥 API 사용을 위한 문법으로 이해했다.
Graphql의 소개 중 가장 이해가 쉬웠던 내용은 Rest API의 단점을 보완한다는 내용이였다.
Rest API 써본 사람은 알겠지만 서버 측으로 응답받은 데이터 중 내가 실제로 사용하는 데이터보다
사용하지 않는 데이터까지 응답받는 경우가 있다.
Graphql의 경우 위 부분을 보완한 장점을 가지고있다.
문장 중 내가 필요로하는 데이터를 명시해주면 명시한 데이터만 응답받을 수 있다.
이 부분으로 확실히 괜히 필요하지 않은 데이터로 인한 리소스 낭비는 없을 것으로 보인다.
이게 Graphql의 장점 중 가장 기억나고 와닿았던 내용이다.
그 외 장점도 여러가지지만 단점도 꽤 여러가지 있는 것으로 알고있다.
자세한 내용은 구글에서 "Graphql 장단점"을 검색해보자
이제 Graphql Client를 Java로 어떻게 구현하는지를 기록하겠다.
참고로 Graphql Server는 아직은 구현 할 일이 없을 것 같아 따로 공부하지 않았다.
Graphql 문법은 대충 아래와 같이 생겼다.
1
2
3
4
5
6
7
|
query($code: ID!) {
country(code: $code) {
name
capital
currency
}
}
|
cs |
위 예제는 굉장히 간단한 예제이고 좀 복잡하게 생긴건 아래와 같다.
(Shopify에서 제공하는 Graphql mutation)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
mutation PaymentSessionResolve($id: ID!, $authorizationExpiresAt: DateTime) {
paymentSessionResolve(id: $id, authorizationExpiresAt: $authorizationExpiresAt) {
paymentSession {
id
status {
code
}
nextAction {
action
context {
... on PaymentSessionActionsRedirect {
redirectUrl
}
}
}
}
userErrors {
field
message
}
}
}
|
cs |
Graphql 문법 안에 여러가지 개념이 존재하는데 자세한 건 아래 URL에서 공부 할 수 있다.
GraphQL | A query language for your API
Evolve your APIwithout versions Add new fields and types to your GraphQL API without impacting existing queries. Aging fields can be deprecated and hidden from tools. By using a single evolving version, GraphQL APIs give apps continuous access to new featu
graphql.org
먼저 Graphql Client를 어떻게 자바로 구현해야하는지가 고민이다.
뭔가 Json이랑 비슷하긴 하지만 Json Object로 구현하기는 애매한 느낌이 들었고
Graphql 같은 경우는 서비스에서 사용 할 데이터가 변하지 않는 이상 수정 할 일은 없다고 생각하여
그냥 파일로 저장하여 가져다 쓰는 방법을 사용했다.


내가 사용해본 경험으로 Graphql Clients는 크게 query와 variables로 나뉜다.
query는 그냥 파일로 저장해논 country.graphql을 가져다 사용 할 것이다.
문제는 variables인데 이건 query에서 인자가 사용되고 있을 경우 필요한 케이스다.
country.graphql의 내용을 보면 query($code: ID!)와 country(code: $code)가 있다.
JAVA의 메소드(인자) 형태와 비슷한데 기능도 비슷하다.
query($code: ID!) - 대충 이 쿼리에서 code라는 인자를 ID Type으로 명시한다는 내용
country(code: $code) - 대충 country라는 데이터를 가져올건데 인자로 code를 받겠다는 내용
지겨운 설명은 그만하고 소스를 보자!
query와 variables를 한번에 생성하여 문자열을 생성하기 위해 아래와 같은 객체를 생성하여 사용하였다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class GraphqlRequestBody {
private String query;
private Map<String, Object> variables;
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
public Map<String, Object> getVariables() {
return variables;
}
public void setVariables(Map<String, Object> variables) {
this.variables = variables;
}
}
|
cs |
객체에 query와 variables를 세팅하고 API Request까지 하는 내용은 아래와 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@Test
void testGraphql() throws Exception {
GraphqlRequestBody requestBody = new GraphqlRequestBody();
requestBody.setQuery(getGraphqlQuery("/static/country.graphql"));
requestBody.setVariables(new HashMap<String, Object>());
requestBody.getVariables().put("code", "KR");
String parameter = new ObjectMapper().writeValueAsString(requestBody);
System.out.println("Request Parameter : " + new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(requestBody));
Utils utils = new Utils();
URI uri = new URI("https://countries.trevorblades.com");
Map<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
List<String> responseList = utils.sendRequest(uri, headers, parameter, "POST");
System.out.println("response : " + responseList.get(0));
System.out.println("response : " + responseList.get(1));
}
|
cs |
결과 :
1
2
3
4
5
6
7
8
9
|
Request Parameter : {
"query" : "query($code: ID!) {\r\n\tcountry(code: $code) {\r\n\t\tname\r\n\t\tcapital\r\n\t\tcurrency\r\n\t}\r\n}",
"variables" : {
"code" : "KR"
}
}
response : 200
response : {"data":{"country":{"name":"South Korea","capital":"Seoul","currency":"KRW"}}}
|
cs |
여기까지 읽고 궁금 할수도 있는 내용들 :
- 테스트에 사용한 URI("https://countries.trevorblades.com") 이거 뭐니?
- country.graphql 파일 가져오는 메소드 getGraphqlQuery 이거 뭐니?
- Json 아닌거 같은데 왜 Content-type이 application/json 이니?
- 왜 Http Method가 POST니?
- 통신에 사용한 utils.sendRequest 이거 뭐니?
설명 :
1. 테스트에 사용한 URI("https://countries.trevorblades.com") 공개 Countries Graphql API이다.
위 공개 API를 통해 Graphql을 경험해볼 수 있다.
좀 더 자세한 내용은 "Graphql Playground"를 검색해보면 될 듯?
2. Method getGraphqlQuery는 그냥 파일 읽어오는 메소드다.
여러분의 좀 더 편안한 복붙을 위해 아래 기록하겠다.
1
2
3
4
5
6
7
8
9
10
11
|
public String getGraphqlQuery(String fileName) throws Exception {
InputStream is = getClass().getResourceAsStream("/static/country.graphql");
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
for (int length; (length = is.read(buffer)) != -1;) {
result.write(buffer, 0, length);
}
return result.toString();
}
|
cs |
3. Content-type이 application/json인 이유는 그냥 그렇게 하라고 되어있다.
참고 : https://graphql.org/graphql-js/graphql-clients/
GraphQL Clients | GraphQL
GraphQL Clients Since a GraphQL API has more underlying structure than a REST API, there are more powerful clients like Relay which can automatically handle batching, caching, and other features. But you don't need a complex client to call a GraphQL server
graphql.org
4. Http Method POST인 이유도 그냥 그렇게 하라고 되어있다.
참고 : https://graphql.org/graphql-js/graphql-clients/
GraphQL Clients | GraphQL
GraphQL Clients Since a GraphQL API has more underlying structure than a REST API, there are more powerful clients like Relay which can automatically handle batching, caching, and other features. But you don't need a complex client to call a GraphQL server
graphql.org
5. Method sendRequest 아래 URI에서 확인할 수 있다.
https://devsangguy.tistory.com/6
[JAVA] Http 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 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 59 60 61 62 63 64 65 66 67 68 69..
devsangguy.tistory.com
위 내용들은 굉장히 개인적인 생각으로 기록한 글이며 정답이 아닐수도 있습니다.
잘못된 부분이 있을 경우 댓글로 남겨주시면 확인하고 수정하도록 하겠습니다.
'Java' 카테고리의 다른 글
데이터 압축 (0) | 2022.05.26 |
---|---|
[Java]NonStaticInnerClass vs StaticInnerClass (0) | 2022.05.18 |
Java Http Rest 통신 소스 (0) | 2022.01.05 |
Java Singleton 객체 구현 및 주의 사항 (0) | 2021.05.16 |
OCP (Open Close Principal) 개방 폐쇄 원칙 (0) | 2021.05.14 |