Next.js, ServerAction vs API in concurrency

곰튀김·2025년 1월 23일
0

이슈

ServerAction을 Promise.all 로 호출했는데, 동시에 수행이 되지 않더라.
이슈 / 해결

의문

  • 그럼 ServerAction하고 API 하고 어떤 것을 쓰는것이 더 좋겠는가?
  • 그럼 API 는 동시에 사용 가능한가?

실험1

ServerAction 내에서 동시에 여러개 하기

"use server";

export const actionCall = async () => {
  const currentTime = new Date().getTime();
  await Promise.all([action1(), action2()]);
  return new Date().getTime() - currentTime;
};

const action1 = async () => {
  return new Promise<void>((resolve) => {
    setTimeout(() => {
      console.log("action1");
      resolve();
    }, 1000);
  });
};

const action2 = async () => {
  return new Promise<void>((resolve) => {
    setTimeout(() => {
      console.log("action2");
      resolve();
    }, 1000);
  });
};

결과

  • 대략 1002 ~ 1005 정도 나옴
  • 동시에 수행되고 있음
  • ServerAction 내에서 Promise.all은 되는구나!

실험2

API 내에서 여러 작업 수행하기

export async function GET() {
  const currentTime = new Date().getTime();
  await Promise.all([action1(), action2()]);
  const result = new Date().getTime() - currentTime;
  return NextResponse.json({ result: result.toString() });
}

결과

  • 대략 1003 ~ 1005 정도 나옴
  • 당연하다고 생각됨

실험3

클라이언트에서 같은 API 동시에 호출하기

const handleApi3 = async () => {
  const currentTime = new Date().getTime();
  await Promise.all([
    fetch("/api/call3").then((res) => res.json()),
    fetch("/api/call3").then((res) => res.json()),
  ]);
  const result = new Date().getTime() - currentTime;
  setResult4(result.toString());
};

결과

  • 대랙 2020 ~ 2100 정도 나옴
  • 동시에 안되고 있구나.
  • 같은 API를 호출하는 것은 동시에 수행을 못한다.

실험4

그럼 다른 API는 동시에 가능한가?

const handleApi4 = async () => {
  const currentTime = new Date().getTime();
  await Promise.all([
    fetch("/api/call3").then((res) => res.json()),
    fetch("/api/call4").then((res) => res.json()),
  ]);
  const result = new Date().getTime() - currentTime;
  setResult5(result.toString());
};

결과

  • 대략 1020 ~ 1100 정도 나옴
  • 동시에 되고 있다.
  • 다른 API는 동시에 호출이 가능하구나!

실험5

실험3에서 같은 API에 대해서 동시에 못하는데, 그럼 같지만 않으면 되는 것인가?

const handleApi3 = async () => {
  const currentTime = new Date().getTime();
  await Promise.all([
    fetch("/api/call3?1").then((res) => res.json()),
    fetch("/api/call3?2").then((res) => res.json()),
  ]);
  const result = new Date().getTime() - currentTime;
  setResult4(result.toString());
};

결과

  • 대략 1020 ~ 1050 정도 나옴
  • endpoint만 다르게 해도 동시에 처리 가능

분석

  • API 호출은 같은 route 에 대해서 동시에 못한다.
  • ServerAction은 다른 action이라도 동시에 못한다.
  • (나는 ServerAction을 선호하니까) ServerAction 에서 작업하고 모든 일은 내부에서 처리하자.
  • 같은 작업을 동시에 여러번 돌려야 하는 작업의 경우 API를 만들고, endpoint 를 다르게 해서 호출하자
  • 이럴거면 그냥 다 API로 만들어 쓰는게 낫겠다!
  • 그럼 어떤경우 ServerAction을 써야할까. environment 사용하는 경우 같은거?

결론

  • API를 사용해서 만드는 것을 기본으로 한다.
  • environment에 영향있는 간단한 작업의 경우에만 ServerAction을 사용하자.
profile
사실주의 프로그래머

1개의 댓글

Powered by GraphCDN, the GraphQL CDN