이시안 개발 블로그

외부 API를 이용해서 JSON 데이터 다뤄보기 본문

☕Java

외부 API를 이용해서 JSON 데이터 다뤄보기

ICAN 2022. 2. 9. 15:36

💻 문제

API는 Application Programming Interface의 약자로 다른 프로그램끼리의 데이터 통신은 API를 통해서 하게 됩니다.

저는 이번에 업비트가 제공하는 QUOTATION API를 사용하여 데이터를 가공해보겠습니다.

 

JSON은 Javascript의 객체와 같이 키 : 값의 쌍으로 이루어진 데이터입니다.

예전에는 XML 형식의 데이터를 주고받았지만 현재는 JSON 포맷을 기본으로 사용합니다.

 

📚 과정

1. 라이브러리 설치

https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind

https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp

Jackson 라이브러리는 Java 객체와 JSON/XML/YAML 등등의 데이터 포맷끼리의 변환을 도와주는 라이브러리입니다.

Jackson 이외에도 Gson, SimpleJson 등등 유사한 기능을 하는 라이브러리가 있습니다.

 

OkHttp 라이브러리는 HTTP 통신을 간편하게 구현하도록 도와주는 라이브러리입니다.

코드 몇 줄로 HTTP 요청을 보내고 응답을 받을 수 있습니다.

 

Gradle 라이브러리 의존성 설정

라이브러리는 Gradle이나 Maven을 통해 쉽게 적용해서 사용할 수 있습니다.

 

2. 테스트 코드 작성

요청과 응답 확인 테스트
@Test
void 데이터를_불러오는지_확인한다() throws IOException {

    // given
    OkHttpClient client = new OkHttpClient();
    
    Request request = new Request.Builder()
            .url("https://api.upbit.com/v1/market/all?isDetails=false")
            .get()
            .addHeader("Accept", "application/json; charset=utf-8")
            .build();

    // when
    Response response = client.newCall(request).execute();

    // then
    assertNotNull(response.body());
}

데이터를 제대로 불러오는지 확인하기 위한 테스트 코드입니다.

  1. HTTP 통신을 위한 OkHttpClient를 생성합니다.
  2. Request.Builder()를 사용해 URL과 헤더 정보를 작성하여 Request 객체를 생성합니다.
  3. 생성한 Request 객체를 OkHttpClient를 통해 데이터를 요청하면 Response 객체로 반환됩니다.
  4. 반환된 Response의 body를 확인합니다.

테스트 결과

테스트는 무소식이 희소식입니다.

다음으로는 JSON 데이터를 가공하는 테스트 코드를 확인해보겠습니다.

비트코인 JSON 데이터
[
  {
    "market": "KRW-BTC",
    "trade_date": "20220209",
    "trade_time": "061357",
    "trade_date_kst": "20220209",
    "trade_time_kst": "151357",
    "trade_timestamp": 1644387237000,
    "opening_price": 53651000,
    "high_price": 53921000,
    "low_price": 52560000,
    "trade_price": 53122000,
    "prev_closing_price": 53651000,
    "change": "FALL",
    "change_price": 529000,
    "change_rate": 0.0098600212,
    "signed_change_price": -529000,
    "signed_change_rate": -0.0098600212,
    "trade_volume": 0.0079,
    "acc_trade_price": 81267506845.6777,
    "acc_trade_price_24h": 536782960319.56854,
    "acc_trade_volume": 1529.00438745,
    "acc_trade_volume_24h": 10045.91217261,
    "highest_52_week_price": 82700000,
    "highest_52_week_date": "2021-11-09",
    "lowest_52_week_price": 33900000,
    "lowest_52_week_date": "2021-06-22",
    "timestamp": 1644387237853
  }
]

비트코인의 JSON 데이터는 위와 같이 리스트를 의미하는 대괄호 안에 중괄호로 감싸진 키와 값 쌍으로 이루어져 있습니다. 해당 데이터를 받기 위한 CoinDto를 만들어보겠습니다.

 

CurrentCoinDto 클래스
public class CurrentCoinDto {
    private String market;
    private Double opening_price;
    private Double high_price;
    private Double low_price;
    private String acc_trade_price;
    private String acc_trade_price_24h;

    public String getMarket() {
        return market;
    }

    public Double getOpening_price() {
        return opening_price;
    }

    public Double getHigh_price() {
        return high_price;
    }

    public Double getLow_price() {
        return low_price;
    }

    public String getAcc_trade_price() {
        return acc_trade_price;
    }

    public String getAcc_trade_price_24h() {
        return acc_trade_price_24h;
    }

    public CurrentCoinDto(Map<String, String> map) {
        this.market = map.get("market");
        this.opening_price = Double.valueOf(map.get("opening_price"));
        this.high_price = Double.valueOf(map.get("high_price"));
        this.low_price = Double.valueOf(map.get("low_price"));
        this.acc_trade_price = map.get("acc_trade_price");
        this.acc_trade_price_24h = map.get("acc_trade_price_24h");
    }
}

제가 필요한 정보는 마켓 코드와 시가, 고가, 저가와 거래대금이며 그에 해당하는 멤버를 만들어두고 생성자를 통해 데이터를 입력하도록 했습니다.

 

코인의 데이터를 불러와서 가공하기
@Test
void 비트코인_데이터_불러오기() throws IOException {

    // given
    OkHttpClient client = new OkHttpClient();
    
    Request request = new Request.Builder()
            .url("https://api.upbit.com/v1/ticker?markets=KRW-BTC")
            .get()
            .addHeader("Accept", "application/json")
            .build();

    // when
    Response response = client.newCall(request).execute();

    String str = response.body().string();
    ObjectMapper mapper = new ObjectMapper();

    List<Map<String, String>> list = mapper.readValue(str, new TypeReference<List<Map<String, String>>>() {
    });

    Map<String, String> map = list.get(0);

    CurrentCoinDto coinDto = new CurrentCoinDto(map);

    // then
    assertEquals(coinDto.getMarket(), "KRW-BTC");
}

이제는 비트코인의 데이터를 받아서 가공해보겠습니다.

 

  1. 아까와 같이 요청을 통해 응답 객체를 반환받습니다.
  2. 응답 객체의 body에는 요청한 데이터가 들어있으며 문자열로 받을 수 있습니다.
  3. Java 객체로 변환하도록 Jackson 라이브러리가 제공하는 ObjectMapper를 생성합니다.
  4. mapper.readValue 메서드를 사용해서 JSON 데이터를 양식에 맞게 변환하여 Java 객체로 만들 수 있습니다. 지금의 경우에는 Map 형태의 데이터를 List가 담고 있는 모습으로 List<Map<String, String>> 형태로 반환받았습니다.
  5. List의 Map 컬렉션의 데이터로 CoinDto를 생성합니다.
  6. 비트코인의 마켓 코드와 일치하는 지 확인합니다.

☄️ 결과

테스트 결과

통신도 잘 됐고 데이터도 제대로 불러왔는지 테스트를 통과했습니다.

'☕Java' 카테고리의 다른 글

멀티 스레드의 임계 영역  (1) 2022.01.19
BigDecimal로 간단한 사칙연산 계산기 만들기  (0) 2022.01.10
Comments