iOS | Apollo을 사용해서 GraphQL API 의 리퀘스트를 해보자.

안녕하세용

회사 혹은 개인 프로젝트에서 사용되는 API 는 RESTful API ? GraphQL 어느 것인가요
제가 다녔던 회사는 REST API로 사용했었어서 아무래도 REST API가 훨씬 익숙한 사람이에요.

GraphQL 을 제가 설명하기엔 서버의 지식이 너무 부족해서
다른 자료들을 살펴보시길 부탁드립니다.

저는 오늘 GraphQL에서 주는 데이터들을 iOS 에서 어떻게 받아와야하는지에 대해 써보려고합니다.

POST 할 곳이 마땅치 않아서 여기서는 GET 에 대해서만 작성하겠습니다 🙏



Apollo?

Apollo?

GraphQL을 구현해보기 전, 저에게 Apollo 는 초등학교 때 문방구에서 사먹는 빨대에 들어있는 과자? 불량식품일 뿐이었답니다,,,,,

Apollo 는 iOS 에서 GraphQL 아주 편리하게 사용할 수 있게 만들어주는 마법의 라이브러리입니다.

https://www.apollographql.com/docs/ios/
https://github.com/apollographql/apollo-ios


Apollo 이외에도 선택지야 있겠지만, 아직 몇 없는 블로그글도 대부분 Apollo 이고
튜토리얼, 지속적인 버전 관리 등의 이유로 저는 Apollo를 선택하였습니다.

자 ! 그럼 Apollo 가 실제로 어떻게 사용되는지 보러 가보시죠 ~ !



Project 에 Apollo 설치하기.

저는 Swift Package Manager 를 사용해서 설치해보았어요.

https://www.apollographql.com/docs/ios/installation/#installing-the-apollo-framework
Cocoapods, Carthage 는 ☝️링크에 친절하게 설명되어 있어용 참고해쥬세요 !

지금부터는 Cocoapods, Carthage 도 동일한 환경설정이 필요하니 스킵하시지 마시고
꼭 꼭 잘 봐주세요
(제가 많이 헤멘 포인트예요 😂)

– Run Script 를 추가해주세요

– 여기서 중요한 포인트 2가지가 있습니다.

