Server Action의 비밀

coggiee
4 min readNov 1, 2024

--

useQueries는 여러 개의 쿼리를 병렬로 호출한다. 하지만 queryFnserver action 이라면 병렬로 처리되지 않는다.

버그인지 의도인지는 모르겠으나 use server는 서버 상태를 업데이트하는 일종의 mutation의 목적으로 디자인 되었기 때문에 데이터를 가져오는 작업에는 추천되지 않으며, 한 번에 단 하나의 작업만 수행한다고 한다. (ref)

곰곰히 생각해보면, mutation은 한 번에 하나만 수행하는 경우가 많기 때문에 use server 의 동작방식이 납득이 가는 것 같다.

server action의 waterfall 예시

전제 조건은, 3개의 쿼리를 useQueries 로 호출하며 각 쿼리의 queryFn 은 서버 액션으로 동작한다. ( 모든 queryFn 은 prisma를 사용하여 db 내부의 데이터를 가져온다.)

// util/network.ts
'use server';

export const getClub = async ({ id }: ID) => {
const response = await prisma.club.findUnique({
where: { id }
});

return response;
}

export const getFooter = async ({ id }: ID) => {
const response = await prisma.footer.findUnique({
where: { club_id: id },
});

return response;
};

export const getLink = async ({ id }: ID) => {
const response = await prisma.navigation.findMany({
where: {
club_id: id,
},
});

return response;
};
server action으로 작성한 queryFn

위 예시를 보면 의도한 바와 다르게 3개의 쿼리가 병렬이 아닌, 한 번에 하나의 작업만 수행되고 있다.

만약 데이터가 많지 않다면 크게 문제가 되지 않을 것 같지만, 미래를 고려해서 바꿔보자.

route handler로의 회귀

export const getClub = async ({ id }: { id: string }) => {
const { data } = await axios<ClubResponse>(`/api/club/${id}/info`);

return data;
};

export const getFooter = async ({ id }: { id: string }) => {
const { data } = await axios<FooterResponse>(`/api/club/${id}/footer`);

return data;
};

export const getLink = async ({ id }: { id: string }) => {
const { data } = await axios<LinkResponse>(`/api/club/${id}/link`);

return data;
};
server action대신 route handler 사용

기존의 서버 액션은 prisma가 브라우저에서 동작할 수 없고 API Endpoint를 작성하는게 번거로워서 사용했다. 하지만 이는 의도했던 바인 병렬 처리로 동작하지 않기 때문에, 서버에서 동작 하면서도 병렬 처리가 될 수 있도록 route handler로 변경했다.

이제 3개의 쿼리가 의도했던 대로 병렬로 동작하는 것을 볼 수 있다.

다른 솔루션 — “중첩 함수”

나에게는 이 솔루션이 약간은 귀찮은 작업처럼 보이지만, 상황과 목적에 맞게 적용하면 될 것 같다.(ref)

핵심은 서버 액션으로 동작하는 함수 내부에 다른 async 중첩 함수를 선언하여 이 중첩 함수에서 로직을 처리하는 것이다. 그리고 외부 함수는 해당 중첩 함수를 반환한다.

요약

문서를 잘 살펴보자

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

coggiee
coggiee

Written by coggiee

0 Followers

Just doing

No responses yet

Write a response