Android

Android Retrofit 사용하여 API 호출하기

BBiRaRiRo 2021. 9. 25. 17:36

1 Retrofit


Retrofit는 REST 기반 웹 서비스를 통해 JSON 혹은 그 외의 데이터를 요청하고
응답받는 것을 쉽게 하는 라이브러리이다.
Retrofit는 HTTP 요청을 OkHttp 라이브러리를 사용한다.

Retrofit 문서

1.1 API 확인

https://baseURL.co.kr/user/login
post{
	id ="id",
	pwd="pwd"
}

위와같은 API를 호출한다.

API 성공 응답

{
  "success": true,
  "code": 0,
  "msg": "성공하였습니다.",
  "data": {
    "token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJWyJS9VUZXhwIjoxVpUhJBk03uo",
    "status": "A",
    "time": null
  }
}

API 실패 응답

{
  "success": false,
  "code": -1002,
  "msg": "아이디 또는 패스워드가 정확하지 않음"
}

2 구현


2.1 의존성 추가

implementation 'com.squareup.retrofit2:retrofit:2.9.0' 
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

2.2 ApiConstants

object ApiConstants {
    const val BASE_URL:String ="https://baseURL.co.kr"
    const val LOGIN_API_PATH:String ="/user/login"
}

API 경로를 한곳에서 관리하려고 만든 kt 파일이다.

2.3 RetrofitClient

object RetrofitClient {
    private var instance : Retrofit? = null

    fun getInstance() : Retrofit {
        if(instance == null){
            instance = Retrofit.Builder()
                .baseUrl(ApiConstants.BASE_URL) //api 의 기본 uri
                .addConverterFactory(GsonConverterFactory.create())
                .build()
        }
        return instance!!
    }
}

Retrofit를 생성하여 사용할 수 있는 Class 파일을 만들어줘야 한다.

 

2.4 응답 받을 데이터 포멧 준비

abstract class ServerResponse {
    val success: Boolean? = null
    val code: Int? = null
    val msg: String? = null
}

 

data class ServerLoginResponse (
    @SerializedName("data")
    val data:Data
): ServerResponse()

data class Data(
    @SerializedName("token")
    val token:String,
    @SerializedName("status")
    val status:String,
    @SerializedName("time")
    val time:String?
)

위에서 알아본 성공 실패의 데이터를 기준으로 data class를 만들어줘야
api 요청 후 결과를 그대로 받을 수 있다.

2.5 API 인터페이스

interface ILoginAPI {

    @POST(ApiConstants.LOGIN_API_PATH)
    fun loginCall(
        @Body json:JsonObject
    ) : Call<ServerLoginResponse>
}

@POST 가있는 것처럼 @GET 등 모두 다양하게 제공한다.
원하는 메서드를 사용하면 되고

@Body는 JSON 을 보낼 때 사용된다.
리턴으로 위에서 만든 data class 가있는 것을 볼 수 있다.
서버의 요청 값을 해당 형태로 받는다.

2.6 LogingAPI 구현

class LoginAPI {
    fun login(id:String , pwd:String,completion:(Boolean)-> Unit){
        try{
            var retrofit = RetrofitClient.getInstance()
            var loginApi = retrofit.create(ILoginAPI::class.java)
            val jsonData: JsonObject = JsonObject().apply {
                addProperty("id", id)
                addProperty("pwd", pwd)
            }
            loginApi.loginCall(jsonData).enqueue(object : Callback<ServerLoginResponse> {
                override fun onResponse(
                    call: Call<ServerLoginResponse>,
                    response: Response<ServerLoginResponse>
                ) {
                    if (response.body()!!.success == true) {
                        completion(true)

                    }else{
                        completion(false)
                    }
                }

                override fun onFailure(call: Call<ServerLoginResponse>, t: Throwable) {
                    completion(false)

                }
            })

        }catch (e:Exception){
            completion(false)
        }
    }
}

 

var retrofit = RetrofitClient.getInstance()
var loginApi = retrofit.create(ILoginAPI::class.java)

위에서 만든 RetrofitClient에 create() 메서드를 통해
위의 Login 인터페이스에서 정의한 엔드 포인트(필요한 자원을 받아올 수 있는 위치)
POST 메서드와 Login 경로 (/user/login)의 구현체를 만든다.

2.7 API 호출

class LoginDataSource {

    fun login(username: String, password: String): Bool {
        try {
            LoginAPI().login(username,password){
                Log.d("결과", "login: it : $it")
                return it
            }
            return false


        } catch (e: Throwable) {
            return false
        }
    }
  
}