(구)Android/Kotlin

[Kotlin] REST API & Retrofit

2022. 10. 25. 23:47
목차
  1. 📌 Intro
  2. 📌 Rest?
  3. REST 정의
  4. REST 개념
  5. REST 구성요소
  6. 📌 REST API
  7. 📌 Retrofit2?
  8. 📌 Retrofit2 사용 방법
  9. 📌 참고

📌 Intro

Retrofit은 서버와 통신할 때 사용하는 라이브러리이다. RestAPI는 무엇이고, Retrofit을 사용하기 위해서는 어떻게 해야하는지 알아보도록 하자.



📌 Rest?

REST 정의

REST는 Representational State Transfer의 약자로 자원을 이름으로 구분하여 해당 자원의 상태를 주고 받는 모든것을 의미한다.
즉, 자원의 표현에 의한 상태 전달을 뜻한다.

  • 자원 : 해당 소프트웨어가 관리하는 모든 것(문서, 그림, 데이터...)
  • 표현 : 자원을 표현하기 위한 이름 (DB의 학생 정보가 자원이면, 'students'를 자원의 표현으로 정함)
  • 상태 전달 : 데이터가 요청되는 시점에 자원의 상태를 전달한다. (JSON 혹은 XML을 통해 데이터를 주고 받는 것이 일반적)

 

REST는 기본적으로 웹의 기존 기술과 HTTP 프로토콜을 그대로 활용하기 때문에, 웹의 장점을 최대한 활용할 수 있는 아키텍처 스타일이다.
REST는 네트워크 상에서 Client와 Server 사이의 통신 방식 중 하나다.



REST 개념

어떤 자원에 대해 CRUD연산을 수행하기 위해 URI(Resource)로 GET, POST 등의 방식(Method)을 사용하여 요청을 보내며, 요청을 위한 자원은 특정한 형태(Representation of Resource)로 표현된다.

 

** CRUD Operation CRUD는 대부분의 컴퓨터 소프트웨어가 가지는 기본적인 데이터 처리 기능인 Create(생성), Read(읽기), Update(갱신), Delete(삭제)를 묶어서 일컫는 말로 REST에서의 CRUD Operation 동작 예시는 다음과 같다.

Create : 데이터 생성(POST)

Read : 데이터 조회(GET)

Update : 데이터 수정(PUT, PATCH)

Delete : 데이터 삭제(DELETE)



REST 구성요소

  1. 자원(Resource) : URI 모든 자원에는 고유한 ID가 존재하고, 이 자원은 Server에 존재한다.
    자원을 구별하는 ID는 HTTP URI다.
    Client는 URI를 이용해 자원을 지정하고 해당 자원의 상태에 대한 조작을 Server에 요청한다.
  2. 행위(Verb) : Method HTTP 프로토콜의 Method를 사용한다.
    HTTP 프로토콜은 GET, POST, PUT, DELETE, PATCH의 Method를 제공한다.
  3. 표현(Representation of Resource) Client와 Server가 주고받는 데이터의 형태로 JSON, XML 등이 있다.



📌 REST API

REST API란 앞서 살펴본 REST의 특징을 기반으로 서비스 API를 구현한 것을 말한다. 최근 구글맵, 카카오맵과 같은 OpenAPI를 제공하는 기업은 대부분 REST API를 제공한다.



📌 Retrofit2?

Retrofit은 안드로이드, 자바, 코틀린에서 쉽게 REST API와 통신할 수 있도록 도와주는 라이브러리다. 동일 Squareup사의 OkHttp 라이브러리의 상위 구현체다.



📌 Retrofit2 사용 방법

Grdle 의존성 추가

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

현재 글을 작성할 때 Retrofit의 최신 버전은 2.9.0버전이다. 만약 최신 버전이 아니더라도 마우스를 올려놓으면 최신 버전을 알려주기 때문에 크게 상관 없을 것이다.



인터넷 사용 권한 추가

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

AnroidManifest.xml파일에 위 코드를 추가하여 인터넷 권한을 부여하도록 하자.



데이터 클래스 생성