1. Apollo CLI(추가한 Run Script) 의 위치는 Dependencies 바로 다음으로 해주세요.
2. 위의 스크린샷에서 빨간색으로 표시된 1️⃣2️⃣3️⃣ 에 적절한 Script 를 넣어줍니다.
1️⃣Cocoapods / Carthage / Swift Package Manger, Apollo 를 설치한 패키지 매니저에 따라 입력할 스크립트가 다릅니다. 🔗 에서 스크립트를 확인해서 넣어주세용
2️⃣$(SRCROOT)/모듈명/*.graphql
3️⃣$(SRCROOT)/모듈명/API.swift
⚠️- 2️⃣, 3️⃣은 Apollo 사용하기에서 다시 한 번 더 살펴봐야해요 !

– 저는 위의 스크린샷과 똑같이 설정했어용


Run Script 설정으로 쪼금 복잡하긴 하지만 😣!
GraphQL의 사용은 REST API 의 사용보다 훨 ~ 씬 간단하답니다.

자 이제 사용하러 가보시죠 !



Apollo 사용하기(설명).

Apollo 에서 제공되고 있는 튜토리얼용 GraphQL API
https://apollo-fullstack-tutorial.herokuapp.com/

이번 Project 에서 사용해 볼 API 는 Apollo 에서 제공된 튜토리얼용 API 를 사용합니다.


지금부터 할 작업을 그림으로 그려보았어요.


🍊오렌지색 부분🌎파란색 부분을 나누어서 설명할게요.


🍊오렌지색 부분

– Xcode에서 project 가 빌드되면, Run Script에 따라 LaunchList.graphql, schema.json 두 가지 파일을 이용해서 API.swift 를 만들어냅니다.

LaunchList.graphql : project 에서 필요한 (화면에 표시할 필요가 있는) property 를 구성해서 만든 query.
schema.json : endpoint 로부터 만들어내는 파일. 서버가 구축되어 있어야 만들 수 있다. A schema file is a JSON file that contains the results of an introspection query. 🔗
API.swift : 위의 두 가지 파일을 이용해서 만든 model. 바로 파싱이 가능한 상태로 선언되어 있다.

– 💫 위의 글을 장황하지만 위의 두 가지 파일을 준비하고 Xcode build 를 실행시키면 뚝딱하고 API.swift 가 만들어지는 것입니다.



🌎파란색 부분

🍊오렌지색 부분 에서 만들어진 API.swift 파일을 이용해서 서버에 request를 하고, 결과를 화면에 표시합니다.
API.swift 가 만들어지지 않으면 GraphQL 을 활용하지 못한다는 것과 같아요 😣


자, 그럼 실제 코드에서 어떻게 작동하는지 보러 가시죠 !

Apollo 사용하기(실제 코드).

Apollo 에서 제공되고 있는 튜토리얼용 GraphQL API
https://apollo-fullstack-tutorial.herokuapp.com/

request 에 필요한 API.swift 를 만들기 위해서 필요한, LaunchList.graphql, schema.json 파일들부터 준비해봅시다.

1. LaunchList.graphql 파일 만들기.

https://apollo-fullstack-tutorial.herokuapp.com/ 를 열어주세용
왼쪽 화면에 원하는 property 의 query 를 작정해서 ▶️버튼을 누르면 오른쪽 화면에 request 시 예상되는 결과값이 나오게 된답니다.

query LaunchList {
  launches {
    cursor
    hasMore
  }
}

– query 를 짜줍시다 !
– 출력값에 문제가 없으면 Xcode에 복붙으로 파일을 만들어주세요
– ⚠️ query 이름을 꼭 ! 넣어주셔야해요 (저는 깜빡했었어서 계속 실행에러가 발생했었어요 ㅠㅡㅠ)

– 파일이름은 Query명.graphql 로 해주세요.

– 추가된 LaunchList.graphql 파일에 아까 작성해둔 query를 넣어주세요.


2. schema.json 파일 만들기.

https://apollo-fullstack-tutorial.herokuapp.com/ 를 열어주세요.

– 다운로드 받으신 JSON 파일을 schema.json 으로 이름을 변경해주세요.

– project 에 추가해주세요.
– ⚠️반드시 !!! 꼭 !!!! LaunchList.graphql 같은 경로에 넣어주세요.


3. API.swift 파일 만들기.
– Xcode Project의 build(혹은 run)을 실행해주세요.

– 👏👏👏👏👏👏👏👏👏👏👏👏
API.swift 가 등장했습니다 👏👏👏

API.swift 를 project 에 추가해줍니다.
– 이걸로 request 할 준비는 끝이에요 !!!! 끼야호

4. request 하는 코드 작성.

import Apollo

final class NetworkManager {
    static let shared = NetworkManager()

    private let requestURL = URL(string: "https://apollo-fullstack-tutorial.herokuapp.com/")! // 예제니까 !를 용서해주세요🙏
    private (set) lazy var apollo = ApolloClient(url: requestURL)
}

– 직접적으로 Apollo 와 view 의 매개체인 NetworkManager 를 만들어줍니다.

5. request 결과물을 view 에 표시하기. (SwiftUI)

– 작은 프로젝트인 만큼 request 메소드를 따로 struct나 class 로 분리시키지 않고, View의 struct 에 같이 적을게요.

struct ContentView: View {
    @State private var launches: LaunchListQuery.Data.Launch? // 서버에서 받은 값을 넣어줄 예정.

    var body: some View {
        Text(launches?.cursor ?? "")
            .onAppear(perform: requestData)
    }
}

launches 프로퍼티를 만들어주고 타입은 API.swift 에서 자동으로 만들어진 model 을 사용합니다.
launches 의 값을 간단하게 Text 로 표시해볼게용

    private func requestData() {
        NetworkManager.shared.apollo.fetch(query: LaunchListQuery()) { result in
            switch result {
            case .success(let graphQLResult):

                if let launches = graphQLResult.data?.launches {
                    self.launches = launches // view 에 표시할 값에 대입.

                    return
                }

                if let errors = graphQLResult.errors {
                    print(errors.map { $0.localizedDescription })
                }

            case .failure(let error):
                print(error.localizedDescription)
            }
        }
    }

– 별도의 모델을 작성할 것도, 파싱할 것도 없이 Apollo 가 자동으로 만들어준 API.swift 를 사용해 원하는 property 값에 넣어주었습니다.

– Apollo 를 통해 GraphQL 로 리퀘스트까지 성공했습니당 👏


😉전체 코드

////// NetworkManager.swift

import Foundation
import Apollo

final class NetworkManager {
    static let shared = NetworkManager()

    private let requestURL = URL(string: "https://apollo-fullstack-tutorial.herokuapp.com/")! // 예제니까 !를 용서해주세요🙏
    private (set) lazy var apollo = ApolloClient(url: requestURL)
}


////// ContentView.swift

import SwiftUI

struct ContentView: View {
    @State private var launches: LaunchListQuery.Data.Launch?

    var body: some View {
        Text(launches?.cursor ?? "")
            .onAppear(perform: requestData)
    }

    private func requestData() {
        NetworkManager.shared.apollo.fetch(query: LaunchListQuery()) { result in
            switch result {
            case .success(let graphQLResult):

                if let launches = graphQLResult.data?.launches {
                    self.launches = launches

                    return
                }

                if let errors = graphQLResult.errors {
                    print(errors.map { $0.localizedDescription })
                }

            case .failure(let error):
                print(error.localizedDescription)
            }
        }
    }
}




초반의 Run script 설정이 Package Manger에 따라 달라서 번거로워서 그렇지
실제로 코드에서 사용되는 request 코드는 너무너무 간단하죠?

Server 를 기준으로 옵셔널과 타입까지 지정되어서 크라이언트쪽에서 고민해야할 것들이 줄어든 것 같아요.

간단하게 View에서 표시하는것 밖에 없었기 때문에 GraphQL 관련 파일들을 별도의 폴더를 나누지 않았지만,
실제로 운영되는 프로젝트였다면 GraphQL 관련 파일들을 따로 Module로 분리하는 것도 좋을 것 같아요.

도움이 되셨을지 모르겠네요 😇 그럼 오늘도 즐거운 iOS 개발 되세용

“iOS | Apollo을 사용해서 GraphQL API 의 리퀘스트를 해보자.”의 1개의 생각

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중