개발 끄적끄적/Android

[Android Kotlin] Retrofit2 사용방법 - Interface와 Data Class까지

공간을담다 2020. 6. 4. 02:15
반응형

공공데이터 등 REST API를 사용해야 할 일은 정말정말 많습니다. 이때 사용할 수 있는 오픈소스 라이브러리인 Retrofit의 사용방법을 설명드리겠습니다.


REST API란?

  • REST는 Http를 조금 더 효율적으로 사용하기 위한 아키텍처입니다.

 

HTTP Method

  • POST : 리소스 생성
  • GET : 리소스 조회 및 출력
  • PUT : 리소스 수정
  • PATCH : 리소스 수정
  • DELETE : 리소스 삭제

둘 다 리소스 수정 기능을 하지만 PUT과 PATCH에는 차이점이 있습니다.

PUT은 해당 리소스의 전체를 교체하는 의미를 지녔지만, PATCH는 일부를 변경하는 의미를 지녔습니다.

 

 

HTTP 응답 코드

  • 1** : 요청을 받았으며 프로세스를 계속함 (정보)
  • 2** : 클라이언트의 요청을 정상적으로 수행 (성공)
  • 3** : 요청 완료를 위해 추가적인 작업 조치가 필요함 (리다이렉션)
  • 4** : 요청의 문법이 잘못되었거나 요청을 처리할 수 없음 (클라이언트 오류)
  • 5** : 서버가 명백히 유효한 요청에 대해 실패함 (서버 오류)

 

 

 

 

 

build.gradle (Module: app)

implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
implementation 'com.squareup.retrofit2:converter-gson:2.6.0'

 

AndroidManifest.xml

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

 

retrofit에 관한 모듈을 추가해주고 인터넷을 사용하기 때문에 Manifest에 인터넷 권한도 추가해줍니다.

 

 

 

 

 

 

이제 Retrofit 사용 방법에 대해 알아보겠습니다.

 

 


경기데이터드림에서 제공하는 공공 API를 활용해 코드를 작성해보겠습니다. 경기데이터드림의 여러 데이터 중 지역화폐 가맹점 현황을 보여주는 api를 예시로 들겠습니다.

 

경기데이터드림 - 지역화폐 가맹점 현황

위와 같은 조건의 공공데이터를 읽어오는 방법을 알아보겠습니다.

 

 

 

MainActivity.kt

val regionRetrofit = Retrofit.Builder()
    .baseUrl("https://openapi.gg.go.kr")
    .addConverterFactory(GsonConverterFactory.create())
    .build()
var regionServer: RetrofitService? = regionRetrofit.create(RetrofitService::class.java)

 

위와 같이 경기데이터드림의 URL인 "https://openapi.gg.go.kr"을 baseUrl로 지정해줍니다. 요청주소 뒤의 "RegionMnyFacltStus"까지 넣지 않는 이유가 있습니다. 이 부분은 path로 처리되며 코드의 재사용성을 높이기 위함입니다.

 

만약

  • https://api.go.kr/user_name  
  • https://api.go.kr/user_address                    
  • https://api.go.kr/user_phone

위와 같은 요청을 필요로 한다고 가정하겠습니다. 변하지 않는 "https://api.go.kr" 을 baseUrl로 하고 뒤의 user_* 을 Interface에서 조절한다면 RetrofitService 객체를 여러 번 생성하지 않아도 되는 것입니다. 

 

 

 

RetrofitService.kt (Interface)

interface RetrofitService {
    @GET("/RegionMnyFacltStus")
    fun getInfo(@Query("Type")Type:String,
                @Query("KEY")KEY:String,
                @Query("pIndex")pIndex:Int? = null,
                @Query("pSize")pSize:Int? = null) : Call<DataClass>
}

이렇듯 baseUrl 외에 path(지역화폐 가맹점 현황)에 해당하는 "RegionMnyFacltStus"는 인터페이스에서 선언해주는 것이 코드의 재사용성을 높일 수 있습니다.

경기데이터드림에서 요구하는 기본인자를 @Query 형태로 보낼 수 있습니다. 이때, pIndex와 pSize는 Nullable로 처리해주었습니다. 경기데이터드림에서 제공하는 기본값이 정해져있어 null로 보내도 되기 때문입니다.

후에 getInfo() 메소드를 사용할 시 선택적으로 값을 기입할 수 있습니다.

 

 

 

DataClass

data class DataClass(var RegionMnyFacltStus:List<Map<String, List<Map<String,Any>>>>?=null)

경기데이터드림에서 제공하는 API의 데이터 구조가 너무나도 복잡해 DataClass의 구조가 복잡해졌습니다.

 

 

쉬운 예시를 들겠습니다.

사용하고자 하는 API의 response body가 

{
    "body":{
    	"name" : "철수",
        "address" : "강남",
        "phone_number" : "010-000-0000"
    }
}

처럼 되어있다고 가정하겠습니다. (response body는 Postman에서 확인 가능합니다)

 

이럴 경우에 DataClass는 아래와 같이 됩니다.

data class DataClass(var body:DataClassBody)
data class DataClassBody(var name:String, var address:String, var phone_number:String)

 

 

 

MainActivity.kt

regionServer?.getInfo("json", "")?.enqueue(object : Callback<DataClass>{
    override fun onFailure(call: Call<DataClass>, t: Throwable) {t.printStackTrace()}
    override fun onResponse(call: Call<DataClass>, response: Response<DataClass>) {
        var name = response?.body()?.body?.name
        var address = response?.body()?.body?.address
        var phoneNum = response?.body()?.body?.phone_number
    }
})
  • 앞서 선언해둔 regionServer와 getInfo() 메소드, DataClass를 사용합니다.
  • getInfo()의 인자값으로 API에서 요구하는 값을 넣어야 합니다. (pIndex, pSize = null 처리함)
  • onResponse()와 onFailure()를 오버라이딩합니다.
  • onResponse() 내에서 response로 요청한 데이터에 접근할 수 있습니다.
  • response?.body()?.* 의 형식으로 접근할 수 있습니다.

 

 

 

 

 

 

 

 

 

반응형