저번에 코드 리뷰를 한다고 했는데 챕터 5 강의를 다 듣고 ㅋㅋ 너무 바뀌어서 그거에 대한 정리를 해보려고 한다
일단 원래 posts를 main에 담았었는데 이걸 파일로 통째로 빼서 관리를 하는걸로 바뀌었다 내가봐도 이게 나은듯
그럼 지금부터 main.js와 api.js에 대한 리뷰를 해보겠다
언제나 그랬듯이 다시 한번 적어보면서 스스로 생각해보고 적어볼거다.
강의를 들으면 생각할 시간이 적어지기 때문에 천천히 블로그 정리하면서 끄적거려보자
// @ts-check
/**
* @typedef Post
* @property {string} id
* @property {string} title
* @property {string} content
*/
/**
* @typedef APIResponse
* @property {number} statusCode
* @property {string | Object } body
*/
/**
* @typedef Route
* @property {RegExp } url
* @property {'GET' | 'POST' } method
* @property {(matches: string[], body: Object.<string, *> | undefined ) => Promise<APIResponse>} callback
*/
const fs =require("fs")
const DB_JSON_FILENAME = 'database.json'
/** @returns {Promise<Post[]>} */
async function getPosts(){
const json = await fs.promises.readFile(DB_JSON_FILENAME, 'utf-8')
return JSON.parse(json).posts
}
/** @param {Post[]} posts */
async function savePosts(posts) {
const content = {
posts,
}
return fs.promises.writeFile(DB_JSON_FILENAME, JSON.stringify(content), 'utf-8')
}
/** @type {Route[]} */
const routes = [
{
url: /^\/posts$/,
method: 'GET',
callback: async () => {
statusCode: 200,
body: await getPosts()
}
},
{
url: /^\/posts\/([a-zA-Z0-9-_]+)$/,
method: 'GET',
callback: async (matches) => {
const postId =matches[1]
if(!postId){
return {
statusCode: 404,
body: 'NotFound!'
}
}
const posts = await getPosts()
const post = posts.find(_post => _post.id === postId)
if(!post){
return {
statusCode: 404,
body: 'NotFound!'
}
}
return {
statusCode: 200,
body: post
}
},
},
{
url: /^\/posts$/,
method: 'POST',
callback: async (_, body) => {
if(!body){
return {
statusCode: 400,
body: 'NotFound'
}
}
/** @type {string} */
/* eslint-disable-nex-line prefer-destructuring */
const title = body.title
const newPost = {
id: title.replace(/\s/g, '_'),
title,
content: body.content
}
const posts = await getPosts()
posts.push(newPost)
savePosts(post)
return {
statusCode: 200,
body: newPost
}
}
}
]
module.exports = {
routes,
}
언제나 그랬듯이 @ts-check로 타입을 엄격하게 정해준다
이번에 적으면서 확실하게 알게 된건데 @typedef가 틀이고 @property가 그 안에
필수로 적은 타입에 맞게 정확하게 적혀있어야하는 애들이다
@propery중에 RegExp는 정규식을 뜻한다!
cosnt fs = requires("fs")로 밖에 있는 database.json을 읽고 쓸 수가 있게 되었다.
getPosts
await fs.promises.readFile(DB_JSON_FILENAME, 'utf-8')
savePosts
return fs.promises.writeFile(DB_JSON_FILENAME, JSON.stringify(content), 'utf-8')
전체적인 post들을 볼 수 있는 posts의 경우
callback부분에 body를 await getPosts()로 가져와서 보여준다!
하나의 post를 볼 수 있는 post의 경우
callback에서 matches라고 해서 내가 적은 post를 가져온다
그리고 postId의 경우 matches[1]인데 이게 이유가 있다
post를 가져오게 되면 id가 배열의 1번째 위치에 있어서...
find로 postId와 _posts.id가 같은지 보고 같으면 post를 통째로 출력한다ㅎ
마지막은 post를 적어보는건데 이거 은근 간단하다.
callback에서 body를 받는데 body는 내가 틀에 맞게 적은거
그래서 newPost에 다가 정제해서 넣는다 -> 그리고 posts에 push
추가로 정보를 새로고침해도 나올 수 있게 savePosts를 써서 database.json에 저장한다!!
흐름을 이해한다고 하긴했지만 정규식 부분, 그리고 실제 동기화를 언제 해야하는지 등 아직은 미흡하다 더 차근차근 해보면서 서버-클라이언트 관계를 이해해보려고 한다