본문 바로가기

백-엔드/노드제이에스(NodeJS)

[Node.js] 업비트 API Request 처리 API


저는 현재 TypeScript와 React Native로 암호화폐 지갑을 개발하고 있으며, 이번 글에서는 지갑 앱에 업비트의 Public API 를 적용하는 과정에서 경험한 스토리를 써보려 합니다.


다음은 UPbit의 공식 API 문서에서 가져온 업비트에서 거래 가능한 마켓 목록을 가져오는 JavaScript와 Node.js API입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//JavaScript API
var data = JSON.stringify(false);
 
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
 
xhr.addEventListener("readystatechange"function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});
 
xhr.open("GET""https://api.upbit.com/v1/market/all");
 
xhr.send(data);
cs


1
2
3
4
5
6
7
8
9
10
// Node.js API
var request = require("request");
 
var options = { method: 'GET', url: 'https://api.upbit.com/v1/market/all' };
 
request(options, function (error, response, body) {
  if (error) throw new Error(error);
 
  console.log(body);
});
cs


request 를 보내기 위해 JavaScript API에서는 XMLHttpRequest를 사용했고, Node API에서는 request를 사용한 것을 확인할 수 있습니다.


이 둘의 차이는 무엇일까요?



XMLHttpReuest


오랜 세월 동안 사람들은 XMLHttpRequest (XHR) 를 이용해서 JavaScript 로 비동기 리퀘스트를 처리해왔습니다. 매우 유용했지만, XHR 는 그렇게 좋은 API 는 아니었습니다. 입력, 출력, 그리고 상태(state) 모두를 하나의 객체로 관리해야 했으며, 상태(state) 는 이벤트를 통해 추적해야 했습니다.


다음은 제가 UPbit의 JavaScript API를 제가 개발중인 앱에서 쓸 수 있도록 TypeScript로 변환해서 가져온 코드입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// src/apis/UPbitAPI.ts
export const publicUpbitAPI = (method: string, url: string, resolve: Function=> {
    let data = JSON.stringify(false);
 
    const xhr = new XMLHttpRequest();
    xhr.withCredentials = true;
 
    xhr.addEventListener("readystatechange"function () {
        if (this.readyState === this.DONE) {
        // console.log(this.responseText);
            resolve(this.responseText);
        }
    });
 
    xhr.open(method, url);
 
    xhr.send(data);
}
cs


뭐가 달라졌는지 보이시나요? API를 publicUpbitAPI 메소드 안에 구현해 놨습니다.

그리고! 매개변수로 method 와 url 말고 resolve라는 Function이 있는 것 보이시나요?!


다음은 다른 파일에서 위의 publicUpbitAPI를 사용하는 코드입니다.


1
2
3
4
5
6
7
8
// src/stores/tokenStore.ts
...
 
const requestAPI = new Promise((resolve) => {
   publicUpbitAPI(GET, MARKET_CODE_URL, resolve)
});
 
...
cs


여기를 보시면, 매개변수 resolve: Function 의 정체가 나옵니다.


JavaScript UPbit API에서 언뜻 보면 data를 받아와야 할 것 같지만 아닙니다. 제가 원하는 업비트에서 거래 가능한 마켓 목록은 responseText에 있으며, 이를 가져오기 위해 Promise를 만든 것입니다.


물론 이건 제가 꼼수를 좀 부려본 거라, 정석은 아닐 겁니다 하하


여튼, 이렇게 복잡복잡합니다.



request API


그럼 이제 Node API를 보겠습니다. JavaScript API보다 request API 를 사용한 Node API가 훨씬 직관직인 걸 보실 수 있을 겁니다.


하지만, 여전히 안에 들어가서 body를 지지고 볶아서 작업해야하는 건 변함이 없습니다.


그래서 이 request를 요즘의 Promise 기반의 비동기 프로그래밍 방식과 어울리도록 만든 request-promise, fetch, axios 등API들이 나왔습니다. 이들은 promise를 반환합니다.



fetch API


다음은 API를 fetch를  변환한 코드입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// src/apis/UPbitAPI.ts
const publicUpbitAPI = (method: string, url: string, body: {} = {}) => {
    return fetch(url, {
      method: method,
      //header: {}
      body: JSON.stringify(body)
    }).then((response) => response.json())
  }
}
 
// src/stores/tokenStore.ts
@action public loadUpbitTokenList = async () => {
  await publicUpbitAPI('GET''https://api.upbit.com/v1/market/all')
  .then((responseJson) => this.parseUpbitTokenSymbol(responseJson))
  .catch((reject) => {
    console.error(
      "Error occurs during requesting TokenList to Upbit :::" + reject
    )
  })
}
cs


보시는 것처럼 fetch는 promise를 반환합니다. 이를 .then으로 바로 값을 받아올 수 있습니다. 엄청 편하고 직관적입니다.



그럼 다음 포스팅에서는 axios(https://www.npmjs.com/package/axios) 와 fetch(https://www.npmjs.com/package/fetch) 를 비교해보고겠습니다.



참고


https://medium.com/@kkak10/javascript-fetch-api-e26bfeaad9b6