Url shortener written in Go. Supports generic/specified key setting and REST API for urls. Needs Redis. Docker-friendly.
There are two images of GoShort:
nikhovas/goshort:alpine
- standalone goshort. Can be used with docker-composenikhovas/goshort:redis
- goshort with embedded Redis database.
All in DockerHub.
Just go build -o urlshort .
in the folder of repository.
You can use environmental variables or config file to set up app.
Name | Description | Default value |
---|---|---|
GOSHORT_PORT | Port to listen to connections. App uses localhost. | 80 |
GOSHORT_TOKEN | Auth token for managing with urls | |
GOSHORT_REDIS_IP | Address of redis server | 127.0.0.1:6379 |
GOSHORT_REDIS_POOLSIZE | Number of opened connections | 10 |
Example of full config file:
redis:
ip: 127.0.0.1:6379
poolSize: 10
token: asdf
port: 80
You can manage urls with rest api on /urls/
POST /urls/ HTTP/1.1
Content-Type: application/json
Authorization: Bearer asdf
Host: 127.0.0.1:80
Content-Length: 49
{
"key": "yandex",
"url": "https://yandex.ru"
}
The default answer's code status is 301 (Moved permanently). If all is OK, the answer should be:
HTTP/1.1 200 OK
Content-Type: application/json
Date: Sat, 02 Jan 2021 11:37:20 GMT
Content-Length: 75
{
"key": "yandex",
"url": "https://yandex.ru",
"code": 301,
"autogenerated": false
}
You can also set your own response code (for example 302 temporary redirect):
Request
POST /urls/ HTTP/1.1
Content-Type: application/json
Authorization: Bearer asdf
Host: 127.0.0.1:80
Content-Length: 63
{
"key": "yandex",
"url": "https://yandex.ru",
"code": 302
}
Response
HTTP/1.1 200 OK
Content-Type: application/json
Date: Sat, 02 Jan 2021 11:42:29 GMT
Content-Length: 75
{
"key": "yandex",
"url": "https://yandex.ru",
"code": 302,
"autogenerated": false
}
If you don't need a specified key for your link, you can use adding link with generic key. It's an increasing string.
In this case there will be no new key if database already has a key-url pair with the url you want to add.
For example, if there is a generic key b
for example.com
, and you send a new generic POST
request for example.com
, there result will be b
, not c
.
Example:
POST /urls/ HTTP/1.1
Content-Type: application/json
Authorization: Bearer asdf
Host: 127.0.0.1:80
Content-Length: 25
{
"url": "example.com"
}
HTTP/1.1 200 OK
Content-Type: application/json
Date: Sat, 02 Jan 2021 15:19:52 GMT
Content-Length: 63
{
"key": "b",
"url": "example.com",
"code": 301,
"autogenerated": true
}
The next generic key request:
POST /urls/ HTTP/1.1
Content-Type: application/json
Authorization: Bearer asdf
Host: 127.0.0.1:80
Content-Length: 25
{
"url": "example.com"
}
HTTP/1.1 200 OK
Content-Type: application/json
Date: Sat, 02 Jan 2021 15:21:21 GMT
Content-Length: 63
{
"key": "b",
"url": "example.com",
"code": 301,
"autogenerated": true
}
Make attention that you can understand if the key is generic by looking at autogenerated
field.
If there is a key conflict with new generic key and existing not generic key, this value will be skipped, and the next alphabet-ordered free generic key will be used.
For example, if the last generic value was b
and there is already a c
key, it
will be skipped. The next generic key will be d
if it is free.
GET /urls/yandex/ HTTP/1.1
Content-Type: application/json
Authorization: Bearer asdf
Host: 127.0.0.1:80
HTTP/1.1 200 OK
Content-Type: application/json
Date: Sat, 02 Jan 2021 15:30:43 GMT
Content-Length: 75
{
"key": "yandex",
"url": "https://yandex.ru",
"code": 302,
"autogenerated": false
}
PATCH /urls/yandex/ HTTP/1.1
Content-Type: application/json
Authorization: Bearer asdf
Host: 127.0.0.1:80
Content-Length: 27
{
"url": "www.yandex.ru"
}
HTTP/1.1 200 OK
Content-Type: application/json
Date: Sat, 02 Jan 2021 15:32:16 GMT
Content-Length: 71
{
"key": "yandex",
"url": "www.yandex.ru",
"code": 302,
"autogenerated": false
}
DELETE /urls/yandex/ HTTP/1.1
Authorization: Bearer asdf
Host: 127.0.0.1:80
HTTP/1.1 200 OK
Date: Sat, 02 Jan 2021 15:34:53 GMT
Content-Length: 0
For simplicity the project uses a simple Bearer token auth, which you can specify with
GOSHORT_TOKEN
env var or in config file. The token in single, so make sure that it is
really secret.
If no token is specified, you don't have to write anything to Authorization
header,
the program won't look to it.
If the token is specified, but something is wrong with auth in your request, you'll get
error 401 (Unauthorized).