Simple&Natural
[Android] Retrofit + Moshi 를 이용한 Json 데이터 받아오기 본문
사용할 API
업비트에서 제공하는 호가정보 조회를 이용하였습니다.
Json 데이터의 구조는 다음과 같습니다.
[
{
"market":"KRW-BTT",
"timestamp":1601978350558,
"total_ask_size":1661426721.82969615,
"total_bid_size":3193649917.22018229,
"orderbook_units":[
{
"ask_price":0.38,
"bid_price":0.37,
"ask_size":52579173.39995168,
"bid_size":326923944.36043933
},
{
"ask_price":0.39,
"bid_price":0.36,
"ask_size":110921173.94925065,
"bid_size":284027857.96811941
},
{
"ask_price":0.4,
"bid_price":0.35,
"ask_size":252161358.85707794,
"bid_size":354853817.36656141
},
{
"ask_price":0.41,
"bid_price":0.34,
"ask_size":155806703.9382614,
"bid_size":371655493.45608652
},
{
"ask_price":0.42,
"bid_price":0.33,
"ask_size":105958189.91011731,
"bid_size":388027941.04106783
},
{
"ask_price":0.43,
"bid_price":0.32,
"ask_size":71299374.27006697,
"bid_size":164048625.24920658
},
{
"ask_price":0.44,
"bid_price":0.31,
"ask_size":152446903.54070296,
"bid_size":44368887.34742182
},
{
"ask_price":0.45,
"bid_price":0.3,
"ask_size":133967225.09835682,
"bid_size":1061505262.56718297
},
{
"ask_price":0.46,
"bid_price":0.29,
"ask_size":63563682.77290502,
"bid_size":68262164.26816135
},
{
"ask_price":0.47,
"bid_price":0.28,
"ask_size":74083950.52470174,
"bid_size":40849391.67084302
},
{
"ask_price":0.48,
"bid_price":0.27,
"ask_size":132084919.68391634,
"bid_size":11608175.08244754
},
{
"ask_price":0.49,
"bid_price":0.26,
"ask_size":73031784.58417466,
"bid_size":22246361.36929818
},
{
"ask_price":0.5,
"bid_price":0.25,
"ask_size":92803453.00606038,
"bid_size":34513290.52543726
},
{
"ask_price":0.51,
"bid_price":0.24,
"ask_size":98015540.52845204,
"bid_size":17739616.83048444
},
{
"ask_price":0.52,
"bid_price":0.23,
"ask_size":92703287.76570024,
"bid_size":3019088.11742463
}
]
}
]
Json 구조 잡기
Json데이터를 파싱하기 위해서는 전체적인 구조를 잡아야 합니다.
우선 전체 데이터를 OrderBook으로, orderbook_units의 세부 주문 내역들은 Order로 설정 하였습니다.
UpbitOrderBook.kt
앞서 잡은 구조를 바탕으로 데이터의 모델 클래스들을 만들어줍니다.
data class OrderBook(
val market: String,
val timestamp: String,
@Json(name = "total_ask_size") val totalAskSize: String,
@Json(name = "total_bid_size") val totalBidSize: String,
@Json(name = "orderbook_units") val orderbookUnits: List<Order>
)
data class Order(
@Json(name = "ask_price") val askPrice: String,
@Json(name = "bid_price") val bidPrice: String,
@Json(name = "ask_size") val askSize: String,
@Json(name = "bid_size") val bidSize: String
)
Json데이터의 키값이 클래스의 변수명과 같은 경우 자동으로 매핑이 되지만 그렇지 않은 경우에는 Json annotation을 사용해
실제 데이터와 클래스의 키값을 매핑해주어야 합니다.
여기서 중요한 것은 Json 데이터의 값이 JsonArray로 되어있을 경우 반환값을 반드시 List로 설정해주어야 합니다.
OrderBookApi.kt
API 호출에 필요한 각종 인터페이스와 함수 등을 작성합니다.
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
private val BASE_URL = "https://api.upbit.com/v1/"
private val retrofit = Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.baseUrl(BASE_URL)
.build()
object OrderBookApi {
val retrofitService: OrderBookApiService by lazy {
retrofit.create(OrderBookApiService::class.java)
}
}
interface OrderBookApiService {
@GET("orderbook")
suspend fun orderbookRequest(
@Query("markets") id: String? = "krw-btc"
): List<OrderBook>
}
Query annotation을 이용해 필요한 파라미터를 함께 보내줍니다.
Default 값은 krw-btc로 설정되어 있습니다.
여기서도 주의해야 할 것은 전체 Json이 JsonArray형태로 둘러싸여 있기 때문에 OrderBookApiService의 orderbookRequest의 리턴값을 List로 설정해주어야 한다는 것입니다.
JsonUnitTest.class
UnitTest 클래스에서 호출해보면 정상적으로 결과가 잘 나오는 것을 확인하실 수 있습니다.
@Test
fun orderBookTest() {
val result = runBlocking {
OrderBookApi.retrofitService.orderbookRequest("krw-btt")
}
Log.d("MyUpbit", "Json: ${result}")
}
// 결과
// Json: [OrderBook(market=KRW-BTT, timestamp=1602031450946, totalAskSize=1610363853.09253375, totalBidSize=3029150425.48084788, orderbookUnits=[Order(askPrice=0.37, bidPrice=0.36, askSize=83228294.41308809, bidSize=306130993.3192356), Order(askPrice=0.38, bidPrice=0.35, askSize=85324949.35571855, bidSize=445303381.25004825), Order(askPrice=0.39, bidPrice=0.34, askSize=86660978.71522919, bidSize=382035088.11419864), Order(askPrice=0.4, bidPrice=0.33, askSize=157991291.25914622, bidSize=391388536.33039288), Order(askPrice=0.41, bidPrice=0.32, askSize=163710287.22101781, bidSize=169211125.24920658), Order(askPrice=0.42, bidPrice=0.31, askSize=160375624.6410458, bidSize=77926433.65151167), Order(askPrice=0.43, bidPrice=0.3, askSize=79015942.13268902, bidSize=1062659066.64597688), Order(askPrice=0.44, bidPrice=0.29, askSize=149945551.54070296, bidSize=64972478.07677426), Order(askPrice=0.45, bidPrice=0.28, askSize=126514226.94351202, bidSize=40992248.81370015), Order(askPrice=0.46, bidPrice=0.27, askSize=63563682.77290502, bidSize=11830397.30466974), Order(askPrice=0.47, bidPrice=0.26, askSize=74083950.52470174, bidSize=22477130.60006738), Order(askPrice=0.48, bidPrice=0.25, askSize=115841966.74178276, bidSize=34713290.52543726), Order(askPrice=0.49, bidPrice=0.24, askSize=73058811.61120168, bidSize=15728522.37771081), Order(askPrice=0.5, bidPrice=0.23, askSize=92801100.24829211, bidSize=3323435.94351157), Order(askPrice=0.51, bidPrice=0.22, askSize=98247194.97150078, bidSize=458297.27840621)])]
마치며
이전까지는 Json 파싱을 위해 주로 Gson을 사용해왔는데 이번에는 한번 Moshi를 사용해 보았습니다.
구글 샘플 프로젝트에서도 대부분 Moshi를 사용하고 있고 Retrofit을 쓰는 경우 Moshi 를 사용하는 것이 최적화나 지원 부분에서 좀 더 유리한 측면이 있다고 합니다. 기존에 Gson을 사용하셨던 분들은 Moshi를 한번 사용해보시는 것도 좋을 것 같습니다.
'안드로이드(Android) > 기타' 카테고리의 다른 글
[Android] 애드몹(Admob) 연동하기 (0) | 2020.10.08 |
---|---|
[Android] Retrofit Field 사용 시 Encoding 문제 (0) | 2020.10.07 |
BottomNavigationView + Hiding On Scroll (0) | 2020.09.28 |
안드로이드에서 Coroutine과 Retrofit 및 Room을 함께 사용 시 주의사항 (1) | 2020.08.25 |
안드로이드 스튜디오 기본 파일 입출력 경로 (0) | 2020.08.21 |