supabase join 으로 여러 데이터 한번에 가져오기

D uuu·2024년 7월 4일
0

Next.js14 프로젝트

목록 보기
10/11
post-custom-banner

리팩토링 과정

최근 프로젝트에서 팔로워 리스트를 가져오는 기능을 구현하던 중, 나를 팔로우한 유저의 프로필 정보를 가져오는 과정이 너무 복잡하고 비효율적이라는 생각이 들었다. 그래서 리팩토링을 진행했으며, 기존 방식에서의 10여변의 API 호출을 Supabase의 조인 기능을 활용하여 이를 한 번의 호출로 해결했다.

기존 방식

나를 팔로우한 유저 리스트를 불러오기 위해서는 두 단계가 필요했다.

1) 팔로워 요청한 유저의 ID 가져오기:

먼저 follow 테이블에서 나를 팔로우한 유저 리스트를 가져온다.

export const getFollowerList = async (pageParam: number, pageSize: number): Promise<FollowType[] | undefined> => {
    const supabase = createClient();

    const { data } = await supabase.auth.getSession();

    if (!data.session) return;

    const user_id = data.session.user.id;

    const { data: followerList, error } = await supabase
        .from('follow')
        .select('*')
        .eq('requestee_id', user_id)
        .range((pageParam - 1) * pageSize, pageParam * pageSize - 1);

    if (error) {
        throw new Error(error.message);
    }

    return followerList;
};

2) followerIds를 가지고 순회하면서 profiles 테이블 조회하기:

얻은 followerIds 배열을 사용하여 profiles 테이블에서 해당 유저의 정보를 가져온다. ids 배열을 가지고 useQueries 를 호출하기 때문에 여기서 많은 API 요청이 발생했고, 결국 목적은 나를 팔로워 한 유저의 프로필 정보를 가져오는 것인데 코드가 복잡해지는 문제가 있었다.

 const {
    data: followerIds,
    hasNextPage,
    fetchNextPage,
    isFetchingNextPage,
} = useInfiniteQuery({
    queryKey: ['followerList'],
    queryFn: ({ pageParam }) => getFollowerList(pageParam, FOLLOW_PAGE_SIZE),
    initialPageParam: 1,
    getNextPageParam: (lastPage, allPages, lastPageParam) => {
        if (lastPageParam < totalPage) {
            return lastPageParam + 1;
        }
    },
    select: (data) => {
            return data.pages.flat().map((page) => page.requester_id);
    },
});

 const followerUserDatas = useQueries({
        queries:
            followerIds?.map((id) => ({
                queryKey: ['followerUser', id],
                queryFn: () => getFollowUserListsPaginated(id!),
            })) || [],
        combine: (results) => {
            return {
                data: results.map((result) => result.data).flat(),
            };
        },
    });

리팩토링 후

이 문제를 해결하기 위해 찾아보던 중 Supabase의 조인 기능을 알게 됐고, 한 번의 API 호출로 팔로워와 관련된 데이터를 한번에 가져오도록 리팩토링을 진행했다.

join 으로 한번에 해결하기

follow 테이블과 profiles 테이블을 조인하여 팔로워와 관련된 모든 데이터를 한 번에 가져온다.

export const getFollowerList = async (pageParam: number, pageSize: number) => {
    const supabase = createClient();

    const { data } = await supabase.auth.getSession();

    if (!data.session) return;

    const user_id = data.session.user.id;

    const { data: followerList, error } = await supabase
        .from('follow')
        .select(
            `
        *,
        profiles!follow_requester_id_fkey1(id, username, avatar_url, email)
        `
        )
        .eq('requestee_id', user_id)
        .range((pageParam - 1) * pageSize, pageParam * pageSize - 1);

    if (error) {
        throw new Error(error.message);
    }
    return followerList;
};
profile
배우고 느낀 걸 기록하는 공간
post-custom-banner

0개의 댓글