Short Link / Short URL ็ญ้พๆฅ โ
็ญ้พๆฅๆฏไธ็ง็ผฉ็ญ้ฟ็ฝๅ็ๆนๆณ๏ผๅฐๅๅง็้ฟ็ฝๅ่ฝฌๆขไธบๆด็ญ็ๅฝขๅผใๅฎ้ๅธธ็ฑไธ็ณปๅ็ๅญๆฏใๆฐๅญๅ็นๆฎๅญ็ฌฆ็ปๆ๏ผๆฏ่ตทๅๅง็้ฟ็ฝๅ๏ผ็ญ้พๆฅๆดๅ ็ฎๆดใๆไบ่ฎฐๅฟๅๅไบซใ
็ฑปไผผ TinyURL
install โ
bash
npm install nanoid
่ฏฆ่ง nanoid
usage โ
- express + knex + mysql2 + nanoid
sql
CREATE TABLE shortcodes (
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '็ญ็ ่ฎฐๅฝ็ๅฏไธๆ ่ฏ',
shortcode VARCHAR(255) NOT NULL COMMENT '็ๆ็ๅฏไธ็ญ็ ',
original_url TEXT NOT NULL COMMENT '็จๆทๆไพ็ๅๅง URL',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '่ฎฐๅฝ็ๅๅปบๆถ้ด'
) COMMENT = 'ๅญๅจ็ญ็ ไธๅๅง URL ็ๆ ๅฐ';
bash
npm install express mysql2 knex nanoid
js
import express from "express";
import knex from "knex";
import { nanoid } from "nanoid";
// ๅๅปบ Express ๅบ็จ
const app = express();
// ้
็ฝฎ knex ่ฟๆฅ MySQL
const db = knex({
client: "mysql2",
connection: {
host: "localhost",
user: "root", // MySQL ็จๆทๅ
password: "root", // MySQL ๅฏ็
database: "short_link", // ๆฐๆฎๅบๅ
},
});
// ่งฃๆ JSON ่ฏทๆฑไฝ
app.use(express.json());
app.get("/", (req, res) => {
res.send("Welcome to mysql2");
});
// ๅๅปบ็ญ็ ๅนถไฟๅญๅๅง URL ็ๆฅๅฃ
app.post("/generate-short-id", async (req, res) => {
const { originalUrl } = req.body;
if (!originalUrl) {
return res.status(400).json({ message: "Original URL is required" });
}
try {
// ไฝฟ็จ shortid ็ๆไธไธชๅฏไธ็็ญ็
const uniqueShortId = nanoid(5);
// ๅฐ็ญ็ ๅๅๅง URL ไฟๅญๅฐๆฐๆฎๅบ
await db("shortcodes").insert({
shortcode: uniqueShortId,
original_url: originalUrl,
});
// ่ฟๅ็ๆ็็ญ็ ๅๅๅง URL
res.status(201).json({ shortcode: uniqueShortId, originalUrl });
} catch (err) {
console.error(err);
res.status(500).json({ message: "Internal Server Error" });
}
});
// ๆ นๆฎ็ญ็ ้ๅฎๅๅฐๅๅง URL
app.get("/:shortcode", async (req, res) => {
const { shortcode } = req.params;
try {
// ๆ นๆฎ็ญ็ ไปๆฐๆฎๅบๆฅ่ฏขๅฏนๅบ็ๅๅง URL
const result = await db("shortcodes").where({ shortcode }).first();
if (!result) {
return res.status(404).json({ message: "Shortcode not found" });
}
// ้ๅฎๅๅฐๅๅง URL
res.redirect(result.original_url);
} catch (err) {
console.error(err);
res.status(500).json({ message: "Internal Server Error" });
}
});
// ๅฏๅจๆๅกๅจ
app.listen(3000, () => {
console.log("Server is running on http://localhost:3000");
});
- express + prisma + nanoid
bash
npm install prisma -D
npm install express @prisma/client nanoid
prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model ShortUrl {
id Int @id @default(autoincrement())
url String
short_url String @unique
create_time DateTime @default(now())
}
bash
npx prisma migrate dev --name init
js
import express from "express";
import { PrismaClient } from "@prisma/client";
import { nanoid } from "nanoid";
// ๅๅปบ Express ๅบ็จ
const app = express();
const prisma = new PrismaClient();
// ่งฃๆ JSON ่ฏทๆฑไฝ
app.use(express.json());
app.get("/", (req, res) => {
res.send("Welcome to mysql2");
});
// ๅๅปบ็ญ็ ๅนถไฟๅญๅๅง URL ็ๆฅๅฃ
app.post("/generate-short-id", async (req, res) => {
const { originalUrl } = req.body;
if (!originalUrl) {
return res.status(400).json({ message: "Original URL is required" });
}
try {
// ไฝฟ็จ shortid ็ๆไธไธชๅฏไธ็็ญ็
const uniqueShortId = nanoid(5);
// ๅฐ็ญ็ ๅๅๅง URL ไฟๅญๅฐๆฐๆฎๅบ
await prisma.shortUrl.create({
data: {
url: originalUrl,
short_url: uniqueShortId,
},
});
// ่ฟๅ็ๆ็็ญ็ ๅๅๅง URL
res.status(201).json({ short_url: uniqueShortId, url: originalUrl });
} catch (err) {
console.error(err);
res.status(500).json({ message: "Internal Server Error" });
}
});
// ๆ นๆฎ็ญ็ ้ๅฎๅๅฐๅๅง URL
app.get("/:shortcode", async (req, res) => {
const { shortcode } = req.params;
try {
// ๆ นๆฎ็ญ็ ไปๆฐๆฎๅบๆฅ่ฏขๅฏนๅบ็ๅๅง URL
const result = await prisma.ShortUrl.findUnique({
where: {
short_url: shortcode,
},
});
if (!result) {
return res.status(404).json({ message: "Shortcode not found" });
}
// ้ๅฎๅๅฐๅๅง URL
res.redirect(result.url);
} catch (err) {
console.error(err);
res.status(500).json({ message: "Internal Server Error" });
}
});
// ๅฏๅจๆๅกๅจ
app.listen(3000, () => {
console.log("Server is running on http://localhost:3000");
});