[Swift] Alamofire를 사용하여 github GraphQL로 데이터 가져오기 !

Kang Hee Young·2022년 3월 8일
1

SwiftUI

목록 보기
5/5
post-thumbnail

멀고도 멀었던 GraphQL 사용기 기록

GraphQL이란!

GraphQL은 페이스북이 2012년에 개발하여 2015년에 공개적으로 발표된 데이터 질의어이다. 그래프QL은 REST 및 부속 웹서비스 아키텍처를 대체할 수 있다. 클라이언트는 필요한 데이터의 구조를 지정할 수 있으며, 서버는 정확히 동일한 구조로 데이터를 반환한다. 그래프QL은 사용자가 어떤 데이터가 필요한 지 명시할 수 있게 해 주는 강타입 언어이다. 이러한 구조를 통해 불필요한 데이터를 받게 되거나 필요한 데이터를 받지 못하는 문제를 피할 수 있다.

우리 모두의 백과사전, 위키에는 위와같이 적혀있다.

평소 유투브보다는 글로 된 설명을 읽는 것을 선호하는데 이번에는 주변에 GraphQL을 경험한 친구들에게 물어봤을때 보내줬던 유투브가 큰 도움이 되었다. 아직 GraphQL의 개념이 잡혀있지 않다면 한번씩 보는 것을 추천.

쉽게 말해 어렵다 API서버가 GraphQL을 지원한다면 내가 원하는 데이터들만을 가져오는게 수월하다.

GraphQL 사용해보기

덕분에 GraphQL을 배웁니다

iOS로 제작된 Let's Git it!을 안드로이드로 제작하게 되면서 현업에 있는 카뎃 2명이 팀에 추가되었고 안드로이드에서는 완성된 앱을 처음부터 새로 만들기를 시작하였다. 역시 현업자 답게 구현된 기능들중 몇가지에 대해 더 좋은 방법들을 제시해주었고 그중 하나가 github Contribution 데이터를 SwiftSoup으로 크롤링 하는것에서 github GraphQL을 사용하여 가져오는 것이다.

before

// 기존 코드 중 일부.
let html = try String(contentsOf: url, encoding: .utf8)
let parsedHtml = try SwiftSoup.parse(html)
let dailyContribution = try parsedHtml.select("rect")

commits = dailyContribution
	.compactMap({ element -> (String, String) in
	guard
		let dateString = try? element.attr("data-date"),
		let levelString = try? element.attr("data-level")
	else { return ("", "") }

	return (dateString, levelString)
})

기존에는 유저ID를 사용하여 Contribution Graph만 따로 보여지는 주소의 데이터를 파싱하여 다시 배열로 구성하는 작업을 하였다. 기능상에는 문제가 없음

Postman을 사용하여 GraphQL 사용해보기

GraphQL을 귓등으로 듣기만 했던 것에 대해 배워볼 좋은 기회란 생각에 GraphQL을 적용해보았다.

API를 건들때는 postman부터 시작하는 것이 국룰.
프로그램을 다운받아 사용할 수도 있다고 하는데 나는 웹으로 쓴다.

api주소: https://api.github.com/graphql
HTTPMethod: POST


기본 설정을 먼저 설정해주고 github API 토큰을 Auth에 넣거나 Header에 넣어서 적용시킬 수 있다.

Auth에 넣을때는 Type을 Bearer Token으로 지정해준다. Header에 넣을때는 Authorization 필드에 "bearer " + token 을 값으로 넣어준다.

이제 Body를 설정해줘야 한다.

이상적인 모습.
Body의 타입을 GraphQL로 지정해주고 위와 같은 query를 사용하면 데이터들이 잘 나온다.

제대로 작동하였을때의 결과출력화면
이때까지만 해도 쉽게 적용이 가능할 줄 알았는데..

Swift로 구현하기.

swift 그리고 GraphQL을 검색하면 가장 많이 나오는게 apolloSwift-GraphQL 두가지 라이브러리를 이용하는 방법이다. 현재 Let's Git it!에 적용되어 있는 외부 라이브러리는 Alamofire, SwiftSoup, Firebase 3개다. 데이터를 관리하는 Firebase외 두개가 더 있는 것도 마음에 안드는데 새로운 라이브러리를 추가한다? 허락할 수 없지.
외부 라이브러리를 추가하지 않고 graphQL을 사용한다면 SwiftSoup을 대체할 수 있게되고 그렇다면 Alamofire, firebase만을 사용할 수 있게 된다.
따라서 이번 글에서는 GraphQL을 사용할때 Alamofire를 사용한다.

let query =
"""
{
\"query\": \"query { user(login: \\\"\(id)\\\"){ contributionsCollection { contributionCalendar { totalContributions weeks { contributionDays { contributionCount date } } } } } }\"
}
"""
let graphQLURL: URL = URL(string: "https://api.github.com/graphql")!
var request:URLRequest = URLRequest(url: graphQLURL)
let data = query.data(using: .utf8)

request.httpMethod = HTTPMethod.post.rawValue // Set Method
request.setValue("bearer " + token, forHTTPHeaderField: "Authorization") // Set Header
request.httpBody = data // Set Body
Alamofire.request(request).responseJSON { response in
    switch response.result {
    case .success(let response) :
        if let res = response as? [String: Any] {
            print(res)
        }
    case .failure(let error):
        print(error)
    }
}

기능만을 구현한 코드는 위와 같다.
Contribution Data를 가져올 id와 github token을 추가로 넣어주면 실행이 가능하다.
body에 들어가는 query는 {"query": "query{...}"} 로 구성되어야한다.
query문에 조금이라도 틀리거나 문제가 있으면 내가 경험했던 많은 문제들을 경험할 수 있다.

Errors

  • ["documentation_url": https://docs.github.com/graphql, "message": Problems parsing JSON]
  • "A query attribute must be specified and must be a string."
  • Bad Credentials -> github token 만료

느낀점

  • Postman에서 body - GraphQL을 사용하여 단순히 query문만 넣으면 되던 것을 Alamofire에 body로 넣는 것에 어려움이 있었다. 단순히 query로 넣으면 안된다.
  • query에서 /"을 사용해서 "을 표기하였는데 안된다. ///"을 사용해야한다.
  • 근본 없이 구현은 해냈다. 근본에 대한 학습이 더 필요하다.
  • 이게 제대로 사용하는건지 모르겠다.

terminal에서 실행해보기

curl -H "Authorization: bearer $token" -X POST -d " \
 { \
   \"query\": \"query { user(login: \\\"hekang42\\\"){ contributionsCollection { contributionCalendar { totalContributions weeks { contributionDays { contributionCount date } } } } } }\"
 } \
" https://api.github.com/graphql

결론

github Token 이슈와 속도 문제로 현재 방식을 대치하여 적용하기 어려움.

참고
Github Docs GraphQL

profile
hekang in 42Seoul.

0개의 댓글