Cara mengkonfigurasi Apollo agar berfungsi dengan GraphQL di Android

Mengapa sebuah artikel?


Baru-baru ini, saya memiliki kebutuhan untuk mengimplementasikan kerja dengan backend di GraphQL. Tidak ada begitu banyak tutorial untuk menyiapkan di Android, tidak seperti REST, dan kebanyakan dari mereka tidak lagi cukup relevan.

Apa itu GraphQL?


GraphQL adalah alternatif modis untuk REST API, yang memungkinkan Anda untuk meminta data dengan cara yang lebih optimal, hanya memberikan data yang Anda butuhkan.

Pengaturan lingkungan


Kami akan membuat permintaan ke server melalui Apollo - perpustakaan paling populer untuk bekerja dengan GraphQL saat ini.

Ayo mulai bekerja. Pertama-tama, mari kita tambahkan izin yang diperlukan untuk bekerja dengan jaringan ke manifes:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Selanjutnya, Anda perlu menghubungkan apollo. Kita pergi ke build.gradle utama dan di bagian dependensi tambahkan baris berikut:

classpath 'com.apollographql.apollo:apollo-gradle-plugin:2.0.0'

Sekarang Anda perlu menambahkan dependensi tambahan di file build.gradle dari modul aplikasi:

implementation("com.apollographql.apollo:apollo-runtime:2.0.0")
implementation "com.apollographql.apollo:apollo-android-support:2.0.0"

Selain itu, tambahkan koneksi plug-in ke bagian paling atas file:

apply plugin: 'com.apollographql.apollo'

Setelah proyek disinkronkan, kita perlu mengonfigurasi pembuatan kode dari model yang dengannya kita akan membuat kueri ke GraphQL.

Mari meminimalkan lingkungan pengembangan dan membuka terminal. Buka folder dengan proyek Anda:

cd /Users/user/Desktop/ProjectName

Jika Anda belum memiliki npm, unduh pertama dari situs resmi

Instal apollo-codegen - alat yang memungkinkan Anda mengunduh schema.json - file yang akan berfungsi sebagai sumber apollo untuk menghasilkan model:

npm install apollo-codegen

Unduh schema.json (Anda harus berada di direktori proyek Anda, tempat folder node_modules muncul):

node_modules/.bin/apollo-codegen download-schema https://   api/ --output schema.json

Sekarang di folder proyek kita melihat file schema.json. Tetap menampilkan file apollo untuk menghasilkan model. Untuk melakukan ini, lakukan langkah-langkah berikut.

Buka folder aplikasi proyek Anda, lalu src -> main. Di sini kita perlu membuat folder graphQL. Di sini kita akan menambahkan file .graphql kami.

Kami menyalin file yang diunduh pada langkah sebelumnya ke folder yang dibuat - schema.json
Lingkungan sudah diatur , buka kode

Pembuatan Kode Model


Mari kita mulai dengan file .graphql. Permintaan akan disimpan di sini.
GraphQL memiliki dua jenis kueri:
kueri - analog
mutasi GET - analog POST / PUT / DELETE

Misalkan Anda membuat layanan untuk memeriksa tamu di sebuah kamar di hotel untuk administrator hotel ini. Aplikasi dapat melakukan 3 fungsi. Login pengguna (administrator), dapatkan informasi tentang ruangan dengan id dan isi tamu

Buat file loginUser.graphql di aplikasi direktori / src / main / graphQL yang dibuat di bagian sebelumnya. Menggunakan file ini apollo akan menghasilkan model untuk nama pengguna.

Konten file:

mutation loginUser($email:String!, $password:String!) {
    login(
        user: {
            email: $email,
            password: $password
        }
    ){
        email,
        token,
        refreshToken
    }
}

Selain itu, kita memerlukan file getRoom.graphql, dengan bantuan model yang dihasilkan untuk mendapatkan kamar hotel:

query getRoom($room_id: String) {
    room(room_id: $room_id) {
        title,
        room_number,
        cheked_in_family_name,
        has_minibar
    }
}

Dan file terakhir adalah checkUserIn.graphql check-in. Juga menggunakan mutasi:

mutation checkInFamily($room_id: String!, $family_name: String!) {
    room(
        room: {
            title: $family_name,
            room_id: $room_id
        }
    ){
        room_id,
        family_name,
        minibar_products{
            title,
            weight
        }
    }
}

Kami membangun proyek dan melihat 3 model yang dihasilkan di folder app / build / generate / source / apollo / debug / service: GetRoomQuery, CheckUserInMutation, LoginUserMutation

Eksekusi query


Buat kelas NetworkService singleton yang akan memberi kami ApolloClient. Kami membuat 2 metode di dalamnya. getApolloClient () untuk menjalankan permintaan yang tidak memerlukan token atau parameter tambahan apa pun, dan getApolloClientWithTokenInterceptor (), di mana kami akan membuang token, untuk permintaan:

import com.apollographql.apollo.ApolloClient
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request

class NetworkService {

  fun getApolloClient(): ApolloClient {
    val okHttp = OkHttpClient
      .Builder()
      .build()

    return ApolloClient.builder()
      .serverUrl(BASE_URL)
      .okHttpClient(okHttp)
      .build()
  }

  fun getApolloClientWithTokenInterceptor(token: String): ApolloClient {

    val httpClient = OkHttpClient.Builder()
      .addInterceptor(Interceptor { chain: Interceptor.Chain ->
        val original: Request = chain.request()
        
        val builder: Request.Builder = original
          .newBuilder()
          .method(original.method, original.body)
        
        builder.header("Authorization", "Bearer $token")
        return@Interceptor chain.proceed(builder.build())
      })
      .build()

    return ApolloClient.builder()
      .serverUrl(BASE_URL)
      .okHttpClient(httpClient)
      .build()
  }

  companion object {
    private var mInstance: NetworkService? = null

    fun getInstance(): NetworkService? {
      if (mInstance == null) {
        mInstance = NetworkService()
      }
      return mInstance
    }
  }
}

Sekarang kita pergi ke aktivitas atau fragmen kita, di sini kita mengimplementasikan eksekusi permintaan. Untuk memulai, masuk:

  private fun loginUser() {

    val client = NetworkService.getInstance()?.getApolloClient()
    val loginMutation = LoginUserMutation
      .builder()
      .email(emailEdit.text.toString())
      .password(passwordEdit.text.toString())
      .build()

    client
      ?.mutate(loginMutation)
      ?.enqueue(object : ApolloCall.Callback<LoginUserMutation.Data>() {

        override fun onResponse(response: Response<LoginUserMutation.Data>) {
          if (!response.hasErrors()) {
            val token = response.data?.login()?.token()
            val email = response.data?.login()?.email()
            // ,   ui,     
            runOnUiThread {
              //   ,  
            }
          }
        }

        override fun onFailure(e: ApolloException) {}
      })
  }

Ini adalah contoh bekerja dengan mutasi. Kami melakukan permintaan ini tanpa token di header. Sekarang mari kita lihat contoh bekerja dengan permintaan, cobalah untuk mendapatkan informasi tentang ruangan. Misalkan sebuah ruangan diberikan kepada kita hanya dengan token. Kami melaksanakan permintaan sebagai berikut:

  private fun getRoom() {
    val token = "123456"
    val client = NetworkService.getInstance()
      ?.getApolloClientWithTokenIntercetor(token)

    val roomId = "123"
    val allRoomsQuery = GetRoomQuery(Input.fromNullable(roomId))

    client
      ?.query(allRoomsQuery)
      ?.enqueue(object : ApolloCall.Callback<GetRoomQuery.Data>() {

        override fun onResponse(response: Response<GetRoomQuery.Data>) {
          if (!response.hasErrors()) {
            val familyName = response.data?.room()?.family_name()
          }
        }

        override fun onFailure(e: ApolloException) {}
      })
  }

Sebagai pekerjaan rumah, cobalah untuk menulis sendiri implementasi dari penyelesaian tamu.

Tautan yang berguna:

dokumentasi apollo-client untuk Android
Github apollo-client android

All Articles