[벡엔드] 블로그 사이트 개발 회고

sang yun Lee·2023년 7월 1일
0

프로젝트 회고

목록 보기
1/3

개요


약 4개월 전, 프론트엔드/백엔드 부트캠프 팀원들과 같이 블로그 사이트 를 개발했었다. 사이트를 개발했을 당시에는 적절한 회고록을 작성하지 못했기에 지금이라도 회고록을 작성해보려 한다.

프로젝트 소개


프로젝트 주제는 블로그 사이트 였다. 일반적인 블로그에서 지원하는 기능인 게시글, 댓글, 썸네일, 유저 프로필, 검색, 게시글 공개범위 설정 뿐만 아니라 깃허브 유사 잔디 (커밋 대신 게시글 갯수 활용), 유저 팔로우 기능을 추가한 사이트였다.
팀원은 백엔드 2명, 프론트 4명이었으며 나는 백엔드 를 맡았다.

프로젝트 결과물


개발 기간: 2023.1.9 ~ 2023.2.12

🔸 블로그 웹사이트

아래는 프로젝트 웹사이트의 메인페이지이다. 현재도 사이트 점속 (프로젝트 웹사이트 링크) 이 가능하며, 접속 시 더 많은 페이지를 확인할 수 있다.

프로젝트 설계 당시에 원했던 기능들을 모두 구현하였다.

🔸 ERD

아래는 프로젝트의 ERD 이다. 최대한 정규화를 지키려 하였다.

🔸 아키텍쳐 다이어그램

온-프레미스 서버에 쿠버네틱스(미니큐브)를 사용해서 배포 중에 있습니다.

맡은 역할


나는 백엔드를 맡았는데, 아래의 기능들을 담당했다.

  • 구현한 기능
    • 게시글 CRUD (썸네일 추가 가능)
    • 유저 정보 CURD (프로필 사진 추가 가능)
    • 게시글 및 유저 검색
    • 게시글 공개범위 설정
    • 깃허브 유사 잔디 (커밋 대신 게시글 갯수 활용) 표시

주요하게 고려했던 부분


🔸 온프레미스 배포

나는 현재 웹사이트의 백엔드 서버 (DB 포함) 를 내 집의 온프레미스 서버 로 배포하고 있고 꾸준히 사용중에 있다. 혼자서 배포와 관련된 작업을 직접 도맡았는데 도메인 구매 , 포트포워딩 , HTTPS 인증서 연결 , MySQL 의 외부 접속 허용 , 컴퓨터 부팅 시 서버 자동 실행 등을 관리하였다.

🔸 횡단 관심사 분리 (SOP)

Controller 에서 직접 담당하고 있던 요청의 형식 및 가공DTO 가 담당하게 하여 횡단 관심사 분리 를 진행하였다.
프로젝트 내 백엔드 서버는 크게 다음과 같이 3가지로 분리되어 있다. Controller , Service , Model .
이 중 Controller 는 요청과 응답의 가공 및 처리를 맡고 있었는데, 요청을 가공하는 코드Controller 의 전역에 작성되어 있어 관리의 복잡도가 증가하였다.
아래는 Controller 코드 내에서 요청을 가공하는 코드 가 길어지는 예시이다.

// Controller 단의 코드
const createPosts = async (req: Request, res: Response) => {
  // (1) 요청의 형식이 올바른지 확인
  checkData({ ... });
  // (2) 요청을 백엔드의 클래스 형식에 맞게 가공
  	// (1) 과 (2) : 코드가 길어질수록 가독성이 떨어지며 코드의 재활용성 또한 떨어진다.
  const input = {
    ...
    title = ...
    description = ...
    ...
  }
  // 가공한 요청을 Service 단으로 보낸다.
  const result = await svc.createPosts(input);
  ...
}

위와 같이 코드가 길어지는 것을 방지하기 위해, 요청을 가공하는 코드DTO Class 에서 담당하도록 하여 횡단 관심사를 분리 함으로써 코드의 가독성과 재활용성을 증가시켰다.

// DTO 클래스
export class CreatePostDto {
  @MinLength(1, {message: '제목은 최소 1글자 이상이여야 합니다',})
  @MaxLength(300, {message: '제목은 최대 300글자 이하이여야 합니다',})
  @Transform(({ value }) => value || 0)
  title?: string;
  ...
}

// Controller 단 코드
const createPosts = async (req: Request, res: Response) => {
  // 요청의 가공을 DTO 가 담당하도록 변경되었다.
  const postDto = await CreatePostDto.factory(req);
  
  // 이전과 동일하게 가공한 요청을 Service 단으로 보낸다.
  const result = await svc.createPosts(input);
  ...
}

🔸 SQL 문 코드 리팩토링

SQL 문에 익숙해지기 위해 raw SQL 로 코드를 짰다. raw SQL 을 하나하나 직접 모두 작성하는 것은 매우 번거로운 일이었기에 중복되는 단어의 경우 함수로 빼내어 코드의 복잡도를 낮추었다.
아래는 raw SQL 문을 함수로 빼내서 직접 작성한 코드이다. getQueryOfSelectPost , whereBuilder , getQueryOfOpenRange 함수 등을 직접 작성하여 가독성을 증가시켰다.

// Read 에 해당하는 함수이다.
// 조인과 다중 컬럼 검색 등을 사용하였으며 원하는 조건의 게시글을 볼 수 있도록 하였다.
const answer = await dataSource
    .query(
      `
      ${getQueryOfSelectPost({ onlyCount })}
      ${whereBuilder("p.id",        ["="], postId, true)}
      ${whereBuilder("p.users_id",  ["="], userId)}
      ${whereBuilder("cate.id",     ["="], cateId)}
      ${whereBuilder("t.id",        ["="], topicId)}
      ${getQueryOfOpenRange(loginedUserId)}
      ${getQueryOfMyFollow(myFollowing)}
      AND (
        1 = 1
      ${whereBuilder("p.title",             ["LIKE", "AND", "SEARCH"], search)}
      ${whereBuilder("p.content",           ["LIKE", "OR",  "SEARCH"], search)}
      ${whereBuilder("cate.category_name",  ["LIKE", "OR",  "SEARCH"], search)}
      ${whereBuilder("tagsOnPost.tags",     ["LIKE", "OR",  "SEARCH"], search)}
      `
    )

개선하고 싶은 부분


비즈니스 로직은 많이 완료가 되었다. 이제 인프라 측면에서 아래와 같은 고려를 해보려 한다.

🔸 쿠버네틱스 적용

현재 하나의 컴퓨터에서만 백엔드 서비스를 담당하고 있다. 이러면 트래픽이 많아졌을 때에 컴퓨터가 부하를 감당하기 어려워 문제가 생길 수 있다. 이러한 문제를 해결하기 위해 2대의 컴퓨터를 추가로 연결시키고 쿠버네틱스 로 컨트롤할 예정이다. 이를 통해 트래픽을 분산시키고 내결함성을 증대시켜 고가용성을 확보하려 한다.
AWS 로도 이러한 것들이 가능하고 실제로 배포한 경험도 있지만 AWS 의 경우 비용에서 부담이 되어, 우선 온프레미스로 진행해볼 예정이다.

🔸 배포 자동화 (CI / CD)

현재는 깃허브를 통한 CI / CD 자동화는 적용되어 있지 않다. 그래서 온프로미스 서버에 쿠버네틱스 를 적용시킨 뒤 깃허브를 통해 CI / CD 파이프라인을 구성할 예정이다.

🔸 모니터링 및 부하테스트

배포된 서버가 얼마만큼의 부하를 감당할 수 있는 지를 k6 를 활용해 테스트하고 그 결과를 그라파나 를 이용해 모니터링하려 한다.

프로젝트 후기


이번 프로젝트는 프론트엔드/백엔드 부트캠프 팀원들과 수료 후 처음으로 아이디어 회의, 그리고 설계부터 구현까지 전부 같이 작업한 프로젝트이고 원했던 기능들을 모두 완성해서 의미가 뜻 깊었다. 그래도 아쉬운 점이 있었다. 지금 되돌아 보면 내가 다른 분들의 상황도 유심히 신경쓰지 않은 게 아쉬웠다. 어떤 팀원분은 프로젝트에 대한 의지가 많이 꺾여있지만 나는 신경을 쓰지 못했다. 길다면 길고 짧다면 짧은 기간이었지만 모두 너무나 친해져서 팀원분들이 모두 만족스러운 프로젝트였으면 했는데, 그런 부분에서 미리 캐치하고 소통하지 못했어서 돕지 못해 너무 아쉬웠다. 그럼에도 나에게는 아직도 도움이 되는 프로젝트이다. 현재도 이 프로젝트 소스를 가지고 도커 이미지도 만들어보았고 추가적으로 유지보수해보고 싶은 것들이 많다. 개발하고 싶은 부분 이라는 목차에서 적은 것들을 모두 진행해볼 예정이다.

0개의 댓글