Skip to content

Instantly share code, notes, and snippets.

@mayankchoubey
Created October 15, 2023 03:22
Show Gist options
  • Save mayankchoubey/94e501058192768a3a526bc06e4eca1d to your computer and use it in GitHub Desktop.
Save mayankchoubey/94e501058192768a3a526bc06e4eca1d to your computer and use it in GitHub Desktop.
Deno - Hono URL shortener service in PostgreSQL
import { shorten } from "./service.js";
import { HTTPException } from "https://deno.land/x/hono/mod.ts";
export async function handleRequest(ctx) {
const ctHdr = ctx.req.header("content-type");
if (!(ctHdr && ctHdr.includes("application/json"))) {
throw new HTTPException(415, { message: "Content type JSON is required" });
}
let reqBody;
try {
reqBody = await ctx.req.json();
} catch (e) {
throw new HTTPException(400, {
message: "Request body is not a valid JSON",
});
}
if (!reqBody.srcUrl) {
throw new HTTPException(400, { message: "Parameter 'srcUrl' is missing" });
}
const srcUrl = reqBody.srcUrl;
if (srcUrl.length > 250) {
throw new HTTPException(400, {
message: "Parameter 'srcUrl' must not be more than 250 characters",
});
}
if (!(srcUrl.startsWith("http://") || srcUrl.startsWith("https://"))) {
throw new HTTPException(400, {
message: "Parameter url must start with http:// or https://",
});
}
const shortenedUrl = await shorten(srcUrl);
if (!shortenedUrl) {
throw new HTTPException(500, { message: "Failed to shorten" });
}
ctx.status(200);
return ctx.json({ srcUrl, shortenedUrl });
}
import { DataTypes, Sequelize } from "sequelize";
const dbUser = Deno.env.get("dbUser");
const dbUserPass = Deno.env.get("dbUserPass");
const dbName = Deno.env.get("dbName");
const sequelize = new Sequelize(
`postgres://${dbUser}:${dbUserPass}@localhost:5432/${dbName}`,
{
logging: false,
pool: {
max: 10,
min: 10,
},
},
);
await sequelize.authenticate();
const ShortenedUrl = sequelize.define("shortenedurl", {
id: {
type: DataTypes.STRING,
primaryKey: true,
},
srcurl: DataTypes.STRING,
created: DataTypes.DATE,
lastaccessed: DataTypes.DATE,
}, {
timestamps: false,
});
export async function save(id, srcUrl) {
await ShortenedUrl.create({
id,
srcurl: srcUrl,
created: new Date(),
lastaccessed: new Date(),
});
return true;
}
import { Hono } from "https://deno.land/x/hono/mod.ts";
import { handleRequest } from "./controller.js";
const app = new Hono();
app.post("/shorten", handleRequest);
Deno.serve({ port: 3000 }, app.fetch);
import { nanoid } from "https://deno.land/x/nanoid/mod.ts";
import { save } from "./db.js";
const baseUrl = "http://test.short/";
export async function shorten(srcUrl) {
if (!srcUrl) {
return;
}
const urlId = nanoid(10);
const shortenedUrl = `${baseUrl}${urlId}`;
const dbStatus = await save(urlId, srcUrl);
return dbStatus ? shortenedUrl : undefined;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment