Skip to content

Commit 466dd45

Browse files
feat(server): apis, test, readme, ui, storage, metrics
0 parents  commit 466dd45

File tree

1,158 files changed

+395882
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,158 files changed

+395882
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
my.db

.idea/.gitignore

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/shorturl.iml

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/watcherTasks.xml

+29
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2+
URL shortener
3+
-
4+
This is an example of how to create a URL shortener using:
5+
6+
- go-swagger as api Framework (OpenAPI 2.0)
7+
- swagger-ui as frontend to publish documentation and provide a way to test APIs
8+
- The apis logic need storage, that is passed as an `interface` to make easier change it
9+
"github.com/boltdb/bolt" has been chosen as implementation since it is a quick key-value db
10+
- prometheus is used to expose metrics under /metrics.
11+
- dependencies are managed through `go mod`
12+
- redirection is performed before hitting the API in the middleware
13+
- error management is present but covers only most common cases
14+
15+
The code NOT autogenerated is:
16+
17+
- `storage` package (logic of storage)
18+
- `middlewares` package (logic to redirect, prometheus)
19+
- `url_implementation` package (logic of APIs)
20+
- `restapi/operation/configure_url_shortener.go` file (linking pieces)
21+
- `swagger-ui/swagger.yml` file (open-api definition, used to auto-generate the code)
22+
23+
The code autogenerated is NOT covered by tests, everything else has a coverage of ~ 80%
24+
25+
![image](./UI.png)
26+
27+
28+
Development:
29+
-
30+
31+
To add new Api modify `swagger-ui/swagger.yml` and run:
32+
33+
`$swagger generate server -f ./swagger-ui/swagger.yml --exclude-main`
34+
35+
Be aware, if you modify any autogenerated file it will be overwritten running such command.
36+
37+
Run test running:
38+
`$go test ./...`
39+
40+
Usage
41+
-
42+
To execute the server clone the repo, cd into it and run:
43+
44+
`$go run ./cmd/url-shortener-server/main.go --port 35307`
45+
46+
Navigate to `localhost:35307/swagger-ui` to visualise the UI and test APIs with a frontend
47+
Navigate to `localhost:35307/metrics` to check metrics, in particular `url_redirected` keeps track of redirection since last execution
48+
49+
There are three methods under `/api`:
50+
- POST `/api` that accept in the json body the URL to make shorter
51+
- GET `/api/{shortURL}` that returns the URL corresponding to shortURL
52+
- DELETE `/api/{shortURL}` that delete the URL
53+
54+
Shortened URLs will be like `short-abcdefghil` and can be used as follows `localhost:35307/short-abcdefghil`
55+
56+
If you try to navigate to a shortened url that does not exist (es: `localhost:35307/short-notExisting`) you will be redirected to `http://www.notfound.com`

UI.png

175 KB
Loading

cmd/url-shortener-server/main.go

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"os"
6+
7+
"github.com/go-openapi/loads"
8+
flags "github.com/jessevdk/go-flags"
9+
"github.com/paologallinaharbur/shorturl/restapi"
10+
"github.com/paologallinaharbur/shorturl/restapi/operations"
11+
)
12+
13+
func main() {
14+
15+
swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON)
16+
if err != nil {
17+
log.Fatalln(err)
18+
}
19+
20+
api := operations.NewURLShortenerAPI(swaggerSpec)
21+
server := restapi.NewServer(api)
22+
defer server.Shutdown()
23+
24+
parser := flags.NewParser(server, flags.Default)
25+
parser.ShortDescription = "url shortener"
26+
parser.LongDescription = swaggerSpec.Spec().Info.Description
27+
server.ConfigureFlags()
28+
for _, optsGroup := range api.CommandLineOptionsGroups {
29+
_, err := parser.AddGroup(optsGroup.ShortDescription, optsGroup.LongDescription, optsGroup.Options)
30+
if err != nil {
31+
log.Fatalln(err)
32+
}
33+
}
34+
35+
if _, err := parser.Parse(); err != nil {
36+
code := 1
37+
if fe, ok := err.(*flags.Error); ok {
38+
if fe.Type == flags.ErrHelp {
39+
code = 0
40+
}
41+
}
42+
os.Exit(code)
43+
}
44+
45+
server.ConfigureAPI()
46+
47+
if err := server.Serve(); err != nil {
48+
log.Fatalln(err)
49+
}
50+
51+
}

go.mod

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module github.com/paologallinaharbur/shorturl
2+
3+
go 1.14
4+
5+
require (
6+
github.com/boltdb/bolt v1.3.1
7+
github.com/go-openapi/errors v0.19.6
8+
github.com/go-openapi/loads v0.19.5
9+
github.com/go-openapi/runtime v0.19.19
10+
github.com/go-openapi/spec v0.19.8
11+
github.com/go-openapi/strfmt v0.19.5
12+
github.com/go-openapi/swag v0.19.9
13+
github.com/go-openapi/validate v0.19.10
14+
github.com/jessevdk/go-flags v1.4.0
15+
github.com/prometheus/client_golang v1.7.1
16+
github.com/stretchr/testify v1.6.1
17+
golang.org/x/net v0.0.0-20200707034311-ab3426394381
18+
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect
19+
)

0 commit comments

Comments
 (0)