{"id":13647739,"url":"https://github.com/ffissore/shorty","last_synced_at":"2025-04-12T06:18:19.405Z","repository":{"id":34541061,"uuid":"176983965","full_name":"ffissore/shorty","owner":"ffissore","description":"URL shortener available as library, microservice (even containerized), aws lambda, and azure function","archived":false,"fork":false,"pushed_at":"2023-06-14T16:25:41.000Z","size":275,"stargazers_count":31,"open_issues_count":10,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-12T06:18:09.694Z","etag":null,"topics":["aws-lambda","azure-functions","container","docker","library","microservice","rust","url-shortener"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ffissore.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-03-21T16:27:37.000Z","updated_at":"2025-04-01T00:27:23.000Z","dependencies_parsed_at":"2024-01-14T10:15:38.032Z","dependency_job_id":"862a660c-ba73-4b4b-943e-fbec27b73979","html_url":"https://github.com/ffissore/shorty","commit_stats":{"total_commits":30,"total_committers":1,"mean_commits":30.0,"dds":0.0,"last_synced_commit":"41ae7034571d06ec38defb67c176323233cb8f65"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffissore%2Fshorty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffissore%2Fshorty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffissore%2Fshorty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffissore%2Fshorty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ffissore","download_url":"https://codeload.github.com/ffissore/shorty/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248525141,"owners_count":21118620,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-lambda","azure-functions","container","docker","library","microservice","rust","url-shortener"],"created_at":"2024-08-02T01:03:45.138Z","updated_at":"2025-04-12T06:18:19.370Z","avatar_url":"https://github.com/ffissore.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# shorty\n\n[![Latest version](https://img.shields.io/crates/v/shorty.svg)](https://crates.io/crates/shorty)\n[![Build Status](https://travis-ci.org/ffissore/shorty.svg?branch=master)](https://travis-ci.org/ffissore/shorty)\n![License](https://img.shields.io/github/license/ffissore/shorty.svg)\n\nShorty is a URL shortener: it assigns a short ID to a URL of any length, and when people will access the URL with that short ID, they will be redirected to the original URL.\n\nThis is useful in cases such as sending SMS notifications, when you have a limited number of characters and don't want to waste them with a long URL and its parameters.\n\nShorty stores its data on Redis.\n\n### Multiple ways of deploying it\n\nShorty is available as\n\n- a [rust library](#rust-library)\n- an [http microservice](#http-microservice)\n- an [AWS lambda](#aws-lambda)\n- an [Azure function](#azure-function)\n\n### Rust library\n\nShorty is written in rust, and available as a crate library.\n\nFor additional information, take a look at the [documentation](https://docs.rs/shorty), and use shorty-http binary crate as an example. \n\n### HTTP microservice\n\nShorty stores its data on redis, so you need to install redis first. How to do that depends on your operating system. If you are on a debian like linux distro, it's just a\n\n```bash\napt-get install redis\n```\n\nIf you prefer `docker`, it's\n\n```bash\ndocker run --rm -it -p 6379:6379 redis:alpine\n```\n\nOnce redis is ready, download the latest shorty [release](https://github.com/ffissore/shorty/releases), unpack the archive and run shorty with\n\n```bash\nSHORTENER_API_KEY_MANDATORY=false ./shorty-http\n```\n\nAgain, if you prefer `docker`, it's\n\n```bash\ndocker run --rm -it -e SHORTENER_API_KEY_MANDATORY=false --network host ffissore/shorty\n```\n\nShorty will log `Starting server on 127.0.0.1:8088`.\n\nNow scroll down to [Using shorty](#using-shorty).\n\n### AWS lambda\n\nIn order to deploy Shorty on AWS, you need... node.js. Duh! Yeah, it's a shame, but `serverless` is a node package and de-facto standard for deploying lambdas on AWS, and it works well.\n\nInstall the required dependencies with \n\n```bash\nnpm install\n```\n\nThen run\n\n```bash\nnpx serverless deploy\n```\n\nThis will download a docker image that will be used to compile shorty. It will then create a Redis instance on AWS, all the networking bits required to make the lambda connect to Redis, and finally it will deploy the lambda.\n\nWhen done, it will print something like\n\n```\nendpoints:\n  GET - https://9tgwceucu4.execute-api.us-east-1.amazonaws.com/dev/{key}\n  POST - https://9tgwceucu4.execute-api.us-east-1.amazonaws.com/dev/\n```\n\nPlease bear in mind that:\n1. Your AWS account will be charged: lambdas are free up to 1 million requests but the \"NAT gateway\" required to expose them is not\n1. The bloat of CloudFormation you'll find in `serverless.yml` has been copy-pasted (thx [ittus](https://github.com/ittus/aws-lambda-vpc-nat-examples/blob/master/serverless.yml)) and I barely understand what it does.\n\nWhen you're done playing with shorty, delete everything with\n```bash\nnpx serverless remove\n```   \n\nNow scroll down to [Using shorty](#using-shorty).\n\n### Azure function\n\nAzure does not support Rust directly, but they allow you to run any kind of runtime as long as it runs in docker.\n\nShorty docker image is available at [docker hub](https://hub.docker.com/r/ffissore/shorty).\n\nThe following commands were taken from [this Azure guide](https://docs.microsoft.com/azure/app-service/containers/tutorial-custom-docker-image).\n\n* Create a resource group\n```bash\naz group create --name shorty-resources --location \"West Europe\"\n```\n* Create a redis instance  \n```bash\naz redis create --resource-group shorty-resources --name shorty-redis --location \"West Europe\" --sku Basic --vm-size c0 --enable-non-ssl-port\n```\n* Create a service plan\n```bash\naz appservice plan create --name shorty-service-plan --resource-group shorty-resources --sku B1 --is-linux\n``` \n* Create a webapp\n```bash\naz webapp create --resource-group shorty-resources --plan shorty-service-plan --name shortyshorty --deployment-container-image-name ffissore/shorty:latest\n```\n* Tell azure that Shorty listens on port 8088\n```bash\naz webapp config appsettings set --resource-group shorty-resources --name shortyshorty --settings WEBSITES_PORT=8088\n```\n* and that for now we don't need API keys\n```bash\naz webapp config appsettings set --resource-group shorty-resources --name shortyshorty --settings SHORTENER_API_KEY_MANDATORY=false\n```\n* Now locate your redis instance on azure portal, and copy its primary access key. It will something like `RandomString=`: that's redis password. Set the redis host variable accordingly\n```bash\naz webapp config appsettings set --resource-group shorty-resources --name shortyshorty --settings SHORTENER_REDIS_HOST=:RandomString=@shorty-redis.redis.cache.windows.net\n```\n\nShorty will be available at https://shortyshorty.azurewebsites.net/\n\nPlease bear in mind that your account will be charged for all of the above.\n\nWhen you're done playing with shorty, delete everything with\n```bash\naz group delete --name shorty-resources\n```   \n\nNow scroll down to [Using shorty](#using-shorty).\n \n### Using shorty\n\nThe following instructions assume shorty is running on your pc. If that's not the case, replace `http://localhost:8088` with the proper domain.\n \nTry this `curl` to store a URL\n\n```bash\ncurl -vv http://localhost:8088/ -H 'Content-Type: application/json' --data '{\"url\":\"https://en.wikipedia.org/wiki/URL_shortening#Techniques\"}'\n```\n\nIf you have enabled API keys, add the API key to the payload, like this\n\n```bash\ncurl -vv http://localhost:8088/ -H 'Content-Type: application/json' --data '{\"api_key\": \"test\", \"url\":\"https://en.wikipedia.org/wiki/URL_shortening#Techniques\"}'\n```\n\nIt will output something like\n\n```json\n{\"id\":\"CGQ6LM8bfj\",\"url\":\"https://en.wikipedia.org/wiki/URL_shortening#Techniques\"}\n```\n\nNow try resolving that ID\n\n```bash\ncurl -vv http://localhost:8088/CGQ6LM8bfj\n```\n\nThe output headers of curl will contain a `Location: https://en.wikipedia.org/wiki/URL_shortening#Techniques`. Try opening the shorty url with your browser.\n\n### Configuration\n\nShorty can be configured through environment variables\n\n* `SHORTENER_REDIS_HOST`: the host of the redis server, defaults to 127.0.0.1\n* `SHORTENER_REDIS_PORT`: the port of the redis server, defaults to 6379\n* `SHORTENER_API_KEY_MANDATORY`: do users have to provide an API key in order to create a new short URL? boolean, defaults to true\n* `SHORTENER_RATE_LIMIT`: the amount of new short url a single API key can create in a period, defaults to 10, if set to 0 no limit is applied\n* `SHORTENER_RATE_LIMIT_PERIOD`: the period of the rate limit, if active, defaults to 600 seconds (10 mins)\n* `SHORTENER_ID_LENGTH`: the length of the ID generated for each URL, defaults to 10. The char set is `a-zA-Z0-9` = 62 chars. If you plan to use shorty only internally, you can use a much shorter ID, like 4 chars.\n* `SHORTENER_ID_GENERATION_MAX_ATTEMPTS`: the max number of attempts to generate a unique ID, defaults to 10. Especially important when the ID length is short and many short URLs are created.\n* `SHORTENER_HOST`: the host shorty will listen to\n* `SHORTENER_PORT`: the port shorty will listen to\n\n### What's on Redis\n\n* API keys: they are prefixed with `API_KEY_`, stored as `API_KEY_my_api_key`, and assigned a boolean value. A missing API key or an API key assigned to `false` will return error \"Invalid API key\"\n* Call rate keys: they are prefixed with `RATE_`, stored as `RATE_my_api_key`, and assigned the registered number of calls. The key is valid until `rate limit period` (see paragraph above) is over.\n* Short IDs, at the configured length (see example above): they are assigned to the original URL\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fffissore%2Fshorty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fffissore%2Fshorty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fffissore%2Fshorty/lists"}