lowdb가 업데이트 되면서 기존에 있던 예제들이 다 오류가 나서 ,, 이왕 하는 거 정리해보는 JSON Server로 Custom Routing하기.
나는 pnpm으로 패키지를 관리해줄 예정. 본인이 쓰는 패키지 매니저로 설치하면 된다.
Package 설치
pnpm add json-server lowdb
그리고 package.json을 설정해준다.
package.json
"type": "module", "start": "nodemon server.js"
server.js를 생성해주고 다음과 같이 적어준다.
server.js
/** JSON Server */ import jsonServer from 'json-server'; /** Lowdb */ import { Low } from 'lowdb'; import { JSONFile } from 'lowdb/node'; const server = jsonServer.create(); const middlewares = jsonServer.defaults(); server.use(middlewares); const db = new Low(new JSONFile('db.json'), {}); /** Custom Routing */ server.get('/members', (req, res) => { res.send(db.get('members').value()); }); const router = jsonServer.router('db.json'); server.use(router); server.listen(3001, () => { console.log('JSON Server is running'); });
Custom Routing이라고 주석처리 된 부분부터 본인이 원하는 라우팅을 지정해주면 된다.
+) 커스텀 라우팅을 지정해줘도, 기본 CRUD는 지원하므로 추가적인 라우팅만 만들어주면 된다.
Request Body를 얻으려면 body parser가 필요하다. 아래의 코드를 추가해주자.
server.use(jsonServer.bodyParser);
controller를 분리하고 싶었는데 JSON Server는 Router 클래스를 따로 제공하진 않더라. 이것저것 시도해보다가 찾아낸 게 ._router 객체였는데, 여기에서 직접 get, post, ~ 등을 붙여주고 use로 연결해주면 되긴 하더라. 그래서 server 인스턴스를 모듈로 따로 관리하고 받아와서 쓰는 느낌으로 구현을 했는데,,, 이상하게 중간에 불러오면 ._router 객체가 undefined로 나오더라. 그래서 그냥 받아와서 쓰기로 했다.
먼저 분리하고 싶은 endpoint로 js 파일을 만들어주고 다음과 같이 적는다.
Routes/members.js
export const getMembersRoute = (router) => { router.post('/members/check/email', (req, res) => { return res.status(200).send({ hasEmail: hasEmail(req.body.email) }); }); return router; };
그리고 server.js에서 다음과 같이 써주면 끝!
server.js
import { getMembersRoute } from './Routes/members.js'; server.use('/members', getMembersRoute(server._router)); server.use(router);
물론 router 앞에서 써줘야 한다.
그런데 이렇게 분리하면 db를 이용한 코드를 중복해서 적어야 한다. DB 관련 로직을 따로 묶어주려면 다음과 같이 해보자.
DB/index.js
/** Lowdb */ import { JSONPreset } from 'lowdb/node'; const defaultData = { members: [ { id: 0, email: '', password: '', nickname: '', }, ], }; const db = await JSONPreset('db.json', defaultData); export const findUser = (target) => db.data.members.find(({ email }) => email === target); export const hasEmail = (target) => !!findUser(target); export const hasNickname = (target) => !!db.data.members.find(({ nickname }) => nickname === target);
그리고 나서 db조작이 필요한 곳에서 쓰면 호출하면 된다.