감자주먹밥

[Kotlin] Retrofit2 사용하기 본문

Android

[Kotlin] Retrofit2 사용하기

JustHm 2021. 6. 28. 22:53
728x90

앱 개발 하면서 API 사용해보는것도 할 줄 알아야 한다는 말을 듣고

간단한 API를 호출 해 보는 코드를 작성해 보았습니다.

무언갈 만들려고 했지만 항상 전공공부에 막혀서 제대로 된 어플 만들 시간이 부족해지구,,,

종강하면 간단한 앱이라도 퀄리티 좋게 만들어 봐야겠습니다!

Retrofit은 속도, 편의성, 가독성에 장점이 있다고 합니다.

annotation 을 사용하여 호출 할 함수를 파라미터와 정의를 해 놓고 호출만 하면 통신이 이뤄지기에 코드를 읽기 아주 편합니다!


implementation 'com.squareup.okhttp3:okhttp:4.9.0'

implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0' //retrofit2

implementation 'com.squareup.retrofit2:retrofit:2.6.2'

implementation 'com.squareup.retrofit2:converter-gson:2.6.2'

위에 두 개는 retrofit을 사용할때 okhttp는 네트워크 요청을 처리하기 위해 사용 한 것이고,

logging-interceptor는 네트워크 요청에 대한 로그를 찍어보기 위해서 추가 한 것입니다.

밑에 두 개가 api 호출을 위한 retrofit 라이브러리입니다.

gson은 JAVA객체를 JSON으로 구현할 수 있게 해주는 라이브러리라고 해서 넣기는 했는데,,,

API 호출하면 보통 JSON으로 와서 그런건 알겠는데

Kotlin 쓰는데 이게 적용이 되나 싶지만 일단 예제 같은거 보면서 따라 했습니다 ㅠㅠ

아시는 분 있으시면 지적부탁합니다!

interface BusAPI {
    @GET("facilities/station/getDataList")
    fun getStationInfo(
        @Query("output") output: String = "json"
    ): Call<BusResult?>
}

가장 먼저 API에 대한 인터페이스를 작성해줍니다!

통신을 위한 인터페이스로써 GET 방식으로 API 주소를 넣어주고 세팅을 해 주는 것입니다.

POSTMAN을 먼저 써보면서 API를 테스트 해보면 이 구조에 대해 이해하기 쉬울 것입니다!

annotation GET 뒤에 있는 주소는 BASE URL을 넣어준 것입니다.

GET, POST, PUT, PATCH, DELETE 등이 있음.

API 토큰 인증이 필요 없어서 따로 하지는 않았지만 필요하다면 HEADER annotation으로 추가 할 수 있습니다.

Example)

interface GeoService {
    @Headers(
        "X-NCP-APIGW-API-KEY-ID: (발급 받은 Client ID)",
        "X-NCP-APIGW-API-KEY: (발급 받은 Secret Key)"
    )
    @GET("gc")
    fun getAddress(
        @Query("coord") coord: String,
        @Query("output") output: String = "json"
    ): Call<GeoResponse>
}

물론 코드에 KEY를 노출 시키면 보안상 문제가 있으니 이렇게는 웬만하면 만들지 않기 파일을 읽어와서 넣어주기

object RetrofitClient{
    const val BASE_URL = "http://bus.andong.go.kr:8080/api/"
    val service: BusAPI = create()

    private fun create(): BusAPI {
        val httpLoggingInterceptor = HttpLoggingInterceptor()
        httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY

        val headerInterceptor = Interceptor { 
            val request = it.request()
                .newBuilder()
                .build()
            return@Interceptor it.proceed(request)
        }

        val client = OkHttpClient.Builder() // OKHTTP 클라이언트 넣는 부분
            .addInterceptor(headerInterceptor)
            .addInterceptor(httpLoggingInterceptor)
            .build()

        return Retrofit.Builder() // retrofit 구성부분
            .baseUrl(BASE_URL)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(BusAPI::class.java)
    }

}

Retrofit 클라이언트를 생성해 주는 부분입니다.

맨 아래 return 하는 부분이 생성하는 부분인데, 마지막 create에는 만들어줬던 API-INTERFACE를 넣어줘서

위 인터페이스를 구현한 클래스가 생성되어 그 클래스로 통신이 이루어집니다.

추가로 client를 만들어서 넣어주었는데, 이것은 네트워크 요청, 통신을 위한 클라이언트를 정의해서 넣어준 것입니다. LoggingInterceptor도 넣어주어서 통신 시 로그도 확인 할 수 있습니다!

data class Station(
    @SerializedName("stationId")
    val stationId: Int,
    @SerializedName("stationNm")
    val stationName: String,
    @SerializedName("gpsX")
    val positionX: Double,
    @SerializedName("gpsY")
    val positionY: Double
)

data class BusResult(
    @SerializedName("results")
    var results: List<Station>
)

API 호출 시 나오는 응답 데이터에 맞춰 데이터 클래스를 만들어 놓는다.

어노테이션으로 네이밍을 응답 데이터와 같게 해주면 알아서 통신 하면서 데이터가 들어온다.

private fun requestStation() {
        RetrofitClient.service.getStationInfo().enqueue(object : Callback<BusResult?> {
            override fun onResponse(call: Call<BusResult?>, response: Response<BusResult?>) {
                station = response.body()?.results!!
                //setMarker()
            }

            override fun onFailure(call: Call<BusResult?>, t: Throwable) {
                Log.d("JUSTHM", "FAIL LOAD API")
            }

        })
    }

지금까진 준비 과정이고 이제 진짜로 요청을 하는 부분이다!

아까 인터페이스에서 정의했던 getStationInfo()를 호출해서 Retrofit으로 통신하고 응답을 받게 된다.

enqueue()는 비동기 통신을 하는것이고, 동기적으로 통신을 할 땐 execute()를 쓰면 된다.

비동기 통신으로 할 땐 인자로 응답이 왔을때의 콜백 함수를 지정해 주면 되고,

동기로 통신을 할 땐 execute()의 반환 값으로 응답 데이터가 반환된다.

 

 

GitHub - JungHm/testapp

Contribute to JungHm/testapp development by creating an account on GitHub.

github.com


참고

https://s2choco.tistory.com/28

[Android] Retrofit2 + Gson 사용하기 (with Kotlin)

https://woovictory.github.io/2019/01/03/Android-What-is-retrofit/

728x90
Comments