pun-sho
PUNy-SHOrtener - Yet Another URL Shortener
Spelled pan‧cho - ˈpãnʲ.t͡ʃo
But, Why?
props to XKCD
We decided that we need something that doesn't exist on every other project (mix all of them , and you would have it).
So, we decided to make yet another URL shortener.
Usage
you can clone this repo or use one of the precompiled binaries available in the release section
you can also use docker, pre-made images are available for you at docker pull ghcr.io/doutorfinancas/pun-sho:latest
or you can
# this API_PORT is defined in .env file or put it in env itself
export API_PORT=8080
docker run --env-file=.env -p 8080:${API_PORT} -t ghcr.io/doutorfinancas/pun-sho:latest pun-sho
you should also copy the .env.example
to .env
and fill the values for the database. you can use either cockroach
or postgres
as value for the DB_ADAPTOR
if you use cockroach
, you can create a free account here
DB migrations
This project uses database migrations. For any changes on the DB structure to be dealt with or replicated or rolled-back we use a migration tool
Install golang-migrate
# cockroach
go install -tags 'cockroachdb' github.com/golang-migrate/migrate/v4/cmd/[email protected]
# postgres
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/[email protected]
Create new migration files
make migration/create
Migrate
To go versions up:
make migration/up
To go versions down:
make migration/clean
Create a short link
read -r -d '' BODY <<EOF
{
"link": "https://www.google.pt/",
"TTL": "2023-03-25T23:59:59Z",
"qr_code": {
"create": true,
"width" : 50,
"height": 50,
"foreground_color": "#000000",
"background_color": "#ffffff",
"shape": "circle"
}
}
EOF
# you could use "background_color": "transparent" to request a png without background
# by setting env property QR_PNG_LOGO to a png filepath,
# it will overlay the logo on qrcode center
curl -XPOST https://yourdomain.something/api/v1/short \
-H 'token: Whatever_Token_you_put_in_your_env' \
-H 'Content-Type: application/json' \
-d $BODY
this would render an answer like:
{
"id":"4b677dfe-e17a-46e7-9cd2-25a45e8cb19c",
"link":"https://www.google.pt/",
"TTL":"2023-03-25T23:59:59Z",
"created_at":"2023-03-20T10:50:38.399449Z",
"deleted_at":null,
"accesses":null,
"short_link":"https://env.configured.domain/s/SEdeyZByeP",
"visits":0,
"redirects":0
}
Get statistics from a visited link
curl -H 'token: ThisIsA5uper$ecureAPIToken' https://yourdomain.something/api/v1/short/c62cbe57-7e45-4e87-a7c1-11cfb006870b
this would render an answer like:
{
"id":"c62cbe57-7e45-4e87-a7c1-11cfb006870b",
"link":"https://www.google.pt/",
"TTL":"2023-03-25T23:59:59Z",
"created_at":"2023-03-19T18:56:06.8404Z",
"deleted_at":null,
"accesses": [
{
"created_at":"2023-03-19T18:56:09.615403Z",
"meta": {
"meta_collection": [
{
"name":"Accept-Encoding",
"values":["gzip, deflate, br"]
},
{
"name":"Accept-Language",
"values":["pt-PT,pt;q=0.9,en-GB;q=0.8,en;q=0.7,en-US;q=0.6,es;q=0.5"]
}
]
},
"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36",
"ip":"127.0.0.1",
"extra":"Map: map[]",
"os":"macOS 10.15.7",
"browser":"Chrome 110.0.0.0",
"status":"redirected"
}
],
"short_link":"https://env.configured.domain/s/SE345ZByeP",
"visits":1,
"redirects":1
}
Get a list of links
curl -H 'token: ThisIsA5uper$ecureAPIToken' https://yourdomain.something/api/v1/short/?limit=20&offset=0
will return a list of short links, using pagination
Deleting a link to make it inaccessible
curl -H 'token: ThisIsA5uper$ecureAPIToken' -XDELETE https://yourdomain.something/api/v1/short/c62cbe57-7e45-4e87-a7c1-11cfb006870b
Releases
We are currently working actively in the project and as such there still isn't a closed API.
we will be releasing 0.X until we bind a contract to the API
Next Steps
- Define stable contract version
- Add GUI (web based) with:
- Base login page
- Dashboard with overview
- Ability to track a specific link data
- Show list of links with filters (by date range, status)
- Allow better security (oauth2 or even simple jwt)
- Add GitHub pages with openapi/swagger definition
Cache-Control max-age should be set on successful redirection
Currently we redirect users with 301. This means that a user only passes our service once, and cache will then keep the user out, so no statistics for the service.
We should add Cache-Control with a max-age policy of 90, following industry practices, to prevent this and allow stats gathering
Create ability to return a QR code when a short link is created
we need to have a shortlink QR code created
Create DELETE endpoint for pun-sho
Currently pun-sho does not allow for deletion (soft) yet. This feature request is simply to have a DELETE /api/v1/short/:UUID: method that places the deleted_at as now.
If deleted_at is set, then redirects should no longer happen. We should still be able to collect statistics on this and track them
feat: #1 Restrict the access to a shorty URL by the number of redirects
Create filters for list short URL
It would be nice to have the ability to filter URLs from list and to have a grouping mechanism, such as
key
orgroup
that would allow one to have a contextful list returnedgroup
orkey
filter to act upon a new field, which is optional (must)start_date
andend_date
filter to act upon created_at (should)status
filter to act upon the state of the short, checking bydeleted_at
or if a redirect happen (could)Create ability to redirect by a number of times
I would like to have redirection limited not only by TTL, but also by number of redirects. There are cases in which I want a link to expire after a single time, other , after 5 times or an arbitrary number.
Not passing the value or passing 0 should be treated as infinite.