2023. 12. 21. 04:04ㆍ프론트엔드/Next.js
이전 포스팅에서 어떻게 진행할 지 알아보았다.
( https://aboveimagine.tistory.com/128 )
이제 코드를 작성해볼 차례!
물론 내 코드가 절대 정답은 아닐 것이므로
개선해야할 부분이 있다면 댓글로 알려주시길 🙏🏻
마크다운 파일의 메타데이터 관리
Front matter
내 로컬 환경의 마크다운 파일을 이용하여 블로그를 만들려면
해당 마크다운 파일에 대한 상세 정보가 필요하다.
즉, 제목, 작성일, 카테고리 등등의 정보를 미리 마크다운 파일 상단에 작성해주면 된다.
이렇게 마크다운(markdown) 파일이나 다른 텍스트 기반 파일의 상단에 위치하며, 해당 파일에 대한 메타데이터(metadata)를 정의하는 부분을 Front matter 라고 한다.
---
title: '제목'
date: '2023-12-10'
---
gray-matter
gray-matter 라이브러리를 이용하면 작성한 front matter를 객체 형태로 바꿔줄 수 있다.
---
title: Hello
slug: home
---
<h1>Hello world!</h1>
{
content: '<h1>Hello world!</h1>',
data: {
title: 'Hello',
slug: 'home'
}
}
설치
$ npm install --save gray-matter
사용
import matter from "gray-matter";
console.log(matter('---\ntitle: Front Matter\n---\nThis is content.'));
// 결과
{
content: 'This is content.',
data: {
title: 'Front Matter'
}
}
서비스 로직 구성
다음은 파일 시스템을 이용해 마크다운 파일을 읽고 쓰는 함수를 만들어야 한다.
브라우저에서는 직접적으로 파일 시스템에 접근할 수 있는 권한이 없다.
따라서 서버사이드에서 Node.js의 fs 모듈을 이용해야 한다.
서비스 로직 종류
src/service/posts.ts
안에 서비스 로직을 구성한다. (CRUD)
fsGetPostsList()
: 전체 md 파일 조회fsGetPostDetail()
: 특정 md 파일 상세 조회fsCreatePost()
: md 파일 생성fsUpdatePost()
: md 파일 수정fsDeletePost()
: md 파일 삭제
나중에 프론트 쪽 함수와 헷갈릴 것 같아서 fs로 시작하게끔 함수명을 정했다.
그리고 fs 모듈의 함수인 readdir()
, readFile()
, writeFile()
, unlink()
등을 이용하여 로직을 작성했다.
일례로 전체 파일 조회 코드만 살펴보면 아래와 같다.
import path from "path";
import { promises as fs } from "fs";
import matter from "gray-matter";
import { NewPost, Post, ApiResponse } from "@/types/post";
const postsDirectory = path.join(process.cwd(), "public/posts");
export async function fsGetPostsList(): Promise<ApiResponse<Post[]>> {
try {
const fileNames = await fs.readdir(postsDirectory);
const postsList = await Promise.all(
fileNames.map(async (fileName) => {
// Remove ".md" from file name to get id
const id = fileName.replace(/\.md$/, "");
// Read markdown file as string
const fullPath = path.join(postsDirectory, fileName);
const fileContents = await fs.readFile(fullPath, "utf8"); // 비동기 메서드로 변경
const matterResult = matter(fileContents);
const result = { id, ...matterResult.data };
return result as unknown as Post;
})
);
return { success: true, data: postsList };
} catch (error) {
return { success: false, error: `Error reading posts list: ${error}` };
}
}
이런 방식으로 위의 CRUD 로직들을 작성해보았다.
이 함수들의 return 값은 response에 해당하므로,
success
(성공 실패 여부), data
(성공 시 해당 데이터), error
(실패 시 에러 메세지)로 이루어진 객체를 리턴하게끔 했다.
이렇게 작업을 하고보니 결국은 이게 일반적으로 백엔드 서버에서 하는 역할이고,
내 로컬 파일이 DB겠구나 하는 감이 이제야 왔다.
그럼 이제 이 요청을 전달할 API는 다음 편에서 계속 🫡
'프론트엔드 > Next.js' 카테고리의 다른 글
[Next.js 13] 풀스택으로 블로그 만들기 0. 프로세스와 용어 이해하기 (컨트롤러, 서비스, 서비스로직..) (1) | 2023.11.30 |
---|---|
[Next.js] i18n/ i18next 국제화 작업/ 다국어 지원 페이지 만들기/ with 리액트, 타입스크립트 (0) | 2022.12.09 |
[Next.js] 리액트의 프레임워크 Next.js를 알아보자. (0) | 2022.11.30 |
[Next.js] Image 컴포넌트 外 업데이트 (Next 13) (1) | 2022.11.28 |