웹서버의 데이터를 받아오자! Retrofit2
이번시간은 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로 받아오는 법을 알아보자