목표 : URL 단축기를 개선해 나만의 단축서비스를 만들어보자.
서비스 주소 : omong.kr/short
우테코 프리코스 3주차 까지의 미션은 코드 작성 후 다시 생각해보고 개선하는 일의 연속이었다.
거의 대부분의 경우에서 결과물의 품질을 향상시키기 위해서는
현재의 문제점이란 무엇인지, 이를 개선할 수 있는 방법으론 무엇이 있는지, 어떻게 적용할 수 있는지
고민해보는 것이 중요하다는 생각이 들었다.
곰곰히 생각해보면, 내가 개발에 흥미를 가지게 된 이유는
개발은 나의 불편함과 귀찮음을 해결해주는 문제 해결도구 였기 때문이다.
인터넷 생활을 하면서 느꼈던 사소한 불편함을 안고 살아가는 것과,
이를 개선해서 더 편하게 사는 것은 아주 작은 차이 같지만
이 작은 차이들이 모여져서 큰 격차를 만들어낼 수 있다고 생각했다.
원본 URL을 짧게 줄여 간단한 URL로 만드는 유틸 성격의 도구.
정보통신기기를 이용해 사람들과 교류하고 소통하는 문화는 이미 수십년 전에 정착되었다.
수학적 계산을 도와주는 컴퓨터의 시초에서 출발해 개인형 컴퓨터, 노트북, 태블릿, 스마트폰, 웨어러블 기기까지
기술의 발전은 우리의 일상을 편리하게 도와주는 방향으로 끊임없이 진화하고 있다.
현대 사회의 사람들은 수많은 서비스들을 동시에 이용하면서 이를 다른 사람들과 쉽게 공유하기도 한다.
멀리 떨어진 사람에게 내가 본 뉴스 기사를 공유하거나, 재미있는 영상을 보여주기 위해서 우리는 URL을 통해 이 리소스를 공간적 제한에 구애받지 않고 쉽게 전달할 수 있다.
URL 단축기를 사용해보지 않은 사람은 거의 없을 것이다.
직접 URL을 단축해보지 않은 사람은 있을 수 있겠지만,
나도 모르는 사이에 공유의 용이성을 위해 단축된 URL을 눌러본 적은 있을 것이다.
그만큼 자주 노출되는 서비스라고 생각해볼 수 있다.
내가 URL단축기를 사용하며 느낀 불편한 점은 세 가지 정도이다.
이 세 가지를 전부 해결하면 좋겠지만, 일단 구현한 뒤에, 차차 불편함을 느꼈던 문제들을 모두 해결할 예정이다.
원래 서비스의 운영이란 그렇다. 불편함 한 개를 해결하는 과정에서 다른 여러가지 문제들이 발생할 수 있다.
그 문제들을 최소화 하는 방식으로 만들거나,
새로이 생겨난 문제들 마저 해결하려는 것이 바로 개발자의 자세라고 생각한다.
소문자 L과 대문자 i 는 구별하기 힘들다. IlIlI
폰트에 따라 차이는 있겠지만 둘이 붙어있으면 정말 구분하기가 어렵다.
api 명세를 상세히 해두어 사용하기 정말 간편한 URL단축 서비스들이 더러 있다. 하지만 유료다.
무료와 오픈소스를 좋아하는 나로써는 유료 서비스는 부담이 된다.
이 역시 서비스의 유료화와 관련이 있다. 하지만 공적인 공지등을 단축시킬때에는 이러한 광고가 신뢰성을 저해시킬 수 있다고 생각한다.
짧은 링크를 생성하는 방법에는 다양한 방식이 존재하지만, 크게 두 가지 접근법이 많이 사용된다:
이 방식은 말 그대로 임의의 문자열을 생성한 뒤, 기존 URL과 함께 저장한다. 디코딩은 불가능하지만, 충분한 랜덤성과 중복 방지를 통해 고유성을 확보할 수 있다.
do {
code = generateRandomCode(길이 4~8);
} while (repository.findByCode(code).isPresent());
repository.save(new ShortUrl(code, originalUrl));
이 접근은 URL 저장 시 생성되는 자동 증가 ID를 Base62 등으로 인코딩하여 단축 코드를 만든다. 숫자를 영문 대소문자+숫자(총 62자)로 인코딩하여 짧고 예측 가능한 코드를 만든다.
하지만 단점은 ID 노출 위험이다. 예를 들어 1번 ID는 aaaaa, 2번 ID는 aaaab처럼 연속된 코드가 생성되며, 외부에서 유추하기 쉬워진다. 이를 방지하기 위해선:
짧고 추측 불가능한 링크가 핵심이라 판단했고, 다음 이유들로 랜덤 문자열 방식을 채택했다:
단축 링크가 실제로 작동하려면, 사용자가 단축 URL에 접속했을 때 원래 주소로 이동시켜야 한다.
이때 사용하는 HTTP 상태코드는 보통 두 가지다:
301 Moved Permanently
302 Found
처음엔 단순히 리디렉션이면 다 된다고 생각했지만,
아래와 같은 이유들로 302 Found가 필요했다!
🔁 URL의 목적은 바뀔 수 있다
📈 분석 및 추적이 필요했다
301은 캐싱되기 때문에 로그가 남지 않음.🔐 접근 제어가 필요했다
결과적으로, 다음과 같이 Spring Boot에서 302 리디렉션을 구현했다:
return ResponseEntity.status(HttpStatus.FOUND)
.location(URI.create(originalUrl))
.build();
URL 단축기는 원리가 굉장히 단순해보이지만, 설계적 고민과 노력이 많이 들어간다.
이상적인 구조를 만들기 위해서는 어떤 서비스를 만들던지 설계에 대한 시간과 방법을 많이 투자해야 한다고 느끼는 시간이었던 것 같다.
11/26 17:53 URL 수정