[목차]
- 도입
- 용어 정리
- 프로젝트에 Apollo 추가하기
- Schema 추가하기
- 쿼리 추가하기
- 쿼리 실행하기
- 마무리
[도입]
이름과 대략적인 내용만 들어보고 써보진 않았다. 최근에 쓰게될 일이 생겨서 그 전에 테스트 겸 셀프 실습을 진행해본다. 모킹 서버를 어디서 찾을까 하다가 Rick and morty (예전에 즐겨본 애니메이션) api 가 눈에 들어왔고 Apollo, GraphQL 공식문서를 참고하여 적용하려 한다. 설레는 마음으로 시작!
릭앤모티 api
Apollo 공식문서 tutorial
GraphQL 공식문서 Introduction
[용어 정리]
<Graphql>
REST API 처러 정해진 모든 양의 데이터가 아닌 원하는 정보만 가져올 수 있다.
여러 depth 의 정보를 한 번의 요청으로 받아올 수 있다.
여러 플랫폼의 여러 각 상황마다 가져와야할 데이터가 다를 때 매우 유용하다. (서버에서 각 상황에 맞는 api 를 만들필요가 없기 때문)
받아야할 항목들이 많고 여러 플랫폼의 각 상황에서 받아야할 정보가 통일되어있다면 REST API 를 사용하고 그렇지 않다면 Graphql 방식을 사용할 것 같다.
(물론 REST API, Graphql 둘 다 만들어놓을 수 있다.)
<Apollo>
Apollo Kotlin 은 GraphQL 쿼리들로 부터 Kotlin, Java 모델들을 생성해주는 GraphQL client 이다.
GraphQL server 로 부터 query 와 mutation 을 실행해주고 쿼리에 명시해놓은 결과를 반환해준다.
JSON 파싱이나 타입 같은 우리가 수동으로 해야할 일을 자동으로 해준다.
[프로젝트에 Apollo 추가하기]
아래 세 가지 모두 app/build.gradle.kts 에 더해준다.
id("com.apollographql.apollo3").version("3.2.0")
⬆️위 플러그인이 프로젝트 빌드할 때, 내 쿼리로부터 모델을 생성하는 컴파일러를 포함하고 있다.
implementation("com.apollographql.apollo3:apollo-runtime:3.2.0")
⬆️dependency 추가
apollo {
packageName.set("com.nosorae.labs")
}
⬆️플러그인이 생성되는 코틀린 파일들을어느 패키지에 넣을지 설정하기 위한 작업 (나 같은 경우는 패키지 네임 통일)
[Schema 추가하기]
schema 는 서버가 어떤 Graphql 오퍼레이션을 수행할 수 있는지 정의해놓은 것이다.
Apollo Kotlin 은 우리의 쿼리로 부터 type-safe model 과 코드를 생성하기 위해 schema 를 필요로 한다.
아래와 같은 형식으로 플러그인에의해 생성된 apolloDownloadSchema 라는 Gradle task 를 사용해서 받아올 수 있다. (물로 스키마 받아오는 다른 다양한 방법이 있음 이번에 사용하는 rick and morty api 같은 경우는 json or sdl 형식으로 다운 받을 수 있게 해주더라. 근데 그 방법으로 )
app/src/main 패키지 안에 (java 패키지와 동일한 레벨에) graphql 패키지를 만들자 그리고 schema 를 추가해준다.
.graphqls 로 받아온다.
./gradlew :app:downloadApolloSchema --endpoint='https://rickandmortyapi.com/graphql' --schema=app/src/main/graphql/com/nosorae/labs/schema.graphql
[쿼리 추가하기]
이제 아무 쿼리를 추가해보자.
(참고한 다른 블로그에서는 Chraracters 로 하길래 나는 Locations 로 해보았다)
릭앤모티 api Playground 로 가서 DOCS 나 SCHEMA를 활용해서 기본적인 쿼리를 작성해보자
이제 위 쿼리를 프로젝트 파일로 만들어보자
쿼리 파일은 스키마와 같은 패키지 안에 그리고 같은 패키지 레벨에 있게 해야한다.
Locations.graphql 로 추가해준다.
여기서 주의할 점은 쿼리는 graphql, 스키마는 graphqls 여야한다는 것이다.
(아직 왜인지는 모르겠으나 공식문서 튜토리얼에서 그렇게 하고 있다. 둘 다 graphqls 로 시도해봤는데 excutable definition 을 찾을 수 없다는 아래와 같은에러가 발생한다.)
(참고로 스키마를 .graphql 로 만들면 아래와 같은 에러가 발생한다.)
쿼리를 추가했다면 이제 빌드해서 코드 생성을 마치어보자
빌드하면 Apollo Kotlin plugin 이 model 을 생성해준다.
(참고로 이 태스크의 이름은 generateApolloSources 이다.)
아래 사진과 같이 확인해도 되고
shift 연타해서 클래스를 검색해서 확인할 수도 있다.
여기까지가 쿼리 코드 생성이다.
[쿼리 실행하기]
매우 간단하다.
먼저 ApolloClient 객체를 Builder 패턴으로 생성해준다.
그리고 분리된 코루틴에서 쿼리를 날려주면된다.
MVVM 패턴을 적용할 예정이긴 하지만 이 글에서 그것까지 다루는 것은 비효율적이라고 생각해서
여기서는 바로 Activity 에서 불러와서 실행하는 코드를 실행해보았다.
class ApolloTestActivity : AppCompatActivity() {
val apolloClient = ApolloClient.Builder()
.serverUrl("https://rickandmortyapi.com/graphql")
.build()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_apollo_test)
lifecycleScope.launch {
val response = apolloClient.query(LocationsQuery()).execute()
Log.d("LocationsQuery", "Success ${response.data}")
}
}
}
-> 결과
D/LocationsQuery: Success Data(locations=Locations(info=Info(count=126), results=[Result(id=1, name=Earth (C-137), type=Planet), Result(id=2, name=Abadango, type=Cluster), Result(id=3, name=Citadel of Ricks, type=Space station), Result(id=4, name=Worldender's lair, type=Planet), Result(id=5, name=Anatomy Park, type=Microverse), Result(id=6, name=Interdimensional Cable, type=TV), Result(id=7, name=Immortality Field Resort, type=Resort), Result(id=8, name=Post-Apocalyptic Earth, type=Planet), Result(id=9, name=Purge Planet, type=Planet), Result(id=10, name=Venzenulon 7, type=Planet), Result(id=11, name=Bepis 9, type=Planet), Result(id=12, name=Cronenberg Earth, type=Planet), Result(id=13, name=Nuptia 4, type=Planet), Result(id=14, name=Giant's Town, type=Fantasy town), Result(id=15, name=Bird World, type=Planet), Result(id=16, name=St. Gloopy Noops Hospital, type=Space station), Result(id=17, name=Earth (5-126), type=Planet), Result(id=18, name=Mr. Goldenfold's dream, type=Dream), Result(id=19, name=Gromflom Prime, type=Planet), Result(id=20, name=Earth (Replacement Dimension), type=Planet)]))
[마무리]
이제야 Apollo, Graphql 과의 인사를 마쳤다. 새로운 기술을 배우는 것은 항상 설레는 것 같다.
과거 진행했던 프로젝트들을 떠올려보니 REST API 보다 GraphQL 이 더 적절했던 때가 보인다. 같은 회원정보라 할지라도 플랫폼이나 화면마다 필요한 정보의 범위 (프로퍼티의 개수) 가 다른데, REST 로는 네트워크 통신량을 줄이자니 API 를 여러개 만들어야하는 번거로움이 있고 하나의 API 로 통일해서 쓰자니 불필요한 정보까지 받아온다는 문제점이 있었던 때가 떠올랐다.
앞으로는 실제 프로젝트에 적용해보며 상황에 맞는 다양한 기능을 적용해볼 것 같다. 그 때마다 블로그에 글을 정리할 예정이다. (빨리 프로젝트에 투입되고 싶다..!)
'Android > 이론 학습' 카테고리의 다른 글
[Android/Compose] Composable 에서 Runtime permission 요청하기 (0) | 2022.12.27 |
---|---|
[Android/Firebase] 기존 프로젝트에 Crashlystics 적용하기 (0) | 2022.03.06 |
[Kotlin/백준] 5430, AC (시간초과 해결) (0) | 2022.02.27 |
[Android] WorkManager 로 복잡한 백그라운드 작업을 쉽게 해결한다고? (기본 사용법과 예시코드 포함) (0) | 2022.02.23 |
[Android] Service 의 타입과 사용법 그리고 권장사항 (0) | 2022.02.23 |