책 검색 앱 만들기(2) - Retrofit으로 카카오 책 검색 API 다루기

2023. 1. 18. 18:01Android Jetpack

    • Retrofit & Okhttp & Moshi

  • OkHttp

OkHttp는 Square에서 제공하는 HttpClient 라이브러리 이며,

쉽게 HTTP 기반의 Request / Response를 할 수 있도록 도와주는 오픈소스 라이브러리이다.

동기, 비동기 방식을 각각 제공하여 개발자가 선택하여 개발할 수 있다.

  • Retrofit

 

OkHttp를 사용하기 쉽게 래핑한 라이브러리 이다.

레트로핏은 안드로이드와 자바에서 쉽게 RESTful한 통신을 할수있도록해준다.

레트로핏을 더 편리하게 쓰기위해 흔히 OkHttp를 함께 사용한다.

 


 

Moshi vs Gson in android

I'm deciding on whether to use Moshi by square or Gson to serialize and deserialize model data. one thing i always did not like about Gson is i think it uses reflection which can be slow on and...

stackoverflow.com

 


  • build.gradle
//Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
//moshi
implementation "com.squareup.moshi:moshi:1.14.0"
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.14.0"
// OkHttp
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'

-> 서버와 통신을 하기위해 모듈에 의존성을추가해준다.

 

  • 카카오 책 검색 api

  • 플러그인에서 json to kotlin class를 installed해준다.

 

 

 

  • Json 응답으로부터  데이터 가져오기.

 

  • Advaced에 Annotation / Moshi로 바꾸자

  • 3개의 데이터클래스가 생성

 

package com.example.kakaobook.ui.view.data.model


import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
data class SearchResponse(
    @Json(name = "documents")
    val documents: List<Book>,
    @Json(name = "meta")
    val meta: Meta
)

 

package com.example.kakaobook.ui.view.data.model


import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
data class Book(
    @Json(name = "authors")
    val authors: List<String>,
    @Json(name = "contents")
    val contents: String,
    @Json(name = "datetime")
    val datetime: String,
    @Json(name = "isbn")
    val isbn: String,
    @Json(name = "price")
    val price: Int,
    @Json(name = "publisher")
    val publisher: String,
    @Json(name = "sale_price")
    val salePrice: Int,
    @Json(name = "status")
    val status: String,
    @Json(name = "thumbnail")
    val thumbnail: String,
    @Json(name = "title")
    val title: String,
    @Json(name = "translators")
    val translators: List<String>,
    @Json(name = "url")
    val url: String
)

 

package com.example.kakaobook.ui.view.data.model
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass


@JsonClass(generateAdapter = true)
data class Meta(
    @Json(name = "is_end")
    val isEnd: Boolean,
    @Json(name = "pageable_count")
    val pageableCount: Int,
    @Json(name = "total_count")
    val totalCount: Int
)
  • @field:Json : 키,벨류 형식으로 데이터를 전달한다고함. 

 

  • Api키 URL 같은경우  여러 코틀린 파일에서 쓰일 거 같으면 class로 분리하여 사용한다.
package com.example.kakaobook.ui.view.data.model.util

import com.example.kakaobook.BuildConfig

 class Constants {
     companion object {
         const val Base_url = "https://dapi.kakao.com/"
         const val api_key = BuildConfig.bookApiKey
     }
 }

 


build.gradle(프로젝트 루트 파일)

 //Secrets Gradle plugin for Android
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1' apply false

 

build.gradle( 모듈 파일)

plugins {
    ..//
    id"com.google.android.libraries.mapsplatform.secrets-gradle-plugin"
}

 

로컬 프로퍼티에 bookapikey를 추가 

bookApiKey = api키

마지막에 상단바에있는  Build를 눌러  Rebuild Project해주면된다.

 

 

  • GET 요청을 수행하는 서비스.
package com.example.kakaobook.ui.view.data

import com.example.kakaobook.ui.view.data.model.SearchResponse
import com.example.kakaobook.ui.view.data.model.util.Constants.Companion.api_key
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.Query

interface BookSearchApi {

    @Headers("Authorization: KaKaoAK $api_key")
    @GET("v3/search/book")
    suspend fun searchBooks(
        @Query("query") query:String,
        @Query("sort") sort:String,
        @Query("page") page:String,
        @Query("size") size:Int,
    ):Response<SearchResponse>

}
  • Retrofit 인스턴스
package com.example.kakaobook.ui.view.data.api

import com.example.kakaobook.ui.view.data.BookSearchApi
import com.example.kakaobook.ui.view.data.model.util.Constants.Companion.Base_url
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory


object RetrofitInstance {
   // 로깅인터셉트는 통신중간에 끼어들어 통신이 잘 되고 있는지를 로그로 찍어준다.
    private val okHttpClient: OkHttpClient by lazy {
        val httpLoggingInterceptor = HttpLoggingInterceptor()
            .setLevel(HttpLoggingInterceptor.Level.BODY)
        OkHttpClient.Builder()
            .addInterceptor(httpLoggingInterceptor)
            .build()
    }
    private val retrofit by lazy {
        Retrofit.Builder()
            .addConverterFactory(MoshiConverterFactory.create())
            .baseUrl(Base_url)
            .client(okHttpClient)
            .build()
    }
    val api: BookSearchApi by lazy {
        retrofit.create(BookSearchApi::class.java)
    }
}

이 클래스에서 레트로핏 통신을 위한 셋팅을 한다고 생각하면 된다.

싱글턴 Object를 사용하여 하나의 인스턴스를만들엇다.

BAS_URL을 지정해주고, 로깅 인터셉터를 설정, Moshi Converter 지정과 같은 작업들을 해준다