다산다난 했던 첫 백엔드 개발 - 엘리스 AI트랙7기 1차 프로젝트 회고✍

Seung Hyeon ·2023년 6월 29일
1

회고

목록 보기
2/2
post-thumbnail

프로젝트가 끝난지 한달 반만에 쓰는 인생 첫 회고,,
이 포스트는 결과 자랑(자랑할 것도 없지만..)보단 많이 배우고 부족한 점을 찾고 앞으로 뭘 배워야할지 알 수 있었던 엘리스 첫 프로젝트 개발기를 정리한 글이다.

 

🌟 Start

사실 결과가 그리 좋게 나오진 않아(내 기준) 회고를 쓸지 말지 고민했지만.. 이번 프로젝트는 그 어떤 프로젝트보다 다산다난했고 그만큼 배워가는 것도 정말 많았기 때문에 기록하는 것이 좋을 것 같았다.

 

🌟 무슨 프로젝트를 했는데?

포트폴리오 공유 웹 서비스를 제작했다.

개인의 포트폴리오를 직접 제작하고 관리할 수 있는 서비스를 만들었고, 개인이 작성한 포트폴리오를 다른 사람에게 공유할 수 있는 네트워크 페이지도 추가했다.

기본적인 기능이라고 할 수 있는 회원가입 및 로그인, 유저정보 수정, 4개 MVP(Award, Certificate, Education, Project) CRUD, 좋아요 기능만 우선 구현되었다.

 

개발 기간은 2주 정도로 상당히 짧았다. 엘리스에서 약간의 스켈레톤 코드를 제공해주었지만 2주동안 배운 실력으로는 코드를 한번에 이해하는 데 한계가 있었기 때문에 처음 2일 동안은 개발 대신 스켈레톤 코드를 완전히 이해하는 데에 집중했다.

🎈 맡았던 역할은?

백엔드를 맡았다.
프레임워크는 Node, Express를 사용했는데, 많고 많은 것 중 Express를 고른 이유는 간단하다. 바로 엘리스에서 배우고 있는 프레임워크이기 때문.. 사실 다른 프레임워크도 시도해보고 싶었지만 2주라는 짧은 시간에 쌩 초보 백엔드 개발자가 배우지도 않은 언어로 하기란 거의 불가능에 가까웠다. 사용할 DB로 MongoDB를 택한 것도 같은 이유이다.

같은 역할을 맡았던 다른 팀원 모두 백엔드가 처음이었기 때문에 기능을 나눠서 구현하기보단 모여서 모든 기능을 같이 개발하는 방식으로 수행했다.

 

🌟 What I learned

🧩 IA설계, API명세, ERD

개발의 완성도를 높이기 위해서는, 개발 전에 어떤 기능을 구현할 건지, 서비스의 구성은 어떤 식으로 할 건지 등 탄탄한 초기 설계 과정이 필요하다.

  • IA 설계
    웹(또는 앱) 구축 시 필요한 화면과 메뉴를 구조화하고, 사용자가 화면을 마주하기까지 필요한 화면의 흐름을 간단하게 나타내는 과정이다. 각 화면들의 연관성과 웹(또는 앱)의 큰 틀을 한눈에 파악할 수 있어 개발 시 수월할 수 있다.

  • API 명세
    API 명세는 웹서비스의 기능과 데이터에 대한 정확하고 명확한 설명을 제공하기 때문에 API명세서를 작성하면 프론트와 백엔드 간에 API 동작방식을 이해하고 공유할 수 있어 원활한 협업이 가능하다.

  • ERD 작성 (DB설계)
    데이터베이스의 구조를 한눈에 파악하고 데이터의 체계적인 저장과 관리를 위해서, 개발 전 스키마명, 필드명, 형식 등을 미리 기록해놓는 것이 좋다.

🧩 라우터, 미들웨어, 컨트롤러 분리

일단 코드를 분리하지 않았을 때 해당 엔드포인트에 접근하면 어떤 동작이 수행되는지 한눈에 파악이 가능하다.
그러나 기능이 점점 복잡해지면 코드의 유지보수성이 떨어진다.
라우터 안에 있는 미들웨어와 컨트롤러를 따로 분리하여 관리하면, 라우터 요청에 따라 특정 미들웨어 및 컨트롤러의 메서드만 호출하게 되어 코드의 재생산성과 유지보수성이 향상되고 코드 개선과 변경이 용이할 수 있다.

<변경 전>

