Next.js + Supabase로 빠르게 블로그 방명록 만들기 (with AI 디자인)
오늘도 어슬렁 어슬렁 재밌는 기술 블로그 없나하고 탐색하던 중, 흥미로운 사이트를 발견했습니다. 자신이 직접 만든 블로그에 방명록 기능을 개발해서 탑재해 놓은 거였죠.
어라 ? 이거 Next.js랑 Supabase로 하면 금방 만들겠는데 하고 생각이 들었습니다. 비록 티스토리 블로그지만 좌측 메뉴에 링크만 걸어두면 접근할 수 있으니까요.
재밌어 보이면 빠르게 실행해야죠 ! 먼저 서버셋팅부터 해보겠습니다.
Supabase
서버는 고민없이 Supabase로 선택했습니다. 제가 요즘 취미로 개발하는 타이브레이크에서 요긴하게 사용하는 서비스인데 Firebase와 비슷한 BaaS입니다. 개인적으로 파이어베이스보다 개발자 친화적이며 풀스택 개발에 최적화된 서비스라 생각하네요.
React, Flutter, Python 등 다양한 플랫폼에서 SDK를 제공해주기때문에 여러 환경에서 편하게 사용할 수 있습니다.
Supabase에 대해 생소할 수도 있으니 GPT에게 물어보니 다음과 같이 답변을 해주네요.
먼저 Supabase에서 가입을 하면 프로젝트를 생성할 수 있습니다. 다음과 같이 프로젝트명과 지역 region을 설정하고 프로젝트를 만들어 봅니다.
감사하게도 Seoul Region을 지원해주네요. 프로젝트를 생성했으니 이제 guestbook 테이블을 생성해 보죠.
테이블에는 어떤 Column이 필요할까요 ? 익명 방명록이라 많은 데이터가 필요하진 않습니다.
- id : guestbook id
- crated_at : 작성 시간
- content : 방명록 내용
supabase에서는 데이터 생성시에 id와 created_at은 자동으로 할당해줍니다. 우리가 추가해야할 건 방명록 내용에 해당하는 content 뿐이죠.
테이블명을 guestbook으로 하고 다음과 같이 column을 설정해주었습니다.
서버 셋팅을 완료했으니 이제 클라이언트를 개발해야겠죠 ?
하지만 화면을 개발하기 위해서는 디자인이 필요합니다. 항상 개발자들이 고통받는 부분이죠 😭
다행히 요즘은 AI가 간단한 디자인정도는 만들어줍니다 ! 세세한 디자인까진 아니어도 간단한 와이어프레임정도는 프롬프트를 통해 손쉽게 생성할 수 있죠.
v0로 디자인 생성하기
프론트엔드의 카르텔, Vercel이 만든 v0에서 간단한 디자인을 만들어보겠습니다. 간단한 설명만 입력하면 원하는 디자인을 만들어 주는데요, 저는 프롬프트를 다음과 같이 설정했습니다.
guest book with bottom fixed small input
방명록 리스트와 하단에 고정된 입력폼 구성의 디자인이 필요해서 요청해봤는데요, 한번 결과물을 살펴볼까요 ?
와우. 딱 깔끔한 디자인의 원하는 결과물이 나왔네요. 이정도면 방명록을 개발하기에 무리없어보입니다.
v0는 프롬프트를 입력하면 평균 3개정도의 결과물을 제공해주는데 원하는 디자인을 고르면 될 것 같습니다. 만약 맘에 들지 않으면 상세한 입력을 통해 원하는 디자인을 추출하면 될 것 같아요.
참고로 v0도 GPT처럼 무료 크레딧이 정해져있습니다. 소진되면 돈을내고 추가 크레딧을 구매해야 합니다.
취미로 사용하기에는 충분히 제공해주는 것 같습니다. 테스트하면서 많이 생성해봤는데 저는 아직 넉넉히 남은것 같아요.
Next.js
서버와 디자인까지 완성되었으니 Next.js로 클라이언트를 개발해보겠습니다.
Next.js는 App Router로 개발하겠습니다. Page Router가 익숙해서 처음에는 폴더구조도 어색하고 예약된 파일명도 낯설었는데 몇번 사용해보니 익숙해졌네요. npx 명령어로 빠르게 Next를 설치해줍니다.
npx create-next-app@latest
환경설정은 원하는 입맛에 골라서 설정해주면 됩니다.
저는 tailwind를 사용하지 않고 따로 UI를 만들어 사용하고 있기에 tailwind는 생략해줄게요.
Supabase에서 데이터를 가져오기 위히서는 supabase 클라이언트를 설정해줘야 합니다. 공식문서에 잘 설명이 되어있으니 참고하시면 됩니다. API KEY를 가지고 supabase client를 설정해주겠습니다.
import { createClient } from "@supabase/supabase-js";
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_KEY!
);
supabase client를 생성하면 이제 SDK와 쿼리문을 통해 데이터를 불러올 수 있습니다. 다음과 같이 supabase에서 guestbook column 데이터를 불러오겠습니다.
const { data, count } = await supabase
.from("guestbook")
.select("*", { count: "exact" })
.order("created_at", { ascending: false });
count "exact"를 설정하면 리스트의 갯수도 함께 리턴받을 수 있습니다. 작성된 순으로 보여주기 위해 created_at을 내림차순으로 정렬해줍니다.
guestbook 리스트를 불러왔으면 등록하는 로직도 필요하겠죠 ? 아래 API를 통해 supabase guestbook 테이블에 데이터를 추가할 수 있습니다.
const result = await supabase.from("guestbook").insert({ content: content });
React-Query를 함께 사용하면 supabase의 데이터를 좀 더 쉽게 관리할 수 있습니다. 저는 다음과 같이 supabase api와 react-query 구현부를 분리하여 사용하고 있습니다.
// api.ts
export const getGuestbooks = async () => {
const { data, count } = await supabase
.from("guestbook")
.select("*", { count: "exact" })
.order("created_at", { ascending: false });
return { data, count } as GuestbookListResultInterface;
};
// queries.ts
const enum QueryKeys {
Guestbook = "guestbook",
}
export const useGetGuestbook = () => {
return useQuery({
queryKey: [QueryKeys.Guestbook],
queryFn: () => getGuestbooks(),
});
};
이렇게 react-query와 함께 사용하면 데이터 캐싱은 물론 loading 유무 등 서버상태를 손쉽게 관리할 수 있죠.
guestbook 등록 API 또한 useMuation을 통해 쉽게 POST를 날릴 수 있습니다.
Vercel에 배포하기
요즘 Vercel을 통한 프론트엔드 배포는 너무나 편하죠. AI 디자인을 토대로 개발을 완료하고 배포를 완료했습니다.
결과물은 다음과 같습니다. 얼추 디자인과 비슷한것 같네요 ?
링크를 통해 방명록에서 테스트해보실 수 있습니다. Supabase는 Free Plan에서 무제한에 가까운 API request를 제공하기 때문에 사이드 프로젝트 혹은 간단한 서비스에서 API로 사용할 수 있습니다.
제 생각이지만 스타트업 초기 혹은 MVP 단계에서 무리없이 백엔드로 사용할 수 있을것 같아요. 속도가 생명인 상황에서는 빠르게 클라이언트 개발을 통해 시장의 반응을 살펴야 하니까요.
아래 깃허브에 코드도 있으니 필요시 참고하세요 ☺️
https://github.com/hurdle92/pure-strike-monorepo/tree/main/apps/guestbook