{
	"user" : [
		{
			"user_id": 1234,
			"name" : "AAA",
			"phone" : "010-1234-5678"
		},
		{
			"user_id": 1235,
			"name" : "BBB",
			"phone" : "010-9876-5432"
		},
		{
			"user_id": 1236,
			"name" : "CCC",
			"phone" : "010-5678-1234"
		},
		{
			"user_id": 1237,
			"name" : "DDD",
			"phone" : "010-1234-4321"
		}
	]
}

 

위의 JSON 객체는 특정 객체를 배열로 담은 변수를 가진 객체다. 따라서 코틀린에서는 다음과 같이 표현할 수 있다.

data class exampleResponse(
	val student: List<User>
) 

data class User(
	val userId: Int,
	val name: String,
	val phone: String
)

JSON에서는 변수를 Snake Case로 표기한다. 하지만 Java와 Kotlin에서는 Camel Case로 변수를 표기한다.
Retrofit 통신을 할 때 서버에 정의된 변수명과 클라이언트에 정의된 변수명이 같으면 스스로 대응시켜 처리해준다. 따라서 id와 phone은 알아서 대응시켜서 처리가 되겠지만 user_id의 경우 userId와 같지 않기 때문에 대응되지 않고 약간의 수정이 필요하다.

 

SerializedName Anonotation을 사용하여 userId를 user_id와 매핑시켜줄 수 있다. (꼭 이름을 변경하지 않더라도 @SerializedName를 써주는게 좋다고 한다.)



Interface 정의

인터페이스를 정의하기 전에 GET과 함께 사용되는 @Path 와 @Query가 있는데 아래 예시 코드에 대한 이해도를 높이기 위해 아주 간단하게 정리해두고 가도록 하자.

  • @Path : 동적인 URI를 가능하게 해주는 Annotation
  • @Query : URI 파라미터를 추가하여 보낼 수 있도록 해주는 Annotation

GET방식은 기본적인 @GET방식과 동적 URI @GET 방식이 있다.

  • 기본적인 @GET(URI) 방식
    URI는 자원의 실제 위치를 의미하고, Resource PATH, EndPoint라고도 불린다.
    전체 URI : http://krrongTistory.com/user
    URL(프로토콜 + URL) : http://krrongTistory.com
    URI(Resource PATH) : user
interface ExampleInterface {
	@GET("user")
	fun getUser(@Query("user_id") userId: Int,
			@Qeury("phone") phone: String): Call<ExampleResponse>
}
// 위와 같은 경우 최종 URI는 다음과 같다. http://krrongTistory.com/user?userId=10&phone=01012341234

 

  • 동적 URI @GET 방식 URL(프로토콜 + URL) : http://krrongTistory.com/
    URI(Resource PATH) : user/{id}
    @Path는 @GET 내부 URI에서 중괄호로 감싸진 변수에 매핑하도록 해주는 역할을 한다. 이 때 중괄호 안의 변수명과 @Path안에 있는 변수명을 일치시켜줘야 한다.
interface ExampleInterface {
	@GET("user/{id}")
	fun getUser(@Path("id") id: Int,
				@Query("userId") userId: Int
				@Query("phone") phone: String): Call<ExampleResponse>
}

getUser 메서드는 userId와 phone을 파라미터로 받고 Call 객체를 리턴하는 함수다.
통신 처리를 할 때는 비동기 처리를 해야 하는데 Retrofit2에서 제공하는 Call 객체를 사용하면 Callback을 구현할 수 있다.



Retrofit 객체 생성

서버와 통신하기 위해 Retrofit 객체가 필요하다.
Rtrofit.Build() 메서드를 통해 Retrofit 객체를 생성할 수 있다.
서버통신은 안드로이드 어디서나 사용될 수 있기 때문에 싱글톤 패턴을 이용해서 Retrofit 객체를 생성해주면 좋다.

object RetrofitClass {
    private val retrofit = Retrofit.Builder()
			.baseUrl(BASE_URL)
			.addConverterFactory(GsonConverterFactory.create())
			.build()
}

object는 싱글톤을 적용한 클래스를 만들 수 있다고 생각하면 된다.
싱글톤이란 앱을 실행할 때 한번만 생성된다는 의미이고 이는 곧 불필요하게 메모리가 사용되는 것을 막을 수 있다.
위처럼 Retrofit 객체를 만들어주면 통신이 필요할 때마다 생성할 필요없이 가져다 사용하면 된다. BASE_URL에는 서버 ip를 넣어주면 된다.

