node.js express - 하나의 api에서 같은서버의 다른 api를 호출하는 법

tennfin1·2023년 7월 22일
0

backend

목록 보기
3/18

코린이입니다.
지적해주시면 너무 감사하겠습니다.


node.js express 패키지를 개발하다가 든 생각입니다.

node express로 api를 개발하는 과정에서, 하나의 api내부에서 다른 api를 호출하는 경우가 있습니다.
특히 외부api 같은 경우는 이 방식을 사용하는 것이 맞습니다.

//귀찮아서 Chat GPT로 작성된 코드

const express = require('express');
const axios = require('axios');

const app = express();

app.get('/external-api', async (req, res) => {
  try {
    const response = await axios.get('https://api.example.com/endpoint');
    // 외부 API에서 받은 데이터를 처리
    res.json(response.data);
  } catch (error) {
    res.status(500).json({ error: 'External API call failed' });
  }
});

app.listen(3000, () => {
  console.log('서버가 3000번 포트에서 실행 중입니다.');
});

근데 같은 서버 안에서 정의된 다른 api라면...어떻게 해야할까요?
일단 기본적으로는 같은 방식으로 가능한 것 같습니다.

//역시나 chatGPT로 작성된 코드

const express = require('express');
const axios = require('axios');

const app = express();

app.get('/internal-api', async (req, res) => {
  try {
    const response = await axios.get('http://localhost:3000/other-endpoint');
    // 내부 API에서 받은 데이터를 처리
    res.json(response.data);
  } catch (error) {
    res.status(500).json({ error: 'Internal API call failed' });
  }
});

app.listen(3000, () => {
  console.log('서버가 3000번 포트에서 실행 중입니다.');
});

근데, 프론트엔드에서 하나의 api를 호춣했는데, 그 안에서 다른 api를 호출하는 방식이 과연 옳은 걸까요?
제가 만든 api의 호출은 결국 http(https) 통신에 의해 이루어지는데, http 통신 안에서 또한 http 통신이 존재한다라...
시간이 굉장히 오래걸리겠군요.(DB통신 오래걸리듯이)

생각해보면 api내에서 외부 api를 호출하는 것에 대해서 이 점은 어쩔 수 없습니다.
외부 api는 저희와는 독립된 개체니깐요.

그렇다면 내부 api를 호출하는 과정에서 이 방식을 해결할 수 있을 것 같습니다.

그 전에 가장 먼저 고려해야할 것이 있습니다.

1. 호출하려는 기능이 꼭 api형태일 필요가 없는 경우

api는 기본적으로 호출과 응답의 구조를 지니는 과정에서 통신을 사용합니다.
즉, 제가 사용하려는 내부 api가 이렇게 다른 api에서 호출만을 위해 사용되는 것인지 아닌지가 정말 중요합니다.

다른 api의 호출되는 용도로만 사용됨 => 굳이 api로 만들어야 하는가?
다른 api에서도 호출됨은 물론이요, 그 자체로도 api로 기능함 => api로 만들긴 해야함.

가령, 다음과 같은 형태에서

//대충작성한 예시 코드지, 코드로서 동작 안합니다.

app.get('/calling-api', async (req, res) => {
  try {
    const response = await axios.get('http://localhost:3000/called-api');
    //other self code
    res.json(response.data);
  } catch (error) {
    res.status(500).json({ error: 'failed' });
  }
});

app.get('/called-api', async (req, res) => {
  try {
    //self code
    res.json(response.data);
  } catch (error) {
    res.status(500).json({ error: 'failed' });
  }
});

/calling-api가 called-api를 호출하는 경우인데,
called-api가 프론트엔드에서 직접호출하는 api가 아니라면, 굳이 api로 호출해주지 않아도 됩니다.

역시나 대충 작성한 함수
app.get('/calling-api', async (req, res) => {
  try {
    const response = await called_api()
    res.json(response.data);
  } catch (error) {
    res.status(500).json({ error: 'failed' });
  }
});

//함수 형태
const called_api = async() =>{
	//your code
    
    return you_wanted
}

대충 작성한거라 문법에 오류가 많지만, 아무튼 async await을 이용해 비동기처리만 잘해주면,
api가 아닌 그냥 함수로서 작성을 해서 가져다 쓰면 되고, 동 서버 내 다른 파일이면 module로 만들어서 사용하면 됩니다.

2. 호출하려는 기능이 꼭 api형태여야만 하는 경우

위의 과정을 이해했으면 당연히 쉽게 유추 가능하다고 생각합니다.
1번과 동일하게 함수를 만들고, 빈 api를 만들어서 그 안에 삽입
= api로서도 호출이 가능하고, 함수로서도 사용이 가능함

역시나 대충 작성한 함수
app.get('/calling-api', async (req, res) => {
  try {
    const response = await called_api()
    res.json(response.data);
  } catch (error) {
    res.status(500).json({ error: 'failed' });
  }
});

//함수 형태
const called_api = async() =>{
	//self code
    return you_wanted
}

app.get('/called-api', async (req, res) => {
  try {
    const response = await called_api() // = self code의 역할을 함
    res.json(response.data);
  } catch (error) {
    res.status(500).json({ error: 'failed' });
  }
});

이상입니다.

다만, 함수형태를 추출해서 api로 가져다 쓰려면 반환이랑 response등을 맞춰줘야하고, try catch등을 잘 다뤄야한다는 점....
뿐만 아니라 api로 작성되는 파일이랑 api 내부에 들어가는 함수 파일을 또 나눠줘야 합니다.

문법 상관없이 작성한 코드라 흐름만 참고하기

profile
심도깊은개발

1개의 댓글

comment-user-thumbnail
2023년 7월 22일

정리가 잘 된 글이네요. 도움이 됐습니다.

답글 달기

관련 채용 정보