ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 웹서버의 데이터를 받아오자! Retrofit2
    Android/Network 2019. 6. 17. 22:58

    이번시간은 Retrofit2! 어디선가 들어보았다...

    MVVM할때 많은 예제들이 Retrofit2을 사용한 것을 보았다.

     

    Retrofit2는 REST통신을 위한 클라이언트 라이브러리다!

    기존에는 아파치를 사용하였는데 왜 이걸 사용해야 하는지는 아래 사진 한장으로 설명

    Apache HTTP 클라이언트 사망선고를 맞아서 그에 맞는 Retrofit으로 갈아타야 된다.

    HttpURLConnection은 코드량이 어마무시하게 늘어난다.

    그래서 Retrofit 이라는 걸 사용하는데 ( 물론 Volley도 있다 )

    아래에서 한번 다루어 보도록 하겠당

     

    사전에 알아보는 REST ( 정리가 매우 잘 되어 있습니다 )

    https://meetup.toast.com/posts/92

     

    REST API 제대로 알고 사용하기 : TOAST Meetup

    REST API 제대로 알고 사용하기

    meetup.toast.com


    gradle dependency

     

    // retrofit2
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'

    // okHttp3
    implementation 'com.squareup.okhttp3:okhttp:3.10.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.4.2'


    다시 한번 정의 하자면

    Retrofit = REST API를 구현한 상태 간단하게 GET POOSET PUT DELETED를 전달시 서

    버에서 처리후 xml, json, text, rss 등으로 응답을 받음

     

    그러면 어떻게 사용하냐면?
    Retrofit은 interface을 정의하고,  이 interface class을 Retrofit에 초기화를 하는 과정을 거치면, 

    HTTP 통신을 할 준비가 완료된다.


    아래코드는 GitHub에서 제공하는 API 중 user와 관련된 부분을 불러오는 부분이다.
    interface Service로 정의하고, @GET annotation을 추가하고 다음을 정의해보자. 

    interface GithubService {
        @GET("users/{owner}/repos")
        fun getRepos(@Path("owner") owner: String): Call<List<GithubRepo>>
    }

    GET은 데이터를 가져오는 동사!

    Path는 Get에 있는 { } 에 해당 파라미터를 넣는다는 어노테이션이다.

     

    @Path말고 @Query도 있다 이름과 같이 ? 쿼리를 쓸때 사용한다.

     

    간단하게 깃허브에서 해당 유저의 레포지토리 목록을 가져오는 것이 완료되었다.


    다음과 같이 Retrofit을 초기화하자. 간단하게 baseUrl을 적어서 초기화할 수 있다. 
    Retrofit을 생성하면, 위에서 생성한 GithubClient 을 retrofit을 통해 생성한다.

    class GithubClient {
    
        companion object {
            val BASE_URL = "https://api.github.com"
        }
    
        fun getService(): GithubService {
            return Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(GithubService::class.java)
        }
    }

    baseUrl : 기본적인 Url을 말한다

    ConverterFactory : 서버에서 가져오는 데이터를 어떻게 파싱할지 선택하면 된다.

    ( 기본적으로 Json으로 많이 데이터를 가져오고 github또한 Json으로 반환된다. )


    [ 데이터 구조 ]

    data class GithubRepo(
        val name: String,
        val private: String,
        val owner : Owner
    )
    
    data class Owner(
        val login: String,
        val url: String
    )

    이후부터는 service을 통해서 Retrofit을 사용하면 된다.

    val github = GithubClient()

     

    이제 실제로 값을 가져와 보도록 하자

    github.getService().getRepos("You-Kkomi").enqueue(object : Callback<List<GithubRepo>> {
    
        override fun onFailure(call: Call<List<GithubRepo>>, t: Throwable) {
            Log.e("dundun",t.toString())
        }
    
        override fun onResponse(call: Call<List<GithubRepo>>, response: Response<List<GithubRepo>>) {
            if (!response.isSuccessful) {
                return
            }
            response.body()!!.forEach { repo -> Log.d("donghun-retrofit", repo.toString()) }
        }
    })

    enqueue메서드의 Callback 함수를 구현해주자!

     

    깃허브 섭서비스에서 본인의 레포지토리를 반환한다.

    데이터가 성공적으로 들어온다면 Log를 찍고

    아닐 경우 해당 오류를 로그로 찍는다.

     

    [ 결과 ]

    GithubRepo(
        name=Refactoring-MVVM-using-AAC, 
        private=false, 
        owner=
            Owner(
                login=You-Kkomi, 
                url=https://api.github.com/users/You-Kkomi
            )
    )

    값은 제대로 들어오는데 통신은 어찌 되는지 궁금하다면 아래와 같이 코드를 변경해보자

    private fun createOkHttpClient(): OkHttpClient {
        val builder = OkHttpClient.Builder()
        val interceptor = HttpLoggingInterceptor()
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        builder.addInterceptor(interceptor)
        return builder.build()
    }
    
    fun getService(): GithubService {
        return Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(createOkHttpClient())
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(GithubService::class.java)
    }

    [ 로그 ]

     D/OkHttp: <-- 200 OK https://api.github.com/users/You-Kkomi/repos (1290ms) 
     D/OkHttp: Date: Mon, 17 Jun 2019 13:18:26 GMT 
     D/OkHttp: Content-Type: application/json; charset=utf-8 
     D/OkHttp: Transfer-Encoding: chunked 
     D/OkHttp: Server: GitHub.com 
     D/OkHttp: Status: 200 OK 
     D/OkHttp: X-RateLimit-Limit: 60 
     D/OkHttp: X-RateLimit-Remaining: 59 
     D/OkHttp: X-RateLimit-Reset: 1560781106 
     D/OkHttp: Cache-Control: public, max-age=60, s-maxage=60 
     D/OkHttp: Vary: Accept 
     D/OkHttp: ETag: W/"dd3e2395e06be4972850c8131018c94e" 
     D/OkHttp: X-GitHub-Media-Type: github.v3; format=json 
     D/OkHttp: Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP,
     X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes,
     X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type 
     D/OkHttp: Access-Control-Allow-Origin: * 
     D/OkHttp: Strict-Transport-Security: max-age=31536000; includeSubdomains; preload 
     D/OkHttp: X-Frame-Options: deny 
     D/OkHttp: X-Content-Type-Options: nosniff 
     D/OkHttp: X-XSS-Protection: 1; mode=block 
     D/OkHttp: Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin 
     D/OkHttp: Content-Security-Policy: default-src 'none' 
     D/OkHttp: Vary: Accept-Encoding 
     D/OkHttp: X-GitHub-Request-Id: A7D4:17B2:1882ED5:1D9F714:5D079321 
     D/OkHttp: // repo json 
     D/OkHttp: <-- END HTTP (25899-byte body)

    다음 강좌는 Rx를 사용하여 서버에 데이터 요청시 Call이 아닌 Single로 받아오는 법을 알아보자

    댓글

Designed by Tistory.