GsonConverterFactory 보통 서버에 JSON 객체를 통해 요청이나 응답을 주고 받는다. 이 때, 안드로이드에서는 JSON 객체를 바로 사용할 수 없기 때문에 JSON Object → JAVA Object, 혹은 그 반대로의 변환 과정이 필요하다. 이를 위해 build.gradle에 converter-gson를 추가한 것이고, Retrofit을 만들어줄 때 GsonConverterFactory를 converter로 넣어 주는 것이다.



이제 생성한 Retrofit 객체가 위 interface를 구현하면 Retrofit 객체를 통해 API를 사용할 수 있다.

object RetrofitClass {
    private val retrofit = Retrofit.Builder()
			.baseUrl(BASE_URL)
			.addConverterFactory(GsonConverterFactory.create())
			.build()
		
		private val _api = retrofit.create(ExampleInterface::class.java)
		val api
			get() = api
}

 

통신

val userId = 1234
val phone = 01012345678
val callGetUser = RetrofitClass.api.getUser(userId, phone)

callGetUser.enqueue(object : Callback<ExampleResponse> {
	override fun onResponse(call: Call<ExampleResponse>, response: Response<ExampleResponse>) {
		if(response.isSuccessful()) { // <--> response.code == 200
			// 성공 처리
			
			//ex)
			Toast.makeText(this, "${response.body().user.size}", Toast.LENGTH_SHORT).show()
		} else { // code == 400
			// 실패 처리
		}
	}
	
	override fun onFailure() { // code == 500
		// 실패 처리
	}
}

Callback 객체를 callGetUser에 넣어 응답이 돌아오면 적절히 처리할 수 있게 해준다.
Callback 객체를 익명 인터페이스로 만든 다음 onResponse와 onFailure 메서드를 구현해준다.
서버와 통신이 성공하면 onReponse를 호출하고, 실패하면 onFairure를 호출한다.
응답 코드가 200이 아닌 400이여도 onResponse를 호출하기 때문에 if(response.isSuccessful())을 이용해서 성공 처리를 해준다.



📌 참고

[1] http://devflow.github.io/retrofit-kr/
[2] https://velog.io/@sasy0113/Android-Kotlin-Retrofit2
[3] https://dev-coco.tistory.com/97
[4] https://gwi02379.tistory.com/3
[5] https://jaejong.tistory.com/38

  1. 📌 Intro
  2. 📌 Rest?
  3. REST 정의
  4. REST 개념
  5. REST 구성요소
  6. 📌 REST API
  7. 📌 Retrofit2?
  8. 📌 Retrofit2 사용 방법
  9. 📌 참고
'(구)Android/Kotlin' 카테고리의 다른 글
  • [Kotlin] Retrofit POST
  • [Kotlin] Fragment에서 권한 요청하기
  • [Kotlin] 런타임 권한 요청(Permission)
  • [Kotlin] 뷰바인딩(ViewBinding 이해하기
Krrong
Krrong
Krrong
노는게 제일 좋아
Krrong
전체
오늘
어제
  • 분류 전체보기 (302)
    • Android (2)
    • 우아한테크코스 (46)
      • Level 5 ~ (3)
      • Level 4 (8)
      • Level 3 | Project (8)
      • Level 2 (12)
      • Level 1 | Mission (4)
      • Level 1 | 정리 (5)
      • 프리코스 (6)
    • 스터디 (1)
      • 기술면접 질문 정리 (1)
      • Kotlin in Action (0)
    • AI⦁딥러닝 (5)
    • Jetson Xavier (9)
    • Computer Vision (6)
      • GoProCam (2)
      • OpenCV (4)
    • (구)Android (36)
      • 이론 (4)
      • Java (20)
      • Kotlin (12)
    • C++ Programming (161)
      • 백준 (146)
      • 알고리즘 (13)
      • STL 사용법 (2)
    • Git (5)
    • Spring (5)
    • 활동 (3)
    • 기타 (3)
    • 🇩🇪 (13)
      • 일상 (13)
    • ✈️ 여행 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 글쓰기
  • 티스토리홈

공지사항

인기 글

태그

  • 퀵소트
  • 알고리즘
  • 정렬알고리즘

최근 댓글

최근 글

hELLO · Designed By 정상우.
Krrong
[Kotlin] REST API & Retrofit
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.