졸프를 위해 사용자의 레포지토리 목록을 불러오는 api를 구현해야 했다.
https://docs.github.com/ko/rest/repos/repos#list-repositories-for-a-user
깃허브 api에 사용자의 레포지토리 목록을 불러오는게 있길래 연동해서 사용했는데 문제는 사용자가 생성하진 않았지만 기여한 레포지토리를 불러올 수 없었다.
(organization 등 협업을 위해 초대된 레포에서 작업한 경우)
그래서 다른 api 중 사용자의 organization 목록을 불러오는 것과, 해당 organization의 레포 목록을 불러오는 api가 있길래 이 2개를 추가해서 총 3번의 조회로 레포지토리 목록을 불러오게 코드를 작성했는데, 문제가 있다.
웹 클라이언트
@Component
public class GithubClient {
private final WebClient webClient;
public GithubClient(WebClient.Builder builder) {
this.webClient = builder
.baseUrl("https://api.github.com")
.build();
}
public List<GithubRepoResponse> getRepos(String token) {
List<GithubRepoResponse> result = new ArrayList<>();
// 1. 내 repo
List<GithubRepoResponse> myRepos = webClient.get()
.uri("/user/repos?per_page=100")
.header("Authorization", "Bearer " + token)
.retrieve()
.bodyToFlux(GithubRepoResponse.class)
.collectList()
.block();
if (myRepos != null) result.addAll(myRepos);
// 2. org 목록
List<GithubOrgResponse> orgs = webClient.get()
.uri("/user/memberships/orgs")
.header("Authorization", "Bearer " + token)
.retrieve()
.bodyToFlux(GithubOrgResponse.class)
.collectList()
.block();
System.out.println("orgs: "+orgs);
// 3. org repo들
if (orgs != null) {
for (GithubOrgResponse org : orgs) {
List<GithubRepoResponse> orgRepos = webClient.get()
.uri("/orgs/{org}/repos?per_page=100", org.getLogin())
.header("Authorization", "Bearer " + token)
.retrieve()
.bodyToFlux(GithubRepoResponse.class)
.collectList()
.block();
if (orgRepos != null) result.addAll(orgRepos);
}
}
return result;
}
}
org 권한 문제로 내가 만든 레포만 불러와짐
계속 org 목록이 []였다...
여러 api 조합해서 요청해서 속도 느림
된다 해도 문제인게, api 3개를 조회하는거라 매우 오래 걸릴 것이다
클라이언트가 서버에 필요한 데이터만 선택적으로 요청할 수 있는 쿼리 언어이자 런타임
기존 rest api는 서버에 구현된 내용대로 사용해야 작동하여, 원하는 데이터만 불러오는데 어려움이 있다.
GraphQl은 직접 쿼리문을 작성하여 서버에 요청하는 방식이라 더욱 유연한 사용이 가능하다.
String query = """
query {
viewer {
repositories(first: 100) {
nodes {
name
url
description
}
}
repositoriesContributedTo(first: 100, contributionTypes: [COMMIT, PULL_REQUEST], orderBy: {field: CREATED_AT, direction: DESC}%s) {
nodes {
name
url
description
}
}
}
}
""";
Map<String, Object> response = restClient.post()
.uri("https://api.github.com/graphql")
.header("Authorization", "Bearer " + accessToken)
.body(Map.of("query", query))
.retrieve()
.body(new ParameterizedTypeReference<>() {});
Map<String, Object> response: json 응답을 맵으로 받는다