Project: URL Shortener
A complete URL shortener project.
Learning Objectives
- Build a full app
##Project: URL Shortener API
In this project, we'll outline how to build a URL Shortener—a classic web application that takes a long URL and generates a short, unique alias. When users visit the alias, they are redirected to the original URL.
This project combines routing, state management, and database integration.
#Core Requirements
- 1POST `/api/shorten`: Accepts a long URL and returns a short URL.
- 2GET `/{alias}`: Looks up the long URL by its alias and redirects the user (HTTP 301 or 302).
- 3Storage: A database (e.g., PostgreSQL using SQLx or SQLite) to persist the mappings.
#State and Database
We need an AppState to hold our database pool.
use sqlx::PgPool;
struct AppState {
db: PgPool,
}#The Shorten Endpoint
To create a short alias, we can generate a random string or hash the database ID. The nanoid crate is great for this.
use actix_web::{post, web, HttpResponse, Responder};
use serde::{Deserialize, Serialize};
use nanoid::nanoid;
#[derive(Deserialize)]
struct ShortenReq {
url: String,
}
#[derive(Serialize)]
struct ShortenRes {
short_url: String,
}
#[post("/api/shorten")]
async fn shorten_url(
req: web::Json<ShortenReq>,
state: web::Data<AppState>
) -> impl Responder {
let alias = nanoid!(6); // Generate 6-char ID
// Insert into DB: alias -> req.url
// e.g., sqlx::query!("INSERT INTO urls ...")
HttpResponse::Ok().json(ShortenRes {
short_url: format!("http://localhost:8080/{}", alias),
})
}#The Redirect Endpoint
When a request comes in for /{alias}, we extract the alias, look up the original URL, and return a redirect.
use actix_web::{get, web, HttpResponse, Responder};
#[get("/{alias}")]
async fn redirect_url(
path: web::Path<String>,
state: web::Data<AppState>
) -> impl Responder {
let alias = path.into_inner();
// Fetch original URL from DB using `alias`
let original_url = "https://example.com"; // Mocked
// Return a 302 Found redirect
HttpResponse::Found()
.append_header(("Location", original_url))
.finish()
}By combining these concepts, you have a fully functional URL shortener API!
Practical Exercise
Build a Shortener Endpoint
TaskRequirements
Try solving the exercise in your local environment first. Once you have a solution, or if you get completely stuck, reveal the answer.
Key Takeaways
- Use `web::Json` to accept long URLs from the client.
- Use `web::Path` to capture the short alias in the redirect route.
- `HttpResponse::Found()` (302) is used to redirect users to the original destination.
- Application state (`web::Data`) is perfect for sharing the database connection pool across these endpoints.
Finished reading?
Mark this lesson as done to track your progress and earn XP.