Skip to content

Commit

Permalink
Update Swagger UI to v3.43.0 and add go1.16 embedding (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
vearutop authored Feb 17, 2021
1 parent 4b4afe0 commit 03f8d29
Show file tree
Hide file tree
Showing 20 changed files with 200 additions and 125 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SWAGGER_UI_VERSION := v3.38.0
SWAGGER_UI_VERSION := v3.43.0

update:
curl https://raw.githubusercontent.com/swagger-api/swagger-ui/$(SWAGGER_UI_VERSION)/dist/swagger-ui-bundle.js -o ./v3/static/swagger-ui-bundle.js
Expand Down
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,36 @@

[![GoDevDoc](https://img.shields.io/badge/dev-doc-00ADD8?logo=go)](https://pkg.go.dev/github.com/swaggest/swgui)

Package `swgui` (Swagger UI) provides HTTP handler to serve Swagger UI.
All assets are embedded in Go source code, so just build and run.
Package `swgui` (Swagger UI) provides HTTP handler to serve Swagger UI. All assets are embedded in Go source code, so
just build and run.

Static assets for `v3` are built from Swagger UI [v3.38.0](https://github.com/swagger-api/swagger-ui/releases/tag/v3.38.0).
Static assets for `v3` are built from Swagger
UI [v3.43.0](https://github.com/swagger-api/swagger-ui/releases/tag/v3.43.0).

[CDN-based](https://cdnjs.com/libraries/swagger-ui) `v3cdn` uses Swagger UI [v3.38.0](https://github.com/swagger-api/swagger-ui/releases/tag/v3.38.0).
[CDN-based](https://cdnjs.com/libraries/swagger-ui) `v3cdn` uses Swagger
UI [v3.43.0](https://github.com/swagger-api/swagger-ui/releases/tag/v3.43.0).

## How to use

```go
package main

import (
"net/http"
"net/http"

"github.com/swaggest/swgui/v3"
"github.com/swaggest/swgui/v3emb" // For go1.16 or later.
// "github.com/swaggest/swgui/v3" // For go1.15 and below.
)

func main() {
http.Handle("/", v3.NewHandler("My API", "/swagger.json", "/"))
http.ListenAndServe(":8080", nil)
http.Handle("/", v3.NewHandler("My API", "/swagger.json", "/"))
http.ListenAndServe(":8080", nil)
}
```

If you use `go1.16` or later, you can import natively embedded assets with `"github.com/swaggest/swgui/v3emb"`, it may
help to lower application memory usage.

## Use CDN for assets

In order to reduce binary size you can import `github.com/swaggest/swgui/v3cdn` to use CDN hosted assets.
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ require (
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
github.com/shurcooL/httpgzip v0.0.0-20190720172056-320755c1c1b0
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
github.com/vearutop/statigz v1.1.1
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 // indirect
golang.org/x/text v0.3.2 // indirect
golang.org/x/tools v0.0.0-20190830172400-56125e7d709e // indirect
Expand Down
21 changes: 21 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc=
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/bool64/dev v0.1.18 h1:uMN5MsHrVWmtRoauefI8wD86b8vbXYnrCZlIhFGyuXI=
github.com/bool64/dev v0.1.18/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/httpgzip v0.0.0-20190720172056-320755c1c1b0 h1:mj/nMDAwTBiaCqMEs4cYCqF7pO6Np7vhy1D1wcQGz+E=
github.com/shurcooL/httpgzip v0.0.0-20190720172056-320755c1c1b0/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/vearutop/statigz v1.1.1 h1:qUeYUA1xnX3wFs1vhsTcHY9LGAl9XBUt4eNr62fZ5FY=
github.com/vearutop/statigz v1.1.1/go.mod h1:kyRG5JBG0J2bGxtNEvA2U8vXwpkhDDiPJvpOwAMTpbw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 h1:eDrdRpKgkcCqKZQwyZRyeFZgfqt37SL7Kv3tok06cKE=
Expand All @@ -18,3 +33,9 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190830172400-56125e7d709e h1:jlbOw43fjYcUlLDKNNmKTeCQFyjkKEW/iUK7w7017XE=
golang.org/x/tools v0.0.0-20190830172400-56125e7d709e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
49 changes: 49 additions & 0 deletions internal/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package internal

import (
"encoding/json"
"html/template"
"net/http"
"strings"

"github.com/swaggest/swgui"
)

// Handler handles swagger UI request.
type Handler struct {
swgui.Config

ConfigJson template.JS

tpl *template.Template
staticServer http.Handler
}

// NewHandlerWithConfig returns a HTTP handler for swagger UI.
func NewHandlerWithConfig(config swgui.Config, assetsBase, faviconBase string, staticServer http.Handler) *Handler {
config.BasePath = strings.TrimSuffix(config.BasePath, "/") + "/"

h := &Handler{
Config: config,
}
j, _ := json.Marshal(h.Config)
h.ConfigJson = template.JS(j)
h.tpl, _ = template.New("index").Parse(IndexTpl(assetsBase, faviconBase))
if staticServer != nil {
h.staticServer = http.StripPrefix(h.BasePath, staticServer)
}
return h
}

// ServeHTTP implements http.Handler interface to handle swagger UI request.
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if strings.TrimSuffix(r.URL.Path, "/") != strings.TrimSuffix(h.BasePath, "/") && h.staticServer != nil {
h.staticServer.ServeHTTP(w, r)
return
}

w.Header().Set("Content-Type", "text/html")
if err := h.tpl.Execute(w, h); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
6 changes: 4 additions & 2 deletions v3/index.tpl.go → internal/index.tpl.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package v3
package internal

var indexTpl = `
func IndexTpl(assetsBase, faviconBase string) string {
return `
<!DOCTYPE html>
<html lang="en">
<head>
Expand Down Expand Up @@ -103,3 +104,4 @@ var indexTpl = `
</body>
</html>
`
}
9 changes: 6 additions & 3 deletions v3/cdn.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

package v3

import "net/http"
import (
"github.com/swaggest/swgui/v3cdn"
"net/http"
)

var staticServer http.Handler

const (
assetsBase = "https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.38.0/"
faviconBase = "https://petstore.swagger.io/"
assetsBase = v3cdn.AssetsBase
faviconBase = v3cdn.FaviconBase
)
58 changes: 8 additions & 50 deletions v3/handler.go
Original file line number Diff line number Diff line change
@@ -1,65 +1,23 @@
package v3

import (
"encoding/json"
"html/template"
"net/http"
"strings"

"github.com/swaggest/swgui"
"github.com/swaggest/swgui/internal"
)

// Handler handles swagger UI request.
type Handler struct {
swgui.Config

ConfigJson template.JS

tpl *template.Template
staticServer http.Handler
}
type Handler = internal.Handler

// NewHandler returns a HTTP handler for swagger UI.
func NewHandler(title, swaggerJSONPath string, basePath string) *Handler {
h := &Handler{}
h.Title = title
h.SwaggerJSON = swaggerJSONPath
h.BasePath = strings.TrimSuffix(basePath, "/") + "/"

j, _ := json.Marshal(h.Config)
h.ConfigJson = template.JS(j)
h.tpl, _ = template.New("index").Parse(indexTpl)
if staticServer != nil {
h.staticServer = http.StripPrefix(basePath, staticServer)
}
return h
return NewHandlerWithConfig(swgui.Config{
Title: title,
SwaggerJSON: swaggerJSONPath,
BasePath: basePath,
})
}

// NewHandlerWithConfig returns a HTTP handler for swagger UI.
func NewHandlerWithConfig(config swgui.Config) *Handler {
config.BasePath = strings.TrimSuffix(config.BasePath, "/") + "/"

h := &Handler{
Config: config,
}
j, _ := json.Marshal(h.Config)
h.ConfigJson = template.JS(j)
h.tpl, _ = template.New("index").Parse(indexTpl)
if staticServer != nil {
h.staticServer = http.StripPrefix(h.BasePath, staticServer)
}
return h
}

// ServeHTTP implements http.Handler interface to handle swagger UI request.
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if strings.TrimSuffix(r.URL.Path, "/") != strings.TrimSuffix(h.BasePath, "/") && h.staticServer != nil {
h.staticServer.ServeHTTP(w, r)
return
}

w.Header().Set("Content-Type", "text/html")
if err := h.tpl.Execute(w, h); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
return internal.NewHandlerWithConfig(config, assetsBase, faviconBase, staticServer)
}
Loading

0 comments on commit 03f8d29

Please sign in to comment.