그럼 토이프로젝트 Dwitter에도 간단하게 유효성 검사를 적용해보자 👍
/server/router/tweets.js
// 외부에서 가져온 미들웨어 먼저 선언 import express from "express"; import "express-async-errors"; import { body } from "express-validator"; // 내부에서 필요한 js 임포트 import * as tweetController from "../controller/tweet.js"; import { validate } from "../middleware/validator.js"; const router = express.Router(); // validation const validateTweet = [ body("text") .trim() // 공백 제거 .isLength({ min: 3 }) .withMessage("text should be at least 3 characters."), validate, ]; // GET /tweets // GET /tweets?username=:username router.get("/", tweetController.getTweets); // GET /tweets/:id router.get("/:id", tweetController.getTweet); // POST /tweeets router.post("/", validateTweet, tweetController.createTweet); // PUT /tweets/:id router.put("/:id", validateTweet, tweetController.updateTweet); // DELETE /tweets/:id router.delete("/:id", tweetController.deleteTweet); export default router;
/server/middleware/validator.js
import { body, validationResult } from "express-validator"; export const validate = (req, res, next) => { const errors = validationResult(req); if (errors.isEmpty()) { return next; } return res.status(400).json({ message: errors.array()[0].msg }); };
컨트롤러에서는 비즈니스 로직만을 갖고 있는게 좋고, 디펜던시를 가지고 있는 것은 좋지않으므로 라우터에서 처리하는 것이 좋다.
또한 여러 라우터를 가지고 있을 수 있으므로, 중복성 제거를 위하여 validator는 따로 경로를 만들어 필요한 라우터에서 import 하여 사용하는 것이 좋다.
중요한 포인트 ✏️
- 데이터베이스에 접근해서 읽고 쓰기 전에, 서버의 최대한 앞단에서 validation 체크를 하는 것이 좋다.
- validation 과 sanitization 을 통해 데이터를 일관성있게 보관한다.
- 컨트롤러에서는 프로젝트의 비즈니스 로직을 담고 있으므로,
- 클라이언트 <> 서버간 데이터 송수신 테스트 방법
- Contract Testing
- Client와 Server간에 api 통신을 할때, 어떻게 서로 규격을 잘 맞춰가는지 테스트하는 방법
- Contract Testing