목차

1. Before 프로젝트

1️⃣ 프로세스

2️⃣ short 알고리즘

2. ⚠️ 프로젝트의 문제점

3. After 프로젝트

1️⃣ 프로세스

2️⃣ 도메인

3️⃣ 알고리즘

4️⃣ 프로젝트

Short URL 프로젝트 리팩터링

1. Before 프로젝트

1️⃣ 프로세스

2️⃣ short 알고리즘

(short url 만드는 과정과 조회하는 과정이 상당히 충격적입니다)

생성

  1. original url, broadcast id, product title의 정보들을 url에 저장합니다.
  2. 저장한 url의 id와 broadcast id를 base62 알고리즘으로 인코딩합니다.
  3. 마지막으로 [ 인코딩한 url id + “” + 인코딩한 broadcast id + “” + product title ]을 base64로 인코딩합니다.

redirect

  1. 요청이 들어온 short url을 base64로 디코딩합니다.
  2. base64로 디코딩한 url을 “_”으로 나눕니다.(slice)
  3. "_" 으로 나눈 값들(인코딩한 url id, 인코딩한 broadcast id, product title)에서 base62로 인코딩한것을 base62로 다시 디코딩합니다.
  4. 최종적으로 디코딩한 값들(url id, broadcast id, product title)을 가지고 url을 조회합니다.
  5. 조회한 값이 null이면 www.nalbang.tv로 리다이렉트하고 존재하면 해당 상품 url로 리다이렉트 시켜줍니다.

아래는 위의 과정에서 생성된 url 예시입니다. https://s.nalbang.tv/MGRfZmZf7YWM7Iqk7Yq47KSR7J6F64uI64uk==

2. ⚠️ 프로젝트의 문제점

  • URL 포멧의 문제점
    • 생성된 short url은 short url이라고 보기 어려운 길이를 가지고 있습니다. (!short)
  • 프로젝트 내부의 문제점
    • 23년도에 만들어진 프로젝트임에도 불구하고 MyBatis로 이루어져있습니다.
    • HashMap 지옥에 빠진 프로젝트입니다. DTO 라는 개념이 존재하지 않았고, MyBatis였기 때문에 Entity라는 개념 자체도 없었습니다.
    • try/catch 지옥에 빠진 프로젝트입니다.
  • 도메인 관점의 문제점
    • product에 short url을 저장하고 url에 product title을 저장하는 등 도메인에 대한 분리가 잘 되지 않았습니다.
    • product와 url 관계에서 역할과 책임이 불분명했습니다.

어떠한 한 부분적으로의 문제가 아니라 전체적인 측면에서 문제가 많았기에 프로젝트를 리팩터링해보았습니다.

3. After 프로젝트

1️⃣ 프로세스

(redirect는 동일)

2️⃣ 도메인

Before

  • Product

    • title
    • short url
  • Url

    • product title
    • broadcast id
    • original url

After

  • Product

    • title
  • Url

    • product id
    • original url
    • short url

3️⃣ 알고리즘

전에는 최종적으로 Base64로 인코딩을 했었죠… 매우 충격적인 알고리즘이었습니다!…

지금은 상품의 id를 가지고 Base62 알고리즘으로 short url을 만들겁니다. 다음은 Base62 알고리즘의 몇 가지 특징입니다.

  • 문자는 대문자 AZ, 소문자 az 및 숫자 0-9로 구성됩니다.
  • 단축 URL의 길이가 가변적입니다. ID 값이 커지면 같이 길어집니다.
  • 유일성 보장 ID 생성기가 필요합니다.
  • ID의 유일성이 보장된 후에야 적용 가능한 전략이라 충돌이 불가능합니다.
  • ID가 1씩 증가하는 값이라고 가정하면 다음에 쓸 수 있는 단축URL이 무엇인지 쉽게 알아낼 수 있어서 보안상 문제가 될 소지가 있습니다.

Base62의 특징을 살펴보면 product id를 사용하면 안될 것 같다는 생각이 듭니다. 이럼에도 불구하고 프로덕트의 id를 가지고 short url을 만드는 이유는 다음과 같습니다.

  1. Base62는 문자(char)를 인코딩하지 못합니다. Base62로 변환하기 전에 문자열을 숫자로 변환하는 과정이 필요한데, 이 과정에서 중복된 결과를 얻을 확률이 있어 유일성이 보장되는 product id를 사용했습니다.
  2. 여러 상점들이 방송을 진행하고 상품을 등록하기 때문에 어떤 단축 URL인지 추측하기 어렵습니다.

이러한 이유들로 product id를 바로 Base62로 변환하는 방법을 선택하였습니다.

4️⃣ 프로젝트

기존 프로젝트의 스택입니다.

  • Java 11
  • Spring Boot 2
  • MyBatis

기존 프로젝트의 스택을 아래 스택으로 전환하였습니다.

  • Java 17
  • Spring Boot3
  • Spring Data JPA