지금까지 개발을 하면서 꼭 해보고 싶었던 것이 바로 직접 기술 블로그를 만드는 일이었다. (매우 멋져...!)
Tistory 나 벨로그처럼 이미 만들어진 서비스가 확실히 사용하기도 편하고 또 노출도 많이 되지만,
실제로 내가 운영을 하면서 꾸준히 유지보수를 할만한 프로덕트를 하나 만들고 싶었다.
내가 제일 좋아하고 자주 하는게 기록 남기는 일이기도 하니까, 그러면 블로그가 딱 적당하다고 생각해 진행하게 되었다.
기술 스택 선정
Next.js
먼저 SEO에 유리한 Next.js 를 사용하기로 했다. 하꼬 블로그지만 많이 노출이 되면 좋은거니까..!
그리고 이번에 Notion API를 연동하면서 알았는데, Next.js 에서 제공하는 api 디렉토리를 통해 엔드포인트를 만들 수 있어서 유용하게 쓸 수 있었다. 그리고 이번에 도입을 하면서 새롭게 알게된 사실인데, Next13 버전에서 기존에 getStaticProps 나 getServerSideProps 같은 함수를 Fetch API 의 옵션으로 대체해 더 간편하게 데이터 가져오기를 할 수 있다고 한다.
Notion API
왜 노션 API를 도입하려고 하느냐?
일단 글을 마크다운으로 작성하기가 매우 싫었기 때문이다.
직접 기술 블로그를 만드신 다른 분들의 글을 참고해보면, 마크다운으로 작성한 글을 정적으로 빌드해 보여주는 SSG 방식을 많이들 적용하는 듯 하다. 그런데 벨로그 대신 티스토리를 사용하는 이유도 마크다운으로 글을 적는게 싫어서였기 때문에 다른 방법을 찾아야 했다.
처음에는 아예 DB도 연동하고 백엔드단을 직접 만들어볼까?! 라고 생각해봤는데 경험이 없어 시간이 오래걸리기 때문에 (퀄리티도 보장 못함 ㅋㅋ), Notion에서 제공하는 API를 사용하기로 결정했다. 노션을 통해 작성된 글을 관리하고 수정하는 것도 편리하게 할 수 있기 때문에 여러모로 괜찮은 선택이라고 생각한다.
Tailwind CSS
한 번 테일윈드를 접하고나니 특별한 다른 이유가 없는 이상 계속 사용하게 되는 것 같다. 사실 실무에서 Tailwind CSS를 쓰는 회사를 거의 보지 못했는데, 일단 개인 프로젝트에는 빠르게 적용할 수 있기 때문에 굳이 쓰지 않아야 할 이유를 잘 모르겠다. 아무래도 코드 가독성이 너무 떨어지다보니 협업시에는 Styled-components 보다 사용성이 떨어질 수도 있겠단 생각이 드는군. 스타일 재사용 문제도 그렇고. 일단 나 혼자 하는 프로젝트니까 큰 문제 없다고 생각함!
전역 상태관리 도구
사실 페이지도 몇개 없고 규모도 작아서 전역 상태관리 도구가 필요할까? 라는 생각.
만약 필요하게 된다면 이번에는 Zustand 를 도입해볼까 한다. 크기도 가볍고 사용 방식이 Redux와 비슷하다고 해서 쉽게 적응할 수 있지 않을까 싶다.
Notion API 연동하기
API 연동을 위해서는 Notion 의 API 통합 페이지에서 통합 키를 발급받아야 한다.
그리고 글을 작성할 노션 DB를 생성한다. DB 생성 후 DB 를 페이지로 오픈하면, 아래 사진과 같이 도메인 바로 다음에 오는 쿼리 파라미터를 볼 수 있는데 이 부분이 DB KEY 에 해당한다.
이 두 키를 환경변수로 잘 등록한 다음에 요청을 보내면 된다.
나같은 경우 처음에는 여러 블로그와 노션 api 공식 문서를 참조해 노션 API 에서 제공하는 SDK 클라이언트를 사용했다.
위와 같이 해당 DB 에 있는 게시글 목록을 불러올 수 있다.
불러온 결과물은 대략 위와 같은데, 정작 필요한 데이터는 properties 항목에 아주 깊숙히 숨어있었기 때문에, 이 데이터를 전부 불러와서 가공을 해주어야 한다는 점이 약간 마음에 걸렸다.
또한 나는 글을 수정하거나 새로 작성했을 때, 새롭게 빌드하는게 아니라 런타임에 데이터를 자동으로 업데이트 하길 원했는데, (이러한 방식을 ISR(클릭시 공식 문서로 이동!) 이라고 한다.) Next13을 적용하면서 데이터를 요청하는 방법이 바뀌었고 이를 위해 GET 메서드로의 요청이 필요했기 때문에 api route를 만들어 서버사이드에서 요청을 하도록 만들기로 했다.
그리하여 변경된 코드는 아래와 같다. 우선 서버사이드에서 Notion API 로 전체 조회 요청을 보내는 request handler 를 아래와 같이 만들었다. 앞에서 서술한 바와 같이 클라이언트에 꼭 필요한 데이터만 보내주고 싶었으므로, 리턴 값을 지정해 보내주고 있다. 이렇게 서버사이드 쪽 코드를 작성하는것은 Next12에서 아주 간단하게만 했었는데, 이번에 13 버전으로 업데이트가 되면서 이쪽 코드에도 변동사항이 있는 것 같다. Chat gpt 에도 아직 업데이트가 안된 내용이라 공식문서를 보고 참고해서 썼다.
// src > app > api > posts > route.ts
import { NextResponse } from 'next/server';
import { database_id } from '../../../constants';
import { PostResp } from '../../../types/NotionTypes';
import { NextApiPostInfoResp } from '../../../types/NextApiTypes';
export async function GET() {
const response = await fetch(
'https://api.notion.com/v1/databases/' + database_id + '/query',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NEXT_PUBLIC_NOTION_KEY}`,
'Content-Type': 'application/json',
'Notion-Version': '2021-08-16',
},
body: JSON.stringify({
sorts: [
{
property: 'published',
direction: 'descending',
},
],
}),
}
);
const { results } = await response.json();
const postsInfo: NextApiPostInfoResp[] = results.map((res: PostResp) => {
return {
id: res.id,
tags: res.properties.Tags.multi_select[0].name,
title: res.properties.title.title[0].text.content,
createdAt: res.created_time,
slug: res.properties.slug.rich_text[0].text.content,
};
});
return NextResponse.json(postsInfo);
}
그러면 이제 클라이언트에서는 위 엔드포인트로 GET 요청을 보내어 블로그 목록을 가져올 수 있다.
// 블로그 목록 가져오기
export const getPosts = async () => {
const response = await fetch(checkEnvironment().concat('/api/posts'));
const data = response.json();
return data;
};
현재는 별도의 cache 나 revalidation 옵션을 넣지 않았는데, 곧 추가하여 업데이트 할 예정이다.
참고로, 이렇게 서버사이드에서 요청을 보내는 것의 장점은 여러가지가 있다. 일단 서버사이드에서 요청을 보내기 때문에 api 키가 노출되지 않는다는 점, 그리고 전체 데이터를 보내주고 클라이언트에서 가공하는게 아니라 한 번 가공되고, 필요하지 않은 데이터를 제거하여 보내기 때문에 클라이언트 측에서 받아야하는 데이터의 크기가 줄어 성능상의 이점이 있다.
또 다른 고려사항으로는 API 요청 횟수 제한이 있다고 gpt 가 알려주었다. 각 클라이언트에서 요청시에는 클라이언트 별로 각각 rate limit을 갖지만 서버에서 요청을 보낼땐 같은 곳에서 요청이 가기 때문에 주의가 필요하다고 하는데, 이를 캐싱 매커니즘을 적용해서 방지할 수 있다고 한다. 서버사이드에서 캐싱은 생각해본적이 없는데 좀 더 알아볼 필요가 있을 듯 하다.
지금까지 조금 어려운 부분은 크게 두 가지이다.
1. Next13 을 사용하는게 낯설음. 근데 공식문서가 워낙 잘 되어있기 때문에 금방 적용할 수 있을 것 같다.
2. 이제 받아온 글의 데이터를 화면에 표시해주어야 하는데, 일반적인 마크다운이나 html 데이터가 아니라서 어떻게 가공을 해야할지 애매한 부분이다.
사실 Notion API + Next.js 블로그를 만들 수 있도록 미리 세팅이 된 오픈 소스도 많다. 그렇기 때문에 이 데이터를 쉽게 가공할 수 있는 오픈 소스가 있지 않을까 라는 생각도 들어서 좀 더 찾아봐야 할 것 같다. 마크다운으로 변환도 가능한 것 같은데 그런 방법을 사용할 수도 있을 것이고..
아무튼 지금까지 만든 블로그는 이렇게 생겼다. Tailwind CSS를 사용해 다크모드와 반응형까지 적용함.
아래 세 개의 최근글이 Notion DB에서 가져와 적용한 내용이다 아하하~
참고하면 좋을 글
아래 화해 블로그에도 자세한 내용이 나와있으니 참고하면 좋을듯.
'프로젝트 > 직접 만드는 기술 블로그' 카테고리의 다른 글
Notion API 를 연동해 블로그를 만들어보자 -2 (0) | 2023.05.21 |
---|