붉은거위 노트 (redgoose note)

API를 묶어서 요청하기

Nest
Concept
Category
Programing
Hit
256
Star
0

예전부터 계속 생각해왔던 것인데 이제서야 갑자기 생각이 나서 기록을 해둔다.

요즘에는 rest api 요청을 엄청많이하는 편이다. 페이스북 웹사이트만해도 작은 요소들도 엄청나게 요청해댄다. http2이후에 퍼포먼스가 대단히 좋아져서 부담없이 사용하곤 하는데 역시나 많이 요청하는것보다 적게 요청해서 한꺼번에 주고받는것이 낫긴하다.
편의성과 파편화를 고려해서 많이 요청하는 쪽으로 선택하곤 하는데 같은 타이밍에 여러번 요청하는것을 보면 아무래도 낭비같이 느껴진다. ㅠㅠ

클라이언트에서 요청하는 부분의 작업은 가이드대로 사용하면 그만이지만 백엔드에서 API 요청을 받는 부분에서 인터페이스를 새롭게 만들어야 하는 수준이 될것이다.
이 부분을 괜찮은 설계로 만들 수 있으면 좋을텐데..

시도하다가 실패했다. ㅠㅠ

예전에 그루핑된 API 처리 모듈을 만드려고 시도해본적이 있었다.
그때 당시에 좌절되었던 이유가 한번 요청해서 결과물을 받아서 조작을 하고, 그것으로 다시 요청해야하는 패턴을 처리하려고 하다가 좌절했던 기억이 난다. (일종의 미들웨어)

아마도 이런 미들웨어도 설계를 꽤 잘하면 파라메터에다 프로그래밍적인 요소를 집어넣어 사용해서 다룰 수 있을것이다. 이건 좀 많이 진행된 모습일것이다..

기초적인 컨셉

기본적인 컨셉은 다음과 같이 요청하는 RestAPI 주소가 3개가 있다. 이것을 처리하는 코드는 다음과 같다.

import { $fetch } from 'ohmyfetch';

// 하나씩 처리하기
const res1 = await $fetch('https://foo.com/aaa');
const res2 = await $fetch('https://foo.com/bbb');
const res3 = await $fetch('https://foo.com/ccc');

// 한꺼번에 처리하기
const [ res1, res2, res3 ] = await Promise.all([
  $fetch('https://foo.com/aaa'),
  $fetch('https://foo.com/bbb'),
  $fetch('https://foo.com/ccc'),
]);

이렇게 사용하면 브라우저에서 결국에 3번 보내고 3번 결과를 받는다.
아무리봐도 퍼포먼스가 별로 좋진 않았다. 수치적으로 증명 됐었고..


현재 구상하고 있는 요청하는 모습은 다음과 같다.

import { $fetch } from 'ohmyfetch';

const { res1, res2, res3 } = await $fetch('https://foo.com/group', {
  method: 'post',
  responseType: 'json',
  body: {
    queues: [
      { url: 'https://foo.com/aaa', method: 'get' },
      { url: '/bbb', method: 'get' },
      { url: '/ccc', method: 'get' },
    ],
  },
});

이런 모습으로 요청하면 한번 요청하고 한번에 받아서 처리할 수 있다.
백엔드 영역에서는 3개의 요청을 처리하지만 속도는 체감이 올 정도로 빠르다.

백엔드 영역에서의 구성

보통 이런 모습은 3개의 API 처리하는걸 새로운 API로 만들어서 운영하겠지만 따로 API를 조각내어 사용하게되면 용도에 맞춰 사용할 수 있을것이다.
그래서 API 주소를 해석하여 각각 내부 라우트에 접근할 수 있으면 좋을것이라 생각된다. 위에 요청하는 파라메터 queues에서의 주소를 해석하고 내부의 라우트 메서드를 실행하는 인터페이스를 먼저 만들어야 할것이다. 아직 제대로 시도해보지 못한 부분..

주소 해석기를 만들고, 접근해서 처리하고, 결과 메시지를 받아서 전부 완성되면 결과물을 내보내면 될것이다.

처리를 순서대로 진행하더라도 내부에서 여러개 처리하는게 더 빠르다. (엄청나게 많은 요청이 있다면 얘기가 달라질지도 모르겠지만..)

"주소 -> 메서드"로의 과정

아마도 이게 가장 험한 언덕일 것이다.
주소 문자를 해석하고 그걸로 메서드로 연결해야 하는데 이게 꽤 변수가 많을 것이다.

앞에 https문자가 붙어있으면 외부에서 요청하는거라고 판단해버리고 따로 요청하면 그만일 것이다.

/bbb, /ccc와 같이 로컬주소라면 내부 모듈의 메서드랑 연결해야 할것인데.. 아마 라우트로 연결할 수 있는지도 시험해봐야 할것이고, 아니면 라우트를 새로 짜야할지도 모르겠다.
최악의 수는 필요한 것들만 조건문 형태의 스위칭을 만들어 문자가 맞으면 일일히 메서드를 실행하게 하는 방법 ㅋㅋ~ (이게 가장 안전빵이고, 구현은 쉬울 것이다.)