-
[Android] Retrofit 알아보기 (REST API/ JSON/ GSON)안드로이드 2024. 5. 1. 14:57
✏️ TIL(Today I Learned)
1. REST API
- REST는 Representational State Transfer의 약자이다.
- 웹의 장점을 최대한 활용할 수 있는 아키텍처 스타일을 의미한다.
- 월드 와이드 웹 (WWW) 자체가 REST 아키텍처를 기반으로 구성되어 있다. 자원(리소스)의 식별: 각 리소스는 고유한 URI로 식별됩니다.
1.1 REST의 핵심 원칙
- 메시지의 상태를 통한 표현: 리소스는 JSON, XML 등의 형식으로 표현된다.
- 상태가 없는(stateless) 통신: 각 요청은 서버에서 필요한 모든 정보를 포함하고 있어야 한다.
이를 통해 서버는 각 요청을 개별적으로 처리할 수 있다. - 클라이언트-서버 구조: 사용자 인터페이스와 데이터 저장소의 관심사가 분리되어 각각의 독립성이 높다.
- 캐시 처리 가능: 응답 데이터에 캐싱이 가능한지 여부를 명시하여 성능을 향상할 수 있다.
- 계층화된 시스템: 서버와 클라이언트 사이에 다양한 계층(보안, 로드 밸런싱 등)이 존재할 수 있다.
1.2 REST와 HTTP
- REST는 HTTP 프로토콜 위에서 구현되는 경우가 많다.
- 주요 HTTP 메서드:
- GET: 리소스 조회
- POST: 리소스 생성
- PUT: 리소스 수정
- DELETE: 리소스 삭제
1.3 RESTful API?
- RESTful API는 REST 원칙을 지킨 API를 말한다.
2. JSON
- JavaScript Object Notation의 축약어로 데이터를 저장하거나 전송할 때 많이 사용되는 경량의 DATA 교환 형식이다.
- JSON데이터는 하나의 NAME과 VALUE로 이루어져있다.
- NAME (데이터이름): String타입
- VALUE (값):
- 문자열 (String): 텍스트 데이터, 큰따옴표로 감싸진 유니코드 문자들의 집합
- 숫자 (Number): 정수 또는 부동 소수점
- 객체 (Object): 이름과 값의 쌍의 집합, 중괄호 {}
- 배열 (Array): 값의 순서 있는 리스트, 대괄호 []
- 불리언 (Boolean): true 또는 false
- null: 값이 없음을 나타내는 null
2.1 JSON 배열
- JSON배열은 중괄호{}가 아닌 대괄호[]로 둘러쌓아 표현한다.
- JSON배열은 , (쉼표)를 사용하여 여러 JSON 데이터를 포함할 수 있다.
- 예시:
{ "name": "John Doe", "age": 30, "isStudent": false, "addresses": [ { "type": "home", "street": "123 Main St", "city": "Anytown", "country": "Anycountry" }, { "type": "work", "street": "456 Office Blvd", "city": "Worktown", "country": "Workcountry" } ], "phoneNumber": null }
3. GSON
Gson은 Google에서 제공하는 오픈소스 라이브러리로, Java와 Kotlin에서 주로 사용된다.
JSON 데이터를 우리가 사용하는 프로그래밍 언어의 객체로 변환해야 할 때가 있다. 반대로, 객체를 JSON 형태로 변환해야 할 때도 있다. 이러한 작업을 직렬화(Serialization)와 역직렬화(Deserialization)라고 한다.
Gson 라이브러리는 이러한 작업을 매우 간단하게 해 준다.
3.1 Gson을 사용하는 이유
- 코드의 간결성:
일반적으로 JSON을 객체로, 또는 객체를 JSON으로 변환하는 작업은 복잡할 수 있다. 그러나 Gson을 사용하면 한 줄의 코드만으로 이러한 변환 작업을 수행할 수 있다. - 성능 효율성:
Gson은 내부적으로 최적화된 알고리즘을 사용하여 직렬화 및 역직렬화 작업을 빠르게 수행한다. 그렇기 때문에 대규모의 데이터나 복잡한 구조의 객체도 효과적으로 처리할 수 있다. - 광범위한 커뮤니티 지원 및 잘 정리된 문서:
Gson은 Google에서 개발되어 오랜 시간 동안 많은 개발자들에게 사용되어 왔다. 따라서 문제 해결 또는 활용 방안에 관한 다양한 정보와 예제가 인터넷상에 많다. 또한 공식 문서도 매우 잘 정리되어 있어, 필요한 정보를 쉽게 찾아볼 수 있다.
3.2 기본 사용법
- Kotlin 객체를 JSON으로 변환
val gson = Gson() val jsonString = gson.toJson(someObject)
- JSON을 Kotlin 객체로 변환
val myClassInstance: MyClass = gson.fromJson(jsonString, MyClass::class.java)
3.3 고급 사용법
- Custom Serializer/Deserializer: 특정 타입에 대해 사용자 지정 직렬화 및 역직렬화 로직을 정의
- @SerializedName 어노테이션: Kotlin 필드와 JSON 키 이름이 다를 경우 매핑
data class Person( @SerializedName("person_name") val name: String )
4. Retrofit
- Retrofit은 Square Inc. 에서 개발한 안드로이드 및 자바를 위한 타입-세이프한 HTTP 클라이언트 라이브러리이다.
- REST API의 HTTP 요청을 자바 인터페이스로 변환하는 것을 주목적으로 한다.
4.1 Retrofit의 장점
- 코드의 간결성
- 복잡한 HTTP API 요청을 쉽고 간결하게 만들 수 있다.
- 간단한 어노테이션을 통해 요청 메서드와 URL을 정의할 수 있다.
- 안정성과 확장성
- 내부적으로 OkHttp 라이브러리를 사용하여 통신, 이를 통해 안정적인 통신이 가능하다.
- 인터셉터를 사용하여 요청/응답 프로세스를 확장하거나 수정할 수 있다.
- 다양한 플러그인과 컨버터 지원
- 다양한 데이터 형식(JSON, XML 등)에 대해 데이터 변환 컨버터를 제공한다.
- RxJava, Coroutines와 같은 비동기 프로그래밍 라이브러리와 연동 가능하다.
4.2 Retrofit 시작하기
- Gradle에 Retrofit 라이브러리 추가
// build.gradle (Module: app) dependencies { implementation 'com.squareup.retrofit2:retrofit:2.x.x' implementation 'com.squareup.retrofit2:converter-gson:2.x.x' // Gson 컨버터 추가 }
- API 인터페이스 정의
interface ApiService { @GET("users/{id}") fun getUser(@Path("id") id: Int): Call<User> // User는 서버 응답으로 받아올 데이터 모델 클래스 }
- Retrofit 인스턴스 생성
val retrofit = Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .build() val apiService = retrofit.create(ApiService::class.java) // apiService 객체를 통해 정의된 API 요청 가능
4.3 응답 처리하기
- 동기식 vs 비동기식 요청
- 동기식 요청: 현재 스레드에서 실행되며, 응답이 올 때까지 다음 코드의 실행이 중단
val response: Response<User> = apiService.getUser(id).execute()
- 비동기식 요청: 콜백을 사용하여 백그라운드에서 실행되며, 응답이 오면 해당 콜백이 호출
apiService.getUser(id).enqueue(object: Callback<User> { override fun onResponse(call: Call<User>, response: Response<User>) { // 처리 } override fun onFailure(call: Call<User>, t: Throwable) { // 오류 처리 } })
- 동기식 요청: 현재 스레드에서 실행되며, 응답이 올 때까지 다음 코드의 실행이 중단
- 응답 객체 사용: Response 객체를 통해 HTTP 응답의 여러 정보에 접근할 수 있다.
if (response.isSuccessful) { val user: User? = response.body() } else { // 오류 메시지 처리 val error: String = response.errorBody()?.string() ?: "Unknown error" }
- 오류 처리: Retrofit의 onFailure 콜백은 네트워크 오류나 데이터 변환 오류 등에서 호출된다.
override fun onFailure(call: Call<User>, t: Throwable) { // 오류 메시지 표시 Log.e("API_ERROR", t.message ?: "Unknown error") }
'안드로이드' 카테고리의 다른 글
[Android] BuildConfig import 안되는 상황 해결 (Unresolved reference: BuildConfig) (0) 2024.05.01 [Android] 미세먼지 앱 (공공 데이터 API) + Retrofit (0) 2024.05.01 [Android] Google Map API 사용하기 (+ SHA 인증서 지문 얻기) (0) 2024.04.30 [Android] 데이터 저장 - Room (0) 2024.04.30 [Android] 데이터 저장 - SharedPreferences (0) 2024.04.30