From 0e372a4e5196b49e0aad2ab9a769cfada3cab80e Mon Sep 17 00:00:00 2001 From: wgroeneveld Date: Mon, 15 Apr 2024 12:09:11 +0200 Subject: [PATCH] added /docs swagger endpoint for kicks and giggles --- README.md | 9 ++++ docs/docs.go | 101 +++++++++++++++++++++++++++++++++++++++++++++ docs/swagger.json | 77 ++++++++++++++++++++++++++++++++++ docs/swagger.yaml | 51 +++++++++++++++++++++++ go.mod | 22 +++++++++- go.sum | 61 +++++++++++++++++++++++++++ main.go | 18 ++++++++ pokemon/handler.go | 5 +++ 8 files changed, 342 insertions(+), 2 deletions(-) create mode 100644 README.md create mode 100644 docs/docs.go create mode 100644 docs/swagger.json create mode 100644 docs/swagger.yaml diff --git a/README.md b/README.md new file mode 100644 index 0000000..3e8263f --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ + +# Pokedex README + +A simple Go-powered REST API kata. + +## Swagger + +- Exposed at `http://localhost:8080/docs` +- Regenerate with `swag init`, see https://github.com/swaggo/http-swagger diff --git a/docs/docs.go b/docs/docs.go new file mode 100644 index 0000000..d6f6d7f --- /dev/null +++ b/docs/docs.go @@ -0,0 +1,101 @@ +// Package docs Code generated by swaggo/swag. DO NOT EDIT +package docs + +import "github.com/swaggo/swag" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "contact": { + "name": "Brain Baking", + "url": "https://brainbaking.com" + }, + "license": { + "name": "MIT", + "url": "https://opensource.org/licenses/MIT" + }, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/pokemon": { + "get": { + "produces": [ + "application/json" + ], + "summary": "get all Pokemon", + "operationId": "get-all-pokemon", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/pokemon.Pokemon" + } + } + } + } + } + }, + "definitions": { + "pokemon.Move": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "pokemonID": { + "description": "implicit; see https://gorm.io/docs/has_many.html", + "type": "integer" + }, + "url": { + "type": "string" + } + } + }, + "pokemon.Pokemon": { + "type": "object", + "properties": { + "height": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "moves": { + "type": "array", + "items": { + "$ref": "#/definitions/pokemon.Move" + } + }, + "name": { + "type": "string" + }, + "weight": { + "type": "integer" + } + } + } + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "1.0", + Host: "localhost:8080", + BasePath: "/", + Schemes: []string{}, + Title: "Pokedex", + Description: "A Pokedex Go Kata", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/docs/swagger.json b/docs/swagger.json new file mode 100644 index 0000000..b9269cd --- /dev/null +++ b/docs/swagger.json @@ -0,0 +1,77 @@ +{ + "swagger": "2.0", + "info": { + "description": "A Pokedex Go Kata", + "title": "Pokedex", + "contact": { + "name": "Brain Baking", + "url": "https://brainbaking.com" + }, + "license": { + "name": "MIT", + "url": "https://opensource.org/licenses/MIT" + }, + "version": "1.0" + }, + "host": "localhost:8080", + "basePath": "/", + "paths": { + "/pokemon": { + "get": { + "produces": [ + "application/json" + ], + "summary": "get all Pokemon", + "operationId": "get-all-pokemon", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/pokemon.Pokemon" + } + } + } + } + } + }, + "definitions": { + "pokemon.Move": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "pokemonID": { + "description": "implicit; see https://gorm.io/docs/has_many.html", + "type": "integer" + }, + "url": { + "type": "string" + } + } + }, + "pokemon.Pokemon": { + "type": "object", + "properties": { + "height": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "moves": { + "type": "array", + "items": { + "$ref": "#/definitions/pokemon.Move" + } + }, + "name": { + "type": "string" + }, + "weight": { + "type": "integer" + } + } + } + } +} \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml new file mode 100644 index 0000000..bf9f9ec --- /dev/null +++ b/docs/swagger.yaml @@ -0,0 +1,51 @@ +basePath: / +definitions: + pokemon.Move: + properties: + name: + type: string + pokemonID: + description: implicit; see https://gorm.io/docs/has_many.html + type: integer + url: + type: string + type: object + pokemon.Pokemon: + properties: + height: + type: integer + id: + type: integer + moves: + items: + $ref: '#/definitions/pokemon.Move' + type: array + name: + type: string + weight: + type: integer + type: object +host: localhost:8080 +info: + contact: + name: Brain Baking + url: https://brainbaking.com + description: A Pokedex Go Kata + license: + name: MIT + url: https://opensource.org/licenses/MIT + title: Pokedex + version: "1.0" +paths: + /pokemon: + get: + operationId: get-all-pokemon + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/pokemon.Pokemon' + summary: get all Pokemon +swagger: "2.0" diff --git a/go.mod b/go.mod index a62f532..05543d4 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,27 @@ module pokedex go 1.22 require ( + gorm.io/driver/sqlite v1.5.5 + gorm.io/gorm v1.25.9 +) + +require ( + github.com/KyleBanks/depth v1.2.1 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/spec v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect - gorm.io/driver/sqlite v1.5.5 // indirect - gorm.io/gorm v1.25.9 // indirect + github.com/swaggo/files v1.0.1 // indirect + github.com/swaggo/http-swagger v1.3.4 // indirect + github.com/swaggo/swag v1.16.3 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/tools v0.20.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 9ec6af8..8f77df5 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,70 @@ +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= +github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= +github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= +github.com/swaggo/http-swagger v1.3.4 h1:q7t/XLx0n15H1Q9/tk3Y9L4n210XzJF5WtnDX64a5ww= +github.com/swaggo/http-swagger v1.3.4/go.mod h1:9dAh0unqMBAlbp1uE2Uc2mQTxNMU/ha4UbucIg1MFkQ= +github.com/swaggo/swag v1.16.3 h1:PnCYjPCah8FK4I26l2F/KQ4yz3sILcVUN3cTlBFA9Pg= +github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E= gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE= gorm.io/gorm v1.25.9 h1:wct0gxZIELDk8+ZqF/MVnHLkA1rvYlBWUMv2EdsK1g8= diff --git a/main.go b/main.go index 6d41cd9..0b1fad4 100644 --- a/main.go +++ b/main.go @@ -1,10 +1,12 @@ package main import ( + "github.com/swaggo/http-swagger" "gorm.io/driver/sqlite" "gorm.io/gorm" "net/http" "os" + _ "pokedex/docs" "pokedex/pokemon" ) @@ -17,10 +19,26 @@ func openNewDb() *gorm.DB { return db } +// @title Pokedex +// @version 1.0 +// @description A Pokedex Go Kata + +// @contact.name Brain Baking +// @contact.url https://brainbaking.com + +// @license.name MIT +// @license.url https://opensource.org/licenses/MIT + +// @host localhost:8080 +// @BasePath / +// @query.collection.format multi func main() { db := openNewDb() pokemon.Seed(db) routes(db) + http.HandleFunc("GET /docs/", httpSwagger.Handler( + httpSwagger.URL("http://localhost:8080/docs/doc.json"), //The url pointing to API definition + )) http.ListenAndServe(":8080", nil) } diff --git a/pokemon/handler.go b/pokemon/handler.go index 999e2e5..e0a09c9 100644 --- a/pokemon/handler.go +++ b/pokemon/handler.go @@ -23,6 +23,11 @@ func HandleFindSingle(db *gorm.DB, rw http.ResponseWriter, req *http.Request) { }) } +// @Summary get all Pokemon +// @ID get-all-pokemon +// @Produce json +// @Success 200 {object} Pokemon +// @Router /pokemon [get] func HandleFindAll(db *gorm.DB, rw http.ResponseWriter, req *http.Request) { repo := NewRepo(db) pokemons, err := repo.FindAll()