Shortlink service backed by Cloudflare Workers KV, with a FastAPI app running on Python Workers.
- Install dependencies:
make sync- Create local env vars:
cp .dev.vars.example .dev.vars- Set
DOMAIN_NAME(for examplego.example.com) - Set
STATIC_ACCESS_TOKEN(any strong token)
- Generate
wrangler.jsoncfrom the template:
export KV_NAMESPACE_ID=<your-kv-namespace-id>
export KV_PREVIEW_NAMESPACE_ID=<your-kv-preview-namespace-id>
./build.sh./build.sh renders wrangler.template.jsonc into wrangler.jsonc and then runs uv run build.
- Run locally:
make dev- Run tests:
make testwrangler.jsonc is generated from wrangler.template.jsonc. Do not edit wrangler.jsonc manually.
If you deploy through Cloudflare's Git-based Workers build:
- Set the build command to:
./build.sh- Add these build arguments:
KV_NAMESPACE_IDKV_PREVIEW_NAMESPACE_ID
-
Set
STATIC_ACCESS_TOKENas a Worker secret. -
Set
DOMAIN_NAMEon the Worker runtime as a variable or secret.
If you deploy from your local machine:
- Export the KV IDs and generate
wrangler.jsonc:
export KV_NAMESPACE_ID=<your-kv-namespace-id>
export KV_PREVIEW_NAMESPACE_ID=<your-kv-preview-namespace-id>
./build.sh- Configure runtime values on the Worker:
UV_CACHE_DIR=/tmp/.uv-cache uv run pywrangler secret put DOMAIN_NAME
UV_CACHE_DIR=/tmp/.uv-cache uv run pywrangler secret put STATIC_ACCESS_TOKEN- Deploy:
make deploy-
Pick the redirect host and set
DOMAIN_NAMEto that host. -
In Cloudflare, route that host to this Worker:
- Go to
Workers & Pages> your Worker >Settings>Triggers - Add a route matching
DOMAIN_NAME/*(examplego.example.com/*) - Ensure DNS for that host exists and is proxied by Cloudflare
Create a shortlink:
curl -i -X POST "https://<DOMAIN_NAME>/api/link" \
-H "Authorization: Bearer <STATIC_ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"code":"gh","link":"https://github.com"}'Verify the redirect:
curl -i "https://<DOMAIN_NAME>/gh"Expected result:
HTTP/1.1 302 FoundLocation: https://github.com
All /api/* routes require one of:
Authorization: Bearer <STATIC_ACCESS_TOKEN>X-Access-Token: <STATIC_ACCESS_TOKEN>
Routes:
GET /api/linklist all shortlinksGET /api/link/{code}fetch one shortlinkPOST /api/linkcreate a shortlink (codeoptional)PUT /api/link/{code}update the destination linkDELETE /api/link/{code}delete a shortlink
Validation rules:
code: lowercase letters and digits only, 1 to 12 characterslink: absolutehttporhttpsURL, max 1024 characters
POST /api/link:
- if
codeis omitted, a random lowercase alphanumeric code is generated - returns
Location: https://<DOMAIN_NAME>/<code>
Any non-/api/* route is treated as a short code and resolved from Cloudflare KV:
- found: HTTP
302redirect to the storedlink - not found or invalid target: HTTP
404