Retrofit으로 Rest API를 사용해보자

지프치프·2021년 12월 10일
0

Android

목록 보기
34/86
post-thumbnail

“Android 로봇은 Google에서 제작하여 공유한 저작물을 복제하거나 수정한 것으로 Creative Commons 3.0 저작자 표시 라이선스의 약관에 따라 사용되었습니다.”


Retrofit이란?

Retrofit이란 같은 회사인 Squareup 사의 okhttp을 기반으로
http 통신을 어노테이션으로 간편하게 구현할 수 있게 해주는 라이브러리이다.

구현

먼저 데이터를 받아올 Rest API는 JsonPlaceHolder을 사용하기로 했다.
이 JsonPlaceHolder는 Rest를 테스트 해볼 수 있는 API 서버이다.

위 서버에서 제공하는 데이터는 아래와 같다.

{
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

DTO

첫번째로 위 데이터들을 담아줄 DTO(Data Transper Object)를 만들어보자.

data class JsonPlaceDTO(
    @Expose
    @SerializedName("userId")
    var userId: String,

    @Expose
    @SerializedName("id")
    var id: String,

    @Expose
    @SerializedName("title")
    var title: String,

    @Expose
    @SerializedName("body")
    var body: String
)

여기서 각 어노테이션의 뜻은

  • @Expose
    이 멤버가 Json으로부터 역직렬화 될 것임을 명시함
  • @SerializedName
    대상 Json에서 해당 이름을 가진 멤버가 대입됨을 명시

Service

Retrofit에서 핵심이 될 수도 있는 Service이다.
어노테이션을 이용해서 요청할 방식을 지정한다.

interface RestService {
    @GET("/posts")
    fun callGet() : Call<JsonObject>

    @GET("/posts/{path}")
    fun callGetPath(@Path("path") path: String) : Call<JsonPlaceDTO>
    
    @POST("/posts")
    fun callPost() : Call<JsonPlaceDTO>
}

HTTP 요청 Method 4가지를 모두 지원하며
(GET, POST, PUT, DELETE)

어노테이션을 이용해서 header나 body도 넣을 수 있다.

RetroClient

object RetroClient {
    private var instance: Retrofit? = null
    fun getInstance() : Retrofit {
        instance?.let {
            return it
        } ?: run {
            instance = Retrofit.Builder()
                .baseUrl("https://jsonplaceholder.typicode.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build()
            return instance!!
        }
    }
}

Retrofit을 초기화하는 코드를 싱글톤으로 구현하였다.

  • baseUrl()
    API의 root url을 설정한다
  • addConvertFactory()
    요청 후 받은 응답(Response)를 변환할 방식을 설정한다.
    변환할 방식 (Convertor)는 아래의 종류가 있다.
    - Gson: com.squareup.retrofit:converter-gson
    - Jackson: com.squareup.retrofit:converter-jackson
    - Moshi: com.squareup.retrofit:converter-moshi
    - Protobuf: com.squareup.retrofit:converter-protobuf
    - Wire: com.squareup.retrofit:converter-wire
    - Simple XML: com.squareup.retrofit:converter-simplexml
  • build()
    설정된 retrofit 인스턴스를 반환

실행

이제 Activity에서 실행해보자

            val service = RetroClient.getInstance().create(RestService::class.java)
            val call = service?.callPost("1")
            call?.enqueue(object : Callback<JsonPlaceDTO> {
                override fun onResponse(call: Call<JsonPlaceDTO>, response: Response<JsonPlaceDTO>) {
                    if(response.isSuccessful) {
                        MyLogger.i("Rest Success, body is ${response.body()}")
                        response.body()?.let {
                            binding.tvRest.text = "${it.id}\r\n\r\n${it.title}\r\n\r\n${it.body}"
                        }
                    }
                    else {
                        runOnUiThread { binding.tvRest.text = "Rest not Success" }
                        MyLogger.e("Rest not success, code is ${response.code()} and request here ${response.raw().request()}")
                    }
                }

                override fun onFailure(call: Call<JsonPlaceDTO>, t: Throwable) {
                    runOnUiThread { binding.tvRest.text = "Rest failure" }
                    MyLogger.e("Rest failure >> ${t.message}")
                }
            })

살펴보면

val service = RetroClient.getInstance().create(RestService::class.java)

Retrofit을 통해 service의 인스턴스를 만들어주고

val call = service?.callPost("1")

request를 서버에 보내고 response를 반환하는 Call<T>의 인스턴스 생성

    call?.enqueue(object : Callback<JsonPlaceDTO> {
	override fun onResponse(call: Call<JsonPlaceDTO>, response: Response<JsonPlaceDTO>) { }
    	override fun onFailure(call: Call<JsonPlaceDTO>, t: Throwable) { }
    })
- enqueue
요청을 비동기로 처리하고 응답을 콜백으로 전달
- onResponse
응답(response)가 성공하면 호출되는 콜백
- onFailure
응답(response)가 실패하면 호출되는 콜백


실행해보면 위 캡쳐처럼 정상적으로 작동하는 것을 볼 수 있다.

지금까지 Retrofit으로 Rest API를 호출해보았다.
간단하게 사용해보았는데 좀 더 디테일하게 사용한다면
okhttp client를 Retrofit에 등록하여 cookie나 header를 지정하거나 logging을 사용할 수도 있다.

이 외의 더 자세한 설명은 공식 문서를 참고하면 좋겠다.

개인적으로 공부했던 것을 바탕으로 작성하다보니
잘못된 정보가 있을수도 있습니다.
인지하게 되면 추후 수정하겠습니다.
피드백은 언제나 환영합니다.
읽어주셔서 감사합니다.

profile
지프처럼 거침없는 개발을 하고싶은 개발자

0개의 댓글