URL Shortener REST API with Actix-web
Build a URL shortener API in Rust with Actix-web and SQLite: send it a long link and get a short code back, open the short link and get redirected to the original, and ask for statistics such as how many times it was clicked. Database access uses sqlx, whose queries are checked against the real database schema when the code compiles, and the service validates URLs, generates codes that can't collide, counts clicks safely when many arrive at once, and is covered by integration tests. You'll learn async web handlers in Actix-web, shared application state, sqlx with migrations and compile-time checked queries, error handling with custom error types, and testing a web service.
- Estimate
- ~8.5h
- Steps
- 5
- Completed by
- 0
- Proposed by
- codeseed.app
Actix-web · sqlx · SQLite
Project roadmap
- 01
Set up Actix-web and the database
~2hCreate a project with actix-web, sqlx (with the sqlite and runtime features), serde and tokio. Write a migration creating a links table (code unique, target URL, created at and clicks), run it at startup with sqlx::migrate!, and share a SqlitePool through web::Data. Add a GET /health route. Done when: the server starts and creates the database.
- 02
Shorten URLs
~2hAdd POST /links taking {"url": "..."}: parse and validate it with the url crate (only http and https, with a host, and at most 2,048 characters), generate a random 7-character code from letters and digits with a secure random generator, and insert it, generating a new code if the unique constraint fails. Return 201 with the code and the full short URL. Define an error type that implements ResponseError so errors become JSON responses. Done when: valid URLs get codes, and invalid ones get 400 with a clear message.
- 03
Redirect and count clicks
~1.5hAdd GET /{code}: increase the click count with a single UPDATE ... SET clicks = clicks + 1 ... RETURNING target_url, so simultaneous clicks are all counted, and respond with a 302 redirect to the target. Return 404 for unknown codes. Done when: opening a short link in a browser redirects to the original, and every click is counted.
- 04
Add statistics
~1hAdd GET /links/{code}/stats returning the target URL, creation date and click count as JSON, using a query_as! query mapped to a struct, checked at compile time. Done when: the stats endpoint returns correct numbers after several visits.
- 05
Test it
~2hWrite integration tests with actix_web::test that build the app with a fresh in-memory SQLite database: shortening valid and invalid URLs, the redirect with its Location header, click counting (including many requests at once), stats, and unknown codes. Run cargo clippy. Done when: cargo test passes, and clippy has no warnings.
Resources
- DocsActix Web documentation
- Docssqlx
- DocsActix Web: testing
- Docsurl crate
- ArticleZero To Production In Rust (book site)
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack