Short URL 프로젝트 리팩터링
1. Before 프로젝트
1️⃣ 프로세스
2️⃣ short 알고리즘
(short url 만드는 과정과 조회하는 과정이 상당히 충격적입니다)
생성
- original url, broadcast id, product title의 정보들을 url에 저장합니다.
- 저장한 url의 id와 broadcast id를
base62
알고리즘으로 인코딩합니다. - 마지막으로 [ 인코딩한 url id + “” + 인코딩한 broadcast id + “” + product title ]을
base64
로 인코딩합니다.
redirect
- 요청이 들어온 short url을
base64
로 디코딩합니다. base64
로 디코딩한 url을“_”
으로 나눕니다.(slice)"_"
으로 나눈 값들(인코딩한 url id, 인코딩한 broadcast id, product title)에서base62
로 인코딩한것을base62
로 다시 디코딩합니다.- 최종적으로 디코딩한 값들(url id, broadcast id, product title)을 가지고 url을 조회합니다.
- 조회한 값이 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
지옥에 빠진 프로젝트입니다.
- 23년도에 만들어진 프로젝트임에도 불구하고
- 도메인 관점의 문제점
- 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을 만드는 이유는 다음과 같습니다.
- Base62는 문자(char)를 인코딩하지 못합니다. Base62로 변환하기 전에 문자열을 숫자로 변환하는 과정이 필요한데, 이 과정에서 중복된 결과를 얻을 확률이 있어 유일성이 보장되는 product id를 사용했습니다.
- 여러 상점들이 방송을 진행하고 상품을 등록하기 때문에 어떤 단축 URL인지 추측하기 어렵습니다.
이러한 이유들로 product id를 바로 Base62로 변환하는 방법을 선택하였습니다.
4️⃣ 프로젝트
기존 프로젝트의 스택입니다.
- Java 11
- Spring Boot 2
- MyBatis
기존 프로젝트의 스택을 아래 스택으로 전환하였습니다.
- Java 17
- Spring Boot3
- Spring Data JPA