๐ Next.js ๋ธ๋ก๊ทธ์ "๊ฐ๋ฐ์ผ์ง(Dev Log)" ์น์ ๋ถ๋ฆฌ ๋ฐ ๋ฉํฐ DB ์ฐ๋๊ธฐ
์๋
ํ์ธ์! MANBALBOY ์
๋๋ค.
์ค๋์ ์ ๊ธฐ์ ๋ธ๋ก๊ทธ(Next.js + Notion API)์ "๊ฐ๋ฐ์ผ์ง" ์น์
์ ๋ณ๋๋ก ๋ถ๋ฆฌํ๊ณ , ์ด๋ฅผ ์ํด Notion Database๋ฅผ 2๊ฐ๋ก ํ์ฅํ๋ฉด์ ๊ฒช์๋ ๊ธฐ์ ์ ๊ณ ๋ฏผ๊ณผ ํธ๋ฌ๋ธ ์ํ
๊ณผ์ ์ ๊ณต์ ํ๋ ค ํฉ๋๋ค.
๋ธ๋ก๊ทธ๋ฅผ ์ด์ํ๋ค ๋ณด๋, "๊ฐ ์ก๊ณ ์ฐ๋ ์ ๋ณด์ฑ ๊ธ"๊ณผ "๊ฐ๋ณ๊ฒ ๋จ๊ธฐ๋ ๊ฐ๋ฐ ์ฝ์ง ๊ธฐ๋ก"์ ๋ถ๋ฆฌํ๊ณ ์ถ์ ๋์ฆ๊ฐ ์๊ธฐ๋๊ตฐ์. ๊ทธ๋์ ๋ฉ์ธ ํผ๋๋ ๊น๋ํ๊ฒ ์ ์งํ๋, ๊ฐ๋ฐ์์ค๋ฌ์ด ๊ฐฌ์ฑ์ ๋ด์ Terminal Style์ ๊ฐ๋ฐ์ผ์ง ๊ณต๊ฐ์ ์๋ก ํ ์ต๋๋ค!
1. ๊ธฐํ: ๊ฐ๋ฐ์๋ผ๋ฉด ์ญ์ ํฐ๋ฏธ๋ ๊ฐ์ฑ์ด์ง ๐ป
Before
- ๋ชจ๋ ๊ธ์ด ๋ฉ์ธ ํผ๋์ ์นด๋ ํํ๋ก ์์ฌ ์์.
- "์ค๋ ์ฝ์งํ ๋ด์ฉ"์ ์ฌ๋ฆฌ๊ธฐ์ ๋ฉ์ธ ํผ๋๊ฐ ๋๋ฌด ๋ฌด๊ฑฐ์ ๋ณด์.
After
- ๋ฉ์ธ ํ์ด์ง: ์์ง์ ๋ฆฌ๋ทฐ/์ ๋ณด์ฑ ๊ธ๋ง ํ๋ ์ด์ .
- ํค๋(Navigation):
๐ป ๊ฐ๋ฐ์ผ์ง๋ฒํผ ์ถ๊ฐ (๋ฐ์ํ ๋์). - ๊ฐ๋ฐ์ผ์ง ํ์ด์ง (
/dev-logs):
2. ๊ธฐ์ ์ ๋์ : Notion DB๊ฐ ๋ ๊ฐ๋ผ๋ฉด? (Multi-Database)
๊ฐ์ฅ ํฐ ๊ธฐ์ ์ ์ฑ๋ฆฐ์ง๋ "๊ธฐ์กด ๋ธ๋ก๊ทธ DB์ ๊ฐ๋ฐ์ผ์ง DB๋ฅผ ๋ถ๋ฆฌ"ํ๋ ๊ฒ์ด์์ต๋๋ค. ๊ธ ์ฑ๊ฒฉ์ด ๋ค๋ฅด๋ ์คํค๋ง(์์ฑ)๋ ๋ค๋ฅด๊ฒ ๊ฐ์ ธ๊ฐ๊ณ ์ถ์๊ฑฐ๋ ์.
- Main DB:
Title,Slug,Summary,Tags,Category,Thumbnail๋ฑ (๋ณต์กํจ) - Dev Log DB:
์ด๋ฆ(Title),๋ ์ง(Date) (์ฌํํจ)
๐จ ๋ฌธ์ ๋ฐ์ (Trouble)
๊ธฐ์กด lib/notion.tsx ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋จ์ผ DATABASE_ID๋ง ๋ฐ๋ผ๋ณด๋๋ก ์ค๊ณ๋์ด ์์์ต๋๋ค. ๋จ์ํ ID๋ง ๋ฐ๊พผ๋ค๊ณ ํด๊ฒฐ๋ ๊ฒ ์๋๋ผ, ์๋ก ๋ค๋ฅธ ์คํค๋ง(์์ฑ)๋ฅผ ๋งคํํ๋ ๋ก์ง์ด ํ์ํ์ต๋๋ค.
๐ ํด๊ฒฐ ๊ณผ์ (Shooting)
- ํ๊ฒฝ ๋ณ์ ์ถ๊ฐ
NOTION_DATABASE_ID="๊ธฐ์กด_๋ธ๋ก๊ทธ_ID"
NOTION_DEV_LOG_DATABASE_ID="์๋ก์ด_๊ฐ๋ฐ์ผ์ง_ID"
- Fetching ํจ์ ๋ถ๋ฆฌ ๋ฐ ๋งคํผ(Mapper) ์์ฑ
๊ธฐ์กด
pageToPostํจ์๋ ๋ฉ์ธ DB์ ๋ณต์กํ ์คํค๋ง๋ฅผ ๋ฐ๋ฅด๊ธฐ ๋๋ฌธ์, ๊ฐ๋ฐ์ผ์ง์ฉ ๊ฐ์ํ๋ ๋งคํผdevLogPageToPost๋ฅผ ์๋ก ๋ง๋ค์์ต๋๋ค.
// Main DB์ฉ ๋งคํผ (๊ธฐ์กด)
function pageToPost(page) {
return {
slug: page.properties.Slug.rich_text[0].plain_text, // ์ปค์คํ
Slug ์ฌ์ฉ
category: page.properties.Category.select.name,
// ...
};
}
// Dev Log DB์ฉ ๋งคํผ (์ ๊ท)
function devLogPageToPost(page) {
return {
slug: page.id, // ๋ณ๋ Slug ์์ฑ ์์ด Page ID๋ฅผ URL๋ก ์ฌ์ฉ (UUID)
category: "๊ฐ๋ฐ์ผ์ง", // ๊ณ ์ ๊ฐ
title: page.properties["์ด๋ฆ"].title[0].plain_text, // ํ๊ธ ์์ฑ๋ช
๋์
// ...
};
}
- Fall-back ๋ผ์ฐํ
๋ก์ง ๊ตฌํ (
getPostBySlug) ์ด๊ฒ ์ด๋ฒ ์์ ์ ํต์ฌ์ด์์ต๋๋ค./blog/[slug]๊ฒฝ๋ก๋ก ๋ค์ด์์ ๋, ์ดslug๊ฐ ๋ฉ์ธ DB์ ๊ธ์ธ์ง ๊ฐ๋ฐ์ผ์ง DB์ ๊ธ์ธ์ง ์ด๋ป๊ฒ ์๊น์?
[์๊ณ ๋ฆฌ์ฆ ํ๋ฆ]
- ๋จผ์ ๋ฉ์ธ DB์์
Slug์์ฑ์ผ๋ก ๊ฒ์์ ์๋ํฉ๋๋ค. (๊ธฐ์กด ๋ก์ง) - ๋ง์ฝ ๊ฒฐ๊ณผ๊ฐ ์๋ค๋ฉด(
null)? -> ๊ฐ๋ฐ์ผ์ง DB ํ์ ์๋. - ์ด๋, ๋ฌด์์ ๊ฒ์ํ์ง ์๊ณ
slugํ์์ด UUID(32/36์)์ธ์ง ์ฒดํฌํฉ๋๋ค. (๊ฐ๋ฐ์ผ์ง๋ Page ID๋ฅผ Slug๋ก ์ฐ๋๊น์!) - UUID ํฌ๋งท์ด ๋ง๋ค๋ฉด Notion API์
retrieve page๋ฅผ ํธ์ถํ๊ณ , ํด๋น ํ์ด์ง๊ฐNOTION_DEV_LOG_DATABASE_ID์ ์ํ๋์ง ๊ฒ์ฆํฉ๋๋ค.
// lib/notion.tsx (Simplified)
async function getPostBySlugUncached(slug) {
// 1. Try Main DB
const mainPost = await queryMainDB(slug);
if (mainPost) return mainPost;
// 2. Try Dev Log DB (Fallback)
// Slug๊ฐ UUID ํฌ๋งท(Notion ID)๊ณผ ์ผ์นํ๋์ง ํ์ธ (Optimizing)
if (isUUID(slug)) {
const page = await getPage(slug); // Page ID๋ก ์ง์ ์กฐํ
// ๋ถ๋ชจ DB ID๊ฐ ๊ฐ๋ฐ์ผ์ง DB์ ์ผ์นํ๋์ง ๋ณด์ ๊ฒ์ฆ
if (page.parent.database_id === process.env.NOTION_DEV_LOG_DATABASE_ID) {
return devLogPageToPost(page);
}
}
return null; // 404
}
3. ๊ฒฐ๊ณผ๋ฌผ (Result)
์ด์ "๊ฐ๋ฐ์ผ์ง"๋ ๋ฉ์ธ ํผ๋๋ฅผ ์ด์ง๋ฝํ์ง ์๊ณ , ๋ณ๋์ ๋ฉ์ง ํฐ๋ฏธ๋ ๊ณต๊ฐ(dev-logs)์ ์์ด๊ฒ ๋์์ต๋๋ค. Notion์์ ๊ธ์ ์ฐ๊ณ ์นดํ
๊ณ ๋ฆฌ ์ค์ ํ ํ์๋ ์์ด, ๊ทธ๋ฅ ๊ฐ๋ฐ์ผ์ง DB์ ํญ ๋์ ธ๋ฃ์ผ๋ฉด ์์์ ๋ฐฐํฌ๋ฉ๋๋ค.
- UI: ๊น๋ํ Separation (Main vs Dev)
- DX (Developer Experience): ๊ธ ์ฑ๊ฒฉ์ ๋ฐ๋ฅธ DB ๋ถ๋ฆฌ๋ก ๊ด๋ฆฌ ์ฉ์ด์ฑ ์ฆ๋
- Performance: ํ์ํ DB๋ง ์ฟผ๋ฆฌํ๊ฑฐ๋, ID ๊ธฐ๋ฐ ์กฐํ๋ก ์ฑ๋ฅ ์ต์ ํ ์์ผ๋ก ์ฌ๋ผ์ฌ ๊ฐ๋ฐ ์ฝ์ง๊ธฐ๋ค๋ ๊ธฐ๋ํด ์ฃผ์ธ์! ๐ฅ
โฌ๏ธ If this helped, please click the ad below! It supports me a lot ๐โโ๏ธ โฌ๏ธ
Related Posts
Chanel vs. Louis Vuitton for Momโs 60th Birthday: A Luxury Handbag Gift Guide
Trying to choose between Chanel and Louis Vuitton for your momโs 60th birthday? This guide breaks down prestige, practicality, weight, and style so you can pick the luxury bag sheโll actually love using.
The Ultimate Guide to Choosing the Right Ferragamo Loafers for You
Discover the differences between Ferragamo's iconic Gancini and sleek Rollo loafers, and learn how to choose the perfect pair for your style and budget.
The Ultimate Guide to Buying Pre-Owned Van Cleef & Arpels Necklaces: Prices, Models, and Pro Tips
Thinking about buying a pre-owned Van Cleef & Arpels necklace? Discover current resale prices for popular Alhambra models, essential authentication tips, and what to look for regarding chain lengths and gemstone conditions.