// certificateRouter.js
certificateRouter.get("/certificates/:id", login_required,  async (req, res, next) => {
          try {
            const certificate_id = req.params.id;
            const getCertificate = await certificateService.getCertificates({
              user_id: certificate_id,
            });
            if (getCertificate.errorMessage) {
              throw new Error(getCertificate.errorMessage);
            }
            return res.status(200).json(getCertificate);
          } catch (error) {
            next(error);
          }
        })
                  
export { certificateRouter };

 

<변경 후>

// certificateRouter.js
certificateRouter.get("/certificates/:id", login_required, getCertificate)   
export { certificateRouter };
// certificateController.js
const GetCertificate = async (req, res, next) => {
  try {
    const certificate_id = req.params.id;
    const getCertificate = await certificateService.getCertificates({
      user_id: certificate_id,
    });
    if (getCertificate.errorMessage) {
      throw new Error(getCertificate.errorMessage);
    }
    return res.status(200).json(getCertificate);
  } catch (error) {
    next(error);
  }
};
export { GetCertificate };

🧩 예약어를 변수명으로 사용하는 행위는 지양 금지

// AwardModel.js
static async delete({ award_id }) {
    const deletedAward = await AwardModel.deleteOne({ id: award_id });
    const isCompleteDeleted = deletedAward.deletedCount === 1;
    return isCompleteDeleted;
  }

위 코드는 수상이력 하나를 삭제하는 함수를 delete 이름으로 정의한 코드이다.
하지만 delete는 자바스크립트의 예약어로 등록되어있기 때문에, 함수 정의 시 해당 이름은 사용을 지양하는 것이 좋다. 금지해야한다.

(예시) delete → deleteById

💡 변수명과 함수명은 알아보기 쉽게!

class Award {
  static async create({ newAward }) {
    const createdNewAward = AwardModel.create(newAward);
    return createdNewAward;
  }
  .....
  
class Certificate {
  static async create({ newCertificate }) {
    const createdNewCertificate = CertificateModel.create(newCertificate);
    return createdNewCertificate;
  }
  .....

위 코드는 각각 수상이력과 자격증이력을 추가하는 함수를 정의한 코드이다. 둘 다 create라는 이름으로 정의되어있고, 코드를 작성한 본인은 두 함수를 구분할 수 있지만 다른 사람은 구분하지 못할 수도 있다. 따라서 다른 사람들도 알아보기 쉬운 이름으로 정의하는 것이 좋다.

(예시) create → createAward / createCertificate

🧩 Communication의 중요성

지금까지 해왔던 다른 프로젝트에서는 정해진 시간에만 만나 각자 한 것들을 공유하고 앞으로 할 것들을 의논하는, 이른바 비즈니스 소통(?)을 주로 해왔다면, 이번 프로젝트는 프로젝트 시작부터 끝까지 하루종일 화상회의를 하며 자유로운 분위기 속에서 함께 개발을 진행했다.
원활한 진행을 위해 잠깐 몇시간 동안은 프론트 엔드와 백엔드 팀으로 나눠서 소통했고, 그 이후는 함께 모여 프론트/백 연동 시 발생하는 에러를 함께 해결하고, 다음 과제를 의논했다.
이런 방식으로 소중한 팀원들과 2주동안 프로젝트를 진행하면서, 자연스레 체득한 것이 많다.

  • 모르는 것은 함께
    웹 서비스 개발 경험이 아얘 없는, 0부터 시작하는 사람들끼리 팀이 구성되었기 때문에 각자 역할을 나눠서 진행해봤자 진도를 나가지 못할 것 같았다.
    기능 구현 시 어디서부터 시작해야할지, 어떤 스택을 사용할지, 에러가 났을 땐 어떻게 해결해야할지 구글링 하면서 함께 알아보았다. 첫 경험이다 보니 코드를 거의 복붙한 경우가 많았기 때문에 당연히 원하는 결과가 안나오는 경우가 태반이었고 끊임없는 에러 속에서 같이 울고 웃었다.
    좋은 팀원들과 이야기하고 논의하면 나도 모르게 발전하고 있다는 느낌이 들었다. 모르는 것이 있으면 끙끙 앓지 않고 물어보거나 같이 알아가면서 함께 성장하는 팀의 일원이 되고 싶다.

  • 설득할 수 있고, 수용할 줄 아는 사람이 되자
    코드를 짤 때는 항상 왜? 이 코드를 사용했는지 늘 생각하고 이를 토대로 팀원을 설득하는 능력이 필요할 것 같다.
    ("코드에는 정답이 없다")
    동시에 다른 사람의 피드백과 의견도 수용해서 새로운 관점과 아이디어를 습득하는 과정도 꼭 필요하다.

  • 말투는 부드럽게
    개발을 하면서 스트레스 받거나 기분이 안 좋은 상황이 올 수 있다. 그런 경우에도 대화할 때는 항상 부드러운 말투를 잊지 말자. 감정에 이끌려 상대방의 기분을 상하게 하는 억양으로 말하면 큰일(?)난다

 

🌟 아쉬웠던 점

🧨 GitLab(깃랩) 관리 부족

개발 초반에는 깃랩을 활용했지만 반복되는 Merge 에러의 늪에서 헤어나오지 못하면서... 결국 코치님의 추천으로 VSCode LiveShare을 사용했다.
LiveShare은 다른 사람의 VScode에 직접 들어가 같이 편집할 수 있는 확장 프로그램이다. 때문에 브랜치를 활용할 필요가 없어지게 되면서 커밋할 필요성도 없어졌다. 편리하기는 하지만, 나중에 실무에 있어서 이 방법은 독이 될 수 있다. 다음 프로젝트 때는 깃 공부를 더 해서 브랜치 관리와 머지를 완벽하게 해내고야 말겠다.

🧨 Validation, 이렇게 하는 게 맞나?

어떤 요청에 필요한 모든 데이터가 정상적으로 들어왔는지를 확인하는 유효성 검사가 필요하다.
초기에는 if로 유효성 검사를 했지만, 코드의 길이가 길어지고 지저분해지는 느낌을 받아 Joi 라이브러리를 사용한 validation 검증 방식을 이용했다.
그런데 Joi 라이브러리의 존재를 프로젝트 마감 1일 전에 알아서 급하게 챗 GPT을 써가며 짜느라 맞게 한건지 잘.. 모르겠다ㅎㅎ; (동작은 잘 됨)

MVP별 validation 스키마 파일을 각각 만들었는데, 지금 생각해보니 각 파일에 들어가는 코드의 양이 그리 많지 않아 하나의 validation 파일을 만들고 그 안에 모든 스키마를 정의해도 괜찮다는 생각이 들었다.

🧨 이미지 업로드 기능

이미지 업로드 기능을 구현하지 못한 걸 이번 프로젝트의 가장 큰 아쉬운 점으로 꼽았다. 시간 상의 이유가 컸다. 사실 마음만 먹으면 하루 혹은 이틀 안에 끝낼 수 있을 것 같았지만, '못해도 프로젝트의 기본 기능만은 반드시 끝내자'는 목표였어서 굳이 새로운 기능을 추가해야할까 라는 분위기도 있었고.. PPT 작성과 VM 배포 작업도 남아 있었기 때문에 욕심을 부리지 않기로 했다.
사실 이런 결정을 하기 전에 잠깐 이미지 업로드 구현 관련 글을 찾아봤고, Node.js의 multer 패키지를 이용하여 로컬 혹은 클라우드에 이미지를 저장하는 방법을 찾아냈다. 다음 프로젝트 때 참고해야겠다.

🧨 코딩 스타일을 꼭 통일하자

개발을 다 마치고 코드를 보니 변수명과 함수명의 코딩 스타일이 저마다 다른 것이 눈에 들어왔다. 어떤 함수명은 파스칼 케이스(예: GetUser), 또 어떤 함수명은 카멜 케이스(예: getUser) 스타일로 뒤죽박죽 되어있는 것을 발견했다.
코딩은 혼자 짜는 것이 아니기 때문에 설령 자신의 코드라도 나중에 다시보고 유지보수를 용이하게 위해서는 코딩 스타일을 통일되게 하는 것이 중요하다고 생각한다. 다음번엔 코딩 스타일을 꼭 통일하자.

🌟 마치며

쓰다 보니 글이 너무 길어졌다. 인생 첫 웹서비스 개발 후기는 '힘든 일도 분명히 있었지만 너무 재밌었다!"였다. 강의에서는 접하지 못했던 새로운 기능을 직접 구현해보는 일은 설렘 그 자체였다. 첫 프로젝트라 아쉬운 점이 매우 많았지만 이를 기반으로 다음 프로젝트 때는 더욱 발전된 실력으로 완성할 수 있기를 소망해본다.

 


※ 피드백 환영

profile
안되어도 될 때까지

0개의 댓글