Retrofit

MunkiJeon·2025년 3월 3일

일단은 Retrofit의 사전적 의미

안드로이드에서의 의미

Java 및 Android 용 type-safe* 한 REST API(POST, GET, PUT, DELETE)를 사용하여 안정적으로 HTTP 통신을 할 수 있게 해주는 라이브러리다.
(OkHttp 상위 호환 버전)

* 여기서 'type-safe'란 말 그대로 타입에 안정적이라는 뜻으로,
[어떠한 경우든 안정적으로 타입을 판별할 수 있어 그 결과를 예측할 수 있는 범위에 있게한다]라고 해석할 수 있다.

특징

  • 다른 라이브러리와는 다르게, Interface를 활용하여 요청을 보낸다.
  • 내부적으로 OkHttp 라이브러리를 사용하여 안정적인 통신이 가능하며,
    인터셉터를 사용하여 요청/응답 프로세스를 확장/수정 할 수 있습니다.
  • 복잡한 HTTP API 요청을 간결하게 만들어 주며
    간단한 어노테이션을 통해 메서드와 URL을 정의 하여 코드의 목적이 뚜렷하다.
  • ConverterFactory를 사용하여 다양한 데이터 형식(JSON, XML)에 대해
    데이터 변환 컨버터를 제공하며, RxJava, Coroutines와 같은
    비동기 프로그래밍* 라이브러리와 연동 가능합니다
  • 동기 · 비동기 처리 방식 중 선택하여 사용할 수 있다.
    (execute / enqueue)
비동기 프로그래밍 : 요청후 응답 수락 여부와 상관없이 다음 동작 가능 
= 선행된 작업을 막지 않고 시간이 오래 걸릴 작업을 동시에 수행 하여 효율성을 상승시켜준다.

사용 방법

  1. gradle 추가 (최신 버전은 Retrofit GitHub에서 확인)
        // Retrofit
        implementation ("com.squareup.retrofit2:retrofit:2.6.2")
        implementation ("com.squareup.retrofit2:converter-gson:2.6.0")
    retrofit을 사용하려면 gradle을 추가해야 한다.
    두 번째 줄에 있는 converter-gson은 응답 결과가 JSON일 때 객체로 변환해주는 놈이다.
    retrofit을 사용하기 위해서는 다음 세 가지의 클래스가 필요하다.

✔ Data class
✔ Http 작업을 정의하는 Interface
✔ Retrofit.Builder를 선언한 Object

2.AndroidManifest에 인터넷 permission 을 추가

      <?xml version="1.0" encoding="utf-8"?>
      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                package="_">

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

      <application
          android:allowBackup="false"
          android:icon="@mipmap/ic_launcher"
          android:label="@string/app_name"
          android:roundIcon="@mipmap/ic_launcher_round"
          android:supportsRtl="true"
          android:theme="@style/Theme.SelfStudy_Kotlin"
          android:usesCleartextTraffic="true"> <---- 2번
          <activity android:name=".MainActivity">
              <intent-filter>
                  <action android:name="android.intent.action.MAIN" />

                  <category android:name="android.intent.category.LAUNCHER" />
              </intent-filter>
          </activity>
      </application>

  </manifest>
  1번은 서버와 통신을 하기 위해 인터넷 권한을 얻는 거고
  2번은 http로 시작하는 사이트에 접근하기 위해서 적어준다.
  (안드로이드는 기본적으로 http 접근을 허용하지 않기 때문. 
	만약 https를 지원하는 사이트와 통신할 거면 안 적어줘도 된다)
  1. Retrofit 객체 만들어주기
    //RetrofitService.kt

    class RetrofitService {

        companion object {
            //통신할 서버 url
            private const val baseUrl = "http://12.345.678.910"

        //Retrofit 객체 초기화
            val retrofit: Retrofit = Retrofit.Builder()
                    .baseUrl(this.baseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()

            val test: TestService = retrofit.create(TestService::class.java)
        }
    }

통신할 서버 url을 'baseUrl'이라는 변수에 넣어주었으며, 이 서버 url은 Retrofit 객체를 만들 때 바로 사용된다.

addConverterFactory(GsonConverterFactory.create())는 위에서 얘기한 Json을 Gson형태로 변환해주는 요소이다.

  1. Retrofit을 통해 통신할 Interface 만들어주기
//TestService.kt

interface TestService {
    @Headers("accept: application/json", "content-type: application/json")
    @POST("/api/signup")
    fun signUp(@Body params: HashMap<String, Any>): Call<SignUpOkResponse>

    @GET("/api/signup/check")
    fun signUpCheck(
            @Query("email") email: String,
            @Query("password") password: String,
    ): Call<SignUpCheckOkResponse>

    @Multipart
    @POST("/api/file")
    fun uploadImage(
            @Part file: MultipartBody.Part
    ): Call<UploadImageOkResponse>

    @GET("/api/info/me")
    fun myInfo(@Header("access_token") accessToken: String): Call<MyInfoOkResponse>

    @GET("/api/info/other")
    fun otherUserInfo(
            @Header("access_token") accessToken: String,
            @Query("user_uid") userUid: Int
    ): Call<OtherUserInfoOkResponse>
}

위 Interface는 통신 대상이 되는 서버 url과 통신하려는 내용을 담아놓은 꾸러미라고 생각하면 된다. 해당 코드에서 알 수 있듯이 예시로는 POST(@POST Annotation), GET(@GET Annotation)를 사용하고 있다.

가장 일반적으로는 GET 방식을 많이 사용하는데, 만약 서버에서 데이터를 받아올 때 Access-Token이 필요하다면 @Header에 Access-Token을 넣고 필요한 @Query 내용을 적어 보내 원하는 데이터를 받아올 수 있다.

POST의 경우에는 서버에 데이터를 넣어주는데 사용되기 때문에, @Header로 json임을 명시해준 뒤 HashMap으로 Body를 만들어 보낸다.

@GET, @POST 옆 괄호 안에 있는 url은 서버에 의해 정해진 API url로, 서버쪽으로부터 우선적으로 확인해야한다.

만약 서버에 json이 아닌 mp4, jpg등 파일을 보내야 하는 경우 MultipartBody라는 형식으로 만들어준 뒤 서버에 보내야 정상적으로 데이터가 전송될 수 있다.

위 예시는 회원가입(signUP)과 로그인을 위한 확인(signUpCheck), 내 정보 확인(myInfo), 타 유저 정보 확인(otherUserInfo), 이미지 업로드(uploadImage) 내용이다.

각 function 끝에 있는 Call은 서버에 요청 후 되돌아오는 대답을 받아주기 위한 요소로, 바로 밑에 추가로 얘기하겠다.

  1. 응답받은 내용을 담을 그릇 DTO 만들기
    위에서 Call 괄호 안에 있는 SignUpCheckOkResponse와 같이 응답받은 데이터를 저장해놓는 객체를 DTO 객체라고 한다. 다른 로직을 갖지 않는 순수한 데이터 객체이기 때문에 Kotlin에서는 data class로 작성한다.
// SignUpCheckOkResponse.kt
data class SignUpCheckOkResponse(
        val uid: Int,
        val is_deleted: Int,
        val created_time: String,
        val updated_time: String,
        val signup_type: String,
        val social_id: String,
        val nickname: String,
        val about: String,
        val gender: String,
        val interests: Int,
        val age: Int,
        val address: String,
        val filename: String,
        val access_token: String
): SignUpCheckResponse

// SignUpCheckErrorResponse.kt
data class SignUpCheckErrorResponse(
        val code: Int,
        val message: String,
        val method: String,
        val url: String
) : SignUpCheckResponse
  1. MethodCallback, ErrorUtils 만들기
  2. 간편하게 사용하기
    https://velog.io/@cmjh951330/restrofit2-method

참고 자료

https://salix97.tistory.com/204
https://oscarstory.tistory.com/71
https://todaycode.tistory.com/38
https://velog.io/@cmjh951330/restrofit2-method
https://velog.io/@jeongminji4490/Android-Retrofit

profile
공장자동화와 웹 개발을 핥아 먹다 앱 개발로 전향한 개발자의 키보드의 낡은 키캡⛑️

0개의 댓글