feat: refactor db calls to url service

This commit is contained in:
2025-07-23 02:58:46 +00:00
parent e72aad0582
commit e735f63b47
15 changed files with 88 additions and 54 deletions

View File

@@ -1,47 +1,34 @@
from fastapi import APIRouter, HTTPException
from fastapi.responses import RedirectResponse
from sqlalchemy.exc import IntegrityError
from app.db import database
from app.models import Url
from app.exceptions import ShortcodeNotFound, ShortcodeConflict
from app.utils import encoder
from app.schemas import UrlPayload
from app.services import encoder
from app.services import UrlService
router = APIRouter()
url_service = UrlService(db=database)
@router.get("/{shortcode}")
async def redirect_to_original_url(shortcode: str):
if not encoder.is_valid(shortcode):
raise HTTPException(status_code=400, detail="Shortcode is not valid")
query = Url.__table__.select().where(Url.shortcode == shortcode)
url_result = await database.fetch_one(query)
if url_result:
return RedirectResponse(url=url_result.url, status_code=302)
else:
raise HTTPException(status_code=404, detail="Shortcode not found")
@router.post("/shorten")
async def create_url_shortcode(url_payload: UrlPayload):
original_url = str(url_payload.url)
query = "SELECT nextval('urls_id_seq')"
next_id = await database.fetch_val(query)
shortcode = encoder.encode(next_id)
raise HTTPException(status_code=400, detail=f"Shortcode '{shortcode}' is not valid")
try:
query = Url.__table__.insert().values({
"id": next_id,
"url": original_url,
"shortcode": shortcode
})
await database.execute(query)
url = await url_service.get_url_by_shortcode(shortcode)
return RedirectResponse(url=url, status_code=302)
except ShortcodeNotFound as e:
raise HTTPException(status_code=404, detail=str(e)) from e
return {"shortcode": shortcode, "original_url": original_url}
except IntegrityError as e:
if 'shortcode' in str(e):
raise HTTPException(status_code=409, detail="Shortcode already in use")
else:
raise HTTPException(status_code=500, detail="Internal Server Error")
@router.post("/")
async def create_url_shortcode(url_payload: UrlPayload):
url = str(url_payload.url)
try:
return await url_service.generate_shortcode_and_save(url)
except ShortcodeConflict as e:
raise HTTPException(status_code=409, detail=str(e)) from e
except:
raise HTTPException(status_code=500, detail="Internal Server Error") from None