프로젝트는 시리즈에 정리한 것 처럼 매일 아침 스크럼을 통해 개발 일정을 조율해가고, 추가할 기능에 대해 토론을 하며 진행했다.
Gitlab을 통해 협업을 진행하였고, 자신의 개발 정도와 목표 등에 대해 이슈와 마일스톤으로 관리를 했었다.
검색 기능은 Mongoose ODM을 사용하여 사용자의 이름, 기술 스택에서 검색어가 존재하는지 정규표현식을 통해 대소문자 구분 없이 검색이 가능하게 하였다.
이때 검색을 진행할 때 쿼리가 여러개 가는것을 막고 한번에 검색 가능하게 만들기 위해 $or operator 또한 사용해주었다.
이미지 업로드 기능은 Multer를 사용하여 구현하였다.
DB에는 Multer의 diskStroage로 현재 시간과 파일 이름을 합쳐 커스터마이징한 사진 이름을 저장한 후, images 폴더에 실제 사진 데이터를 저장하게 만들었다.
이때 배포 환경과 개발환경의 환경 변수 [이미지 폴더 경로 ]를 다르게 설정하기 위해 env 파일에서 경로를 불러온다.
비밀번호 찾기 기능은nodemailer
모듈을 사용하여 구현하였다.
요청이 들어올 때, 올바른 값을 가지고 있는지에 대한 검증을 위한 검증 미들웨어를 만들었다.
function checkProjectCreated(req, res, next) { const fields = ["title", "description", "from", "to"]; const body = Object.keys(req.body); const check = fields.filter((field) => !body.includes(field)); if (check.length) { return res.status(400).json({ success: false, error: { code: 400, message: `${check.join(", ")} 은(는) 필수로 입력해줘야 합니다.`, }, }); } next(); }
초기엔 위와 같이 직접 request안의 body나 query, parameter 등을 검증하는 validator를 만들었지만, 이후 더 쉽고, 직관성있게 검증 미들웨어를 만들 수 있도록 해주는
express-validator
를 알게되어 코드를 변경하였다.const validate = (req, res, next) => { const errors = validationResult(req); if (errors.isEmpty()) { return next(); } return res.status(400).json({ success: false, error: { code: 400, message: errors.array()[0].msg, detail: errors.errors, }, }); }; const checkUserCreated = [ body("name") .exists() .withMessage("이름을 입력해주세요.") .bail() .isLength({ min: 2 }) .withMessage("이름은 필수로 2 글자 이상 입력해야 합니다!") .bail(), body("email") .exists() .withMessage("이메일을 입력해주세요.") .bail() .isEmail() .withMessage("올바른 이메일을 입력해주세요.") .bail(), body("password") .exists() .withMessage("비밀번호를 입력해주세요.") .bail() .isLength({ min: 4 }) .withMessage("비밀번호는 4글자 이상이어야 합니다."), validate, ];
변경 후 코드는 위 코드와 같다.
딱 봤을 때 코드 길이가 줄어들지 않아서 어디가 간편하고 좋은지 모를 수 있지만 딱 코드만 보고도 어느 값이 필수 값인지, 어느 값에는 어떤 조건을 통과해야하는지에 대한 것들이 한 눈에 보이기 때문에 직관적으로 검증 로직에 대해 알 수 있다는 장점이 있어 유용하게 사용해야겠다고 생각했던 경험이였다!
경력 부분 구현에 있어서는 다른곳에서 구현한 것과 다른것이 없었다.
다만Mongoose ODM
의populate
와sort
를 가장 적절하게 사용한 부분이라 소개에 넣었다.static async findAll({ userId }) { const user = await UserModel.findOne({ id: userId }); const careers = await CareerModel.find( { author: user }, { _id: false, __v: false } ).populate('author', 'id -_id').sort({ fromDate: 1, toDate: 1 }); return careers; }
Mongoose
에서sort
를 구현하기 위해서 위 처럼sort
에1
또는0
의 값을 넣어주면 된다.
위 코드처럼1
을 넣어주게 될 경우에는 오름차 순으로 정렬하게 된다.
위의 기능들 말고도 여러가지 기능을 열심히 구현했지만 소개할 정도의 기능은 아니라 여기까지만 넣어놨다!
만약 다른 부분의 코드가 궁금하거나 완성했을 때 어떻게 작동하는지가 궁금하다면
https://github.com/Shin-GC/OurPortfolioServiceProject.git
위 주소의github
레포지토리를 참고하시면 됩니다!
신광천
Back
소통과 구조가 중요하다고 생각하게된 프로젝트였어요!
확실히 일을 시작하기전 아침마다 스크럼을 통해 각자 진행정도에 맞춰서 진행하고, 기능 추가 여부를 확인해서 추가를 하자고 한건 다 성공할 수 있었던 것 같고, 데이터 구조 부분은 몇번이나 수정을 했었는데 딱 구조를 정해뒀으면 프론트 팀원분들이 수정하는 고생을 덜 할 수 있고, 저희 코드 수정도 최소화 할 수 있어 기능을 하나라도 더 추가할 수 있지 않을까 라는 아쉬움이 있어서 이 두가지가 이 프로젝트를 진행하면서 가장 중요하게 느꼈던 것 같아요 🙂
백**
Front
제가 생각하는 제일 중요한 것은 애정이라고 생각합니다! 프로젝트에 대한 애정이 있어야 이것저것 할 욕구도 생기고 각자 맡은 부분에 대한 자신감도 생기기 때문에 더 좋은 아이디어들이 추가된 프로젝트가 만들어질 수 있다고 생각합니다. 그래서 이번 저희 프로젝트 진행이 잘 이루어지지 않았나 싶습니다! 다들 이번 프로젝트에 대한 애정이 많으셔서 공통된 목표에 각자 아이디어들을 덧붙이니까 너무 좋은 결과물이 나왔어요!!
박**
Front
협업에서 중요한것은 소통인것 같습니다
- 혼자 문제를 끌어 안기보단 팀원들과 함께 문제를 풀어나가는게 중요하다 생각합니다 (효율성, 다양한 시각의 해결법을 배움)
- 하나의 작품을 만들기 위해, 개발 스타일을 통일 시킬 때에도 충분한 소통이 중요하다 생각합니다
김**
back
제가 하고 싶은 말이 다 나와버려서 쓸 게 없긴 하지만, 저는 믿음이 중요하다고 생각했습니다. 내가 만든 기능을 프론트쪽에서 잘 구현해주실거라는 믿음, 내가 맡은 일을 잘 해낼 수 있을 거라는 자신감, 다섯 명이 모이면 뭐든지 할 수 있을거라는 믿음이 모여서 프로젝트를 진행하면서 이것저것 과감하게 도전할 수 있는 원동력이 되었다고 생각해요