본문 바로가기
Node.js

숏링크 변환 구현 - Node.js

by Zih0 2021. 11. 20.

숏링크

쇼핑몰같은 곳에서 주소창을 보면 긴 url(롱링크, 이제부터는 롱링크라고 표현하겠습니다)을 확인하실 수 있을겁니다. 정보들을 url 파라미터나 쿼리 스트링으로 저장하여 관리하다보면 url 길이가 길어질 수 밖에 없습니다.

해당 url을 공유할 때 롱링크는 미관상 보기 안좋은 편입니다. 이를 위해 나온 게 숏링크입니다.

대표적으로는 bit.ly 서비스가 있습니다.

+ ) 링크를 변경하는 서비스의 경우 보통 마케팅 데이터도 같이 처리하는 곳이 많다고 들었습니다. 브랜치, 앱스플라이어 등등

플로우

숏링크 생성

  1. 롱링크를 서버에 전송 (POST)
  2. 서버에서 숏링크 코드를 생성 ( shortid 라이브러리 사용 )
  3. 숏링크 코드, 롱링크, 숏링크에 대한 데이터를 DB에 저장
  4. 숏링크 반환

숏링크 접속

  1. 숏링크로 주소 접속
  2. url의 파라미터( 숏링크 코드 )로 DB 검색
  3. 만약 해당 코드를 발견하면 DB에선 롱링크를 가져옴
  4. 롱링크로 리다이렉트

구현

서버 제작을 위해 nodejs, mongodb를 사용했습니다.

먼저 아래 라이브러리를 설치합니다.

$ npm i express mongoose shortid
$ npm i -D nodemon

db 설정

config 폴더를 생성하여 db.js 파일을 생성합니다.

아래와 같이 작성합니다.

id, password, dbName은 본인의 환경에 맞게 설정해줍니다

const mongoose = require('mongoose');

const DB_URI = 'mongodb://id:password@localhost:27017/dbName';

mongoose.connect(DB_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

const connection = mongoose.connection;

module.exports = connection;

그리고 models 폴더를 생성하여 UrlMode.js 파일을 생성합니다.

const mongoose = require('mongoose');

const URLSchema = new mongoose.Schema({
  urlCode: String,
  shortUrl: String,
  longUrl: String,
  date: {
    type: String,
    default: Date.now,
  },
});

module.exports = mongoose.model('Url', URLSchema);

express 설정

최상단에 index.js 파일을 생성하여 아래와 같이 작성합니다.

const express = require('express');
const app = express();
const connection = require('./config/db');

connection.once('open', () => console.log('DB Connected'));
connection.on('error', () => console.log('Error'));

// body parser
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

const PORT = process.env.PORT || 5000;
app.listen(PORT, console.log(`server started, listening PORT ${PORT}`));

라우팅 생성

저는 아래와 같이 폴더와 파일들을 구성했습니다.

├── routes
│   ├── redirect.js
│   └── url.js
├── controllers
│   └── url.controller.js

routes 폴더의 redirect.js 파일은 숏링크 접속 시, 리다이렉트를 시키기위한 라우트 파일입니다.

그리고 url.js 에서는 롱링크를 숏링크로 만드는 API를 작성하기 위한 라우트 파일입니다.

controllers 폴더의 url.controller.js 파일에선 숏링크 생성하는 함수와 숏링크를 롱링크 전환하는 함수를 저장해놓았습니다.

우선 컨트롤러에서 함수를 작성하겠습니다.

//url.controller.js

const shortid = require('shortid');
const Url = require('../models/UrlModel');

const baseUrl = 'http://localhost:5000';

module.exports = {
  shortenUrl: async (req, res) => {
    const { longUrl } = req.body;
    const urlCode = shortid.generate();
    console.log(req);
    if (longUrl) {
      try {
        let url = await Url.findOne({
          longUrl,
        });
        if (url) {
          res.json(url);
        } else {
          const shortUrl = baseUrl + '/' + urlCode;
          url = new Url({
            longUrl,
            shortUrl,
            urlCode,
            date: new Date(),
          });
          await url.save();
          res.json(url);
        }
      } catch (err) {
        console.log(err);
        res.status(500).json('Server Error');
      }
    } else {
      res.status(500).json('Invalid Url');
    }
  },
  redirectUrl: async (req, res) => {
    try {
      const url = await Url.findOne({
        urlCode: req.params.code,
      });
      console.log(url);
      if (url) {
        return res.redirect(url.longUrl);
      } else {
        return res.status(404).json('No URL Found');
      }
    } catch (err) {
      console.error(err);
      res.status(500).json('Server Error');
    }
  },
};

다음으로는 숏링크를 생성하는 API 라우트 설정

// url.js

const express = require('express');
const urlController = require('../controllers/url.controller');

const router = express.Router();

router.post('/shorten', urlController.shortenUrl);

module.exports = router;

마지막으로 숏링크를 리다이렉트 시키는 API 라우트 설정

// redirect.js

const express = require('express');
const urlController = require('../controllers/url.controller');
const router = express.Router();

router.get('/:code', urlController.redirectUrl);

module.exports = router;

index.js에서 위 라우터들을 연결시키겠습니다.

const express = require('express');
const app = express();
const connection = require('./config/db');

// 라우터 import 
const redirectRoute = require('./routes/redirect');
const urlRoute = require('./routes/url');

connection.once('open', () => console.log('DB Connected'));
connection.on('error', () => console.log('Error'));

app.use(express.json());
app.use(express.urlencoded({ extended: false }));

// 라우터
app.use('/', redirectRoute);
app.use('/api/url', urlRoute);

const PORT = process.env.PORT || 5000;
app.listen(PORT, console.log(`server started, listening PORT ${PORT}`));

데모

먼저 숏링크로 만들 주소를 찾습니다.

저는 쿠팡의 대란 주소를 사용하겠습니다!

해당 주소를 서버로 POST 요청 보내면 아래와 같이, 숏링크 코드와 숏링크를 확인할 수 있습니다.

마지막으로 숏링크로 접속을 하게 되면, 서버에서 해당 롱링크로 리다이렉트 시키는 것을 확인 가능합니다!

 

 

github : https://github.com/Zih0/short-link-maker

댓글