🐰 엘리스 SW 6기 1차 프로젝트 쇼핑몰 사이트 만들기 회고 (3) - 프로젝트 진행 2주차 (+ 발표)
이전 글
🐰 엘리스 SW 6기 1차 프로젝트 쇼핑몰 사이트 만들기 회고 (2) - 프로젝트 진행 1주차 (tistory.com)
🐰 엘리스 SW 6기 1차 프로젝트 쇼핑몰 사이트 만들기 회고 (2) - 프로젝트 진행 1주차
이전 글 🐰 엘리스 SW 6기 1차 프로젝트 쇼핑몰 사이트 만들기 회고 (1) - 프로젝트 시작 전 (tistory.com) 🐰 엘리스 SW 6기 1차 프로젝트 쇼핑몰 사이트 만들기 회고 (1) - 프로젝트 시작 전 조금(?) 늦
developingdiaryoflily.tistory.com
1차 프로젝트 진행 마지막 주인 2주차 회고를 해 보겠다!
1️⃣ API 연결하기
2주차부터는 백엔드가 만들어 놓은 API를 연결하는 작업을 시작하였다.
프론트 분들께 API 문서를 공유해 드리면서 API에 대해 궁금한 점이 생기면 해당 API를 만든 사람을 찾아가 물어볼 수 있도록 하였다.
API 연결을 하면서 다양한 문제가 발생했었는데, 기억에 남는 문제나 오류는 다음과 같다.
❗ mongoDB 연결 문제
프론트에서 통신 코드를 작성 후 DB에 제대로 반영되는지를 확인하기 위해서 mongoDB에 접근이 가능해야 했다. 처음에는 각자 mongoDB로 실행했는데, 어떤 분은 연결이 잘 되고, 어떤 분은 연결이 잘 안되는 문제가 발생하였다.
결국 모든 IP 허용 설정을 하고, 하나의 mongoDB url에 연결하여 진행하였다.
나중에 지적받은 부분이기는 하지만, 모든 IP에서의 접근 허용을 설정하게 되면 보안상의 문제가 있을 수 있기 때문에, 안전하게 진행하기 위해서는 앞으로 접근을 허용하고 싶은 IP만 등록하여 사용해야겠다는 생각이 들었다.
❗ TypeError: Converting circular structure to JSON
위 에러는 내가 작성한 백엔드 코드에서 발생한 오류였다.
회원 주문 조회를 위해 해당 회원이 주문한 내역을 불러와야 했는데 그 과정에서 오류가 발생하였다.
postman으로 회원 주문 조회 api 실행 시 데이터가 잘 받아져와서 처음에는 백엔드 코드에는 문제가 없는 것으로 생각을 했었는데 결론적으로는 내가 작성한 백엔드 코드가 문제였었다.
결과가 {orderData: [주문 데이터 객체들......]} 이런 형식으로 나가야지 정상인데, 객체 안에 바로 배열을 넣어서 반환시켜 버리는 바람에 클라이언트에 데이터가 제대로 전달되지 않았던 것이다.
이것 때문에 한두시간 정도 시간을 잡아먹었던 기억이 난다🥲
이 오류를 통해 오류가 발생했을 때는 항상 모든 가능성을 살펴보는 것이 좋겠다는 깨달음을 얻을 수 있었다 😂오류가 잘 해결되지 않을 경우 항상 내가 작성한 코드부터 다시 확인을 해보는 습관을 가져야겠다고 다짐했다....!
❗ SyntaxError: Unexpected token < in JSON ...
이 부분은 다른 분이 맡으신 파트에서 오류 잡기를 도와드리다가 발견한 에러이다.
이 에러가 발생한 이유는 백엔드에서 응답을 res.send 메서드를 사용하여 객체를 JSON 형태로 변환한 형태가 아닌 문자열 자체를 전달해 주었는데, 이를 프론트에서 fetch(url).then(res => res.json()).... 이런 식으로 문자열 데이터를 JSON 파싱을 시도하였기 때문에 발생하였다.
백엔드에서는 응답 형식을 JSON으로 통일하거나, 프론트엔드에게 반환되는 데이터 형식에 대한 명확한 안내를 해드렸으면 더 좋았겠다는 생각이 들었다!
오류를 회고하면서 드는 생각인데, 앞으로 새 프로젝트를 진행할 때에는 에러가 발생할 시 기록하는 습관을 들여야겠다고 느꼈다. 그렇게 하면 에러나 버그를 통해 구현에 어려움을 느꼈었던 부분을 다시 되짚어 볼 수 있고, 나중에 비슷한 오류가 발생하였을 때 빠르게 해결할 수 있을 거 같다! 😊
2️⃣ viewRouter 파일 작성
본격적으로 프론트 js 코드 작성에 들어가면서 URL에 따라 그에 맞는 화면을 보여주어야 했다.
처음에는 어떻게 화면을 제공해 주어야 하는지 갈피를 잘 잡지 못했고, 아예 viewRouter를 정의해야 하는 사실조차 인지하지 못하고 있었다.
서칭과 오피스타임에서의 코치님들의 조언을 바탕으로 viewRouter 파일을 작성하였다.
<src/routers/viewRouter.js>
import express from "express";
import path from "path";
const viewsRouter = express.Router();
viewsRouter.use("/", express.static(path.join(process.cwd(), "src/views")));
// 홈페이지
viewsRouter.get("/", (req, res) => {
res.sendFile(path.join(process.cwd(), "src", "views", "public", "main.html"));
});
// About 페이지
viewsRouter.get("/about", (req, res) => {
res.sendFile(
path.join(process.cwd(), "src", "views", "public", "about.html")
);
});
// 장바구니 페이지
viewsRouter.get("/cart", (req, res) => {
res.sendFile(path.join(process.cwd(), "src", "views", "cart", "cart.html"));
});
..........
export { viewsRouter };
프론트에서 어떠한 URL로 접근하려 할 시 그 URL이 요청 경로가 되고, viewRouter에서 해당 경로와 매치되는 HTML 파일을 res.sendFile 메서드를 통해 응답으로 보내주는 역할을 하는 파일이다.
viewsRouter.use("/", express.static(path.join(process.cwd(), "src/views"))); 코드는 '/' 경로로 들어오는 모든 요청에 대하여 express.static 미들웨어를 사용해 정적 파일을 제공해 준다.
process.cwd()와 src/views는 각각 node.js 프로세스가 시작된 디렉토리와 정적 파일들이 위치한 디렉토리를 나타낸다.
위 코드는 src/views와 같은 JS와 CSS 같은 정적 파일을 제공하기 위해 작성한 코드이다. 요청이 들어가는 모든 경로에서 JS 파일과 CSS 파일을 제공해 주어야 하므로 라우터 경로는 '/'가 된다.
res.sendFile로 전달해 주는 파일은 클라이언트가 접근하려고 하는 URL에 따라 매치가 되는 정적인 HTML 파일이다. 위 코드에 의해 해당 HTML 파일에서 사용하는 CSS와 JS 파일이 같이 바인딩되어 나올 수 있게 된다.
3️⃣ 프론트 코드 작성 및 웹사이트 테스트
2주차에서의 백엔드 역할은 주로 API 관련하여 질문을 받거나 통신 시 에러가 발생하면 그것을 수정하고, 웹사이트 테스트를 해보는 것이었다. 그래서 1주차에 비해서 시간이 좀 남아서 나의 경우에는 프론트 분들을 도와 프론트 코드를 작성하였다.
그렇게 하여 내가 맡게 된 업무는 로그인, 회원가입, 주문창에 주문할 상품 목록들 띄우기 js 코드 작성과 비회원 주문조회 페이지와 관리자 배송상태 관리 페이지 전체 제작, 다른 파일에서의 자잘한 오류들이나 개선할 부분 고치기 정도가 되었다.
구현 방법에 관해서는 다른 글에서 자세하게 다루어 볼 예정이다!
이미 다른 분들이 작성해 놓은 파일에 내 코드를 더하는 경험을 처음 해볼 수 있어서 좋았다.
내가 부트캠프를 통해 얻고 싶었던 것 중 하나가 다른 사람이 작성한 코드를 해석하는 능력인데 프론트 코드를 짜면서 다른 분이 작성해 놓은 코드들을 많이 접할 수 있었고, 이미 어느 정도 만들어 놓은 로직에 맞추어서 코드를 더하는 경험이 새로웠다.
또한, 주문 관리 페이지나 비회원 주문조회 페이지 같은 경우는 처음부터 만들었어야 했는데 2가지 경험을 모두 해볼 수 있어서 의미있었다! 😊
또한 다른 분들의 버그나 오류를 잡는 데 성공했을 때에는 뿌듯함을 느낄 수 있었다. 팀장이라는 직책의 무게(?)가 있었어서 그런지 프론트 작업에도 백엔드 작업할 때 만큼 열정적으로 임했던 거 같다!
4️⃣ 구현에서 제외할 기능 선정하기
프로젝트 마감일이 다가오고 있는 상황에서는 구현에서 제외할 기능을 선정하였다.
필수 기능 중에서는 관리자가 상품 데이터를 CRUD 할 수 있는 기능과 카테고리를 CRUD 할 수 있는 기능, 우리가 추가해서 구현하려 했던 기능 중에서는 상품 검색 기능을 빼고 가기로 하였다.
여기에서 아쉬웠던 점은 백엔드에서 배포를 맡아주셨던 분이 관리자 관련 API를 제작하셨는데 이를 제대로 써보지 못하고 프로젝트가 종료되었다는 점이다.
내가 좀 더 경험치가 많았다면 다른 작업을 더 빨리 끝내고 나서 도와드릴 수 있지 않았을까 하는 아쉬움도 있다.
5️⃣ 발표 자료 준비
프로젝트 마지막 날인 2주차 금요일에는 프론트엔드는 버그 수정과 기능 마무리하기를 맡았고, 백엔드가 발표 자료 준비를 맡았다.
주요 내용으로는 인프라 구조, 프로젝트 진행 과정의 큰 틀, 프로젝트 기능들, 트러블 슈팅, 느낀점을 적었다.
발표는 다음 날인 토요일에 이루어졌고, 내가 발표를 맡게 되었다!
발표를 마치고 나면 코치님들의 질문이 이어진다.
내가 받았던 질문과 지적은
➡️ Nginx를 사용한 이유가 따로 있는지?
➡️ innerHTML 보안 이슈
➡️ mongoDB 모든 아이피 접근 허용 시의 보안 이슈와 유저의 주소를 그대로 저장할 시의 보안 이슈
➡️ JWT 토큰에 대하여 설명해 보아라.
정도가 있었다.
이러한 질문들을 받으면서 프로젝트 완성에만 집중하느라 보안과 관련된 부분에서는 신경을 잘 쓰지 못했던 거 같고, 내가 사용한 기술들에 대한 이해도가 충분하지 않았음을 느낄 수 있었다.
코드를 작성할 때나 어떠한 기술을 적용할 때 왜 이렇게 코드를 작성하였는지, 왜 이 기술을 적용하였는지 생각하고 넘어가는 습관을 지녀야겠다는 생각이 들었다.
이렇게 1차 프로젝트 진행 과정에 대한 전체적인 회고는 끝이다❗
글을 적으면서 커밋 내역, 코드 내용, 디스코드에서의 소통 내용을 다시 살펴보았는데 1차 프로젝트에서는 모르는게 많아서 어리바리했었던 상황도 꽤 있었지만 정말 최선을 다했고, 내가 2주 안에 정말 많은 것들을 했구나를 느낄 수 있었다.
앞으로 리팩토링을 진행하면서 기능 구현 방법에 대해서도 기록해볼 생각이다!