초보 개발자의 백엔드 개발기

크로코 (Croco)·2021년 1월 1일
25

myWallets

목록 보기
1/4
post-thumbnail

안녕하세요. 저는 myWallets에서 백엔드 개발을 담당하고 있는 형주입니다.

myWallets는 Apple Wallet에 다양한 멤버십 카드들을 추가할 수 있는 서비스입니다.

멤버십 리스트에서 멤버십을 선택해 패스를 추가하면 휴대폰의 Apple Wallet 앱에 등록해 멤버십을 빠르게 사용할 수 있습니다.

이 글에서는 초보 개발자인 제가 myWallets 서비스의 백엔드 개발을 진행한 과정에 대해 소개해 드리고자 합니다.

myWallets의 프론트엔드에 관심이 있으시다면 다음 글을 봐주세요! 마이월렛 프론트 엔드 이야기


기술 스택

  • NestJS
  • TypeScript
  • MySQL, TypeORM

백엔드 개발 경험이라고는 라라벨을 비롯한 PHP 프레임워크들 뿐이었던 저는 이번 프로젝트가 첫 TypeScript 프로젝트이자 Nest 프로젝트였습니다.

평소였다면 접해보지 못했을 새로운 프레임워크와 언어를 이 프로젝트를 통해 배우게 되어 정말 뜻깊은 작업이 되었던것 같습니다 ☺️

myWallets 서비스 구조에 대해

myWallets은 위와 같은 구조로 패스를 생성합니다.

애플 월렛에서 지원하는 패스 타입은 보딩 패스, 쿠폰, 이벤트 티켓, 매장 카드, 제네릭, 매장 카드로 총 5개의 타입이 존재합니다.

이 모든 패스 타입을 지원하기 위해 PassTemplate과 Pass는 타입에 따라 다른 필드를 가지는 객체로 구성되어야 했습니다.

팀의 최고 존엄 개발자분께서 전달해 주신 귀중한 링크

테이블 상속 전략에 대한 고민

myWallets에서 사용하고 있는 ORM인 TypeORM에서는 싱글 테이블 전략멀티 테이블 전략 (Concrete 테이블 전략)을 제공합니다.

싱글 테이블 전략은 모든 자식 엔티티의 칼럼을 한 테이블에 저장하고 Discriminator(구분자)를 사용해 테이블에 어떤 자식 엔티티가 저장되어 있는지 구분합니다.

싱글 테이블 전략을 사용하면 테이블이 커질 수 있다는 단점이 있지만 다른 전략에 비해 쿼리 속도는 비교적 빠릅니다.

TypeORM에서 제공하는 또 다른 전략인 멀티 테이블 전략은 자식 엔티티를 위한 모든 속성을 가지는 테이블을 각각 생성합니다.

이 전략은 여러 종류의 엔티티를 쿼리할때 여러 테이블에 접근 해야하므로 성능이 떨어지는 단점이 있습니다.

위와 일맥상통하는 점으로 테이블이 너무 많아지면 심미적으로 불-편 하기에 이번 프로젝트에서는 싱글 테이블 전략을 사용하기로 결정했습니다.

import { ChildEntity, Column } from 'typeorm';
import { PassTemplate, PassTemplateType } from './pass-template.entity';

@ChildEntity(PassTemplateType.Coupon)
export class CouponPassTemplate extends PassTemplate {
  @Column()
  itemName!: string;

  @Column()
  itemImage!: string;
}
import { ChildEntity } from 'typeorm';
import { PassTemplate, PassTemplateType } from './pass-template.entity';

@ChildEntity(PassTemplateType.StoreCard)
export class StoreCardPassTemplate extends PassTemplate {}

위 코드에서 CouponPassTemplate과 StoreCardTemplate이 공통적으로 PassTemplate을 상속하는 모습을 확인할 수 있습니다.


우리의 협업 방식

myWallets 에서는 GitLab Flow에 따라 협업을 진행합니다.

기능 단위별로 브랜치를 열고 작업한 후 PR을 생성합니다.

이 과정에서 myWallets의 모든 코드는 리뷰를 받고 develop 브랜치로 머지됩니다.

그리고 일정한 간격을 두고 Frontend와 함께 릴리즈하고 master(production)에 최종적으로 배포하고 있습니다.

리뷰의 흔적

보다 나은 코드를 위해 myWallets 프로젝트에는 모든 코드는 리뷰를 받아야 한다는 원칙이 있습니다.

이런 리뷰 분화는 익숙해 지는데 시간이 다소 걸리고 힘들기도 했지만 새로운 언어와 프레임워크에 적응하는데 정말 많은 도움이 되었습니다.

TypeScript와 Nest 생태계에 처음 발을 들인 입장으로 팀 내에서 Nest 경험이 풍부한 다른 개발자로부터 리뷰를 받으면서 프레임워크와 언어 특성에 맞는 코드를 작성하는 법을 배울 수 있었습니다.

또한 프로젝트 초기에 정한 코드 컨벤션과 린팅 스타일에 대해서도 코드 리뷰를 통해 유지할 수 있게 되었습니다.

다만 개발 후기글을 쓰면서 알아차린 부분이지만 PR 템플릿이 정해져 있지 않고 내용이 없어 리뷰어께서 고생을 많이 하셨을것 같은 생각이 드네요 ㅋㅋㅋ..

저는 리뷰를 받는 입장이라 크게 생각을 못했지만,, 이 글을 빌어 감사를 전합니다 🙏

개발을 하면서 쌓인 46개의 머지된 PR

앞으로의 계획

위 이미지의 PR에서도 볼 수 있듯이 각 모듈을 DDD를 도입해 리팩토링을 하고 있습니다.

지금은 다른 모듈 의존성이 없는 멤버십 모듈부터 작업을 하고 있지만 앞으로는 Pass 생성을 포함한 모든 모듈을 Domain Driven 으로 개발하는 것이 저의 목표입니다.


myWallets 백엔드를 간략하게 소개했습니다.

블로그에 글로써 개발 후기를 적는것이 아직 어색해 제가 이야기하고 싶은 내용을 모두 다 담지 못해 너무 아쉽습니다.

myWallets의 다른 글들도 많은 기대 부탁드립니다 🙏

profile
세상을 바꾸는 사이드 프로젝트 팀, 크로코입니다.

4개의 댓글

comment-user-thumbnail
2021년 1월 1일

좋은 글 감사합니다. 잘 읽었습니다! 👍

1개의 답글
comment-user-thumbnail
2021년 1월 4일

재밌어보이네요 :p

1개의 답글