Merge pull request #24 from elvinchan/23
#23 Fix bug of matching path for spec
This commit is contained in:
commit
e4b714794f
@ -31,7 +31,7 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// ApiRoot with Echo instance
|
// ApiRoot with Echo instance
|
||||||
r := echoswagger.New(echo.New(), "doc/", nil)
|
r := echoswagger.New(echo.New(), "/doc", nil)
|
||||||
|
|
||||||
// Routes with parameters & responses
|
// Routes with parameters & responses
|
||||||
r.POST("/", createUser).
|
r.POST("/", createUser).
|
||||||
@ -56,7 +56,7 @@ func createUser(c echo.Context) error {
|
|||||||
## Usage
|
## Usage
|
||||||
#### Create a `ApiRoot` with `New()`, which is a wrapper of `echo.New()`
|
#### Create a `ApiRoot` with `New()`, which is a wrapper of `echo.New()`
|
||||||
```
|
```
|
||||||
r := echoswagger.New(echo.New(), "doc/", nil)
|
r := echoswagger.New(echo.New(), "/doc", nil)
|
||||||
```
|
```
|
||||||
You can use the result `ApiRoot` instance to:
|
You can use the result `ApiRoot` instance to:
|
||||||
- Setup Security definitions, request/response Content-Types, UI options, Scheme, etc.
|
- Setup Security definitions, request/response Content-Types, UI options, Scheme, etc.
|
||||||
|
@ -31,7 +31,7 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// ApiRoot with Echo instance
|
// ApiRoot with Echo instance
|
||||||
r := echoswagger.New(echo.New(), "doc/", nil)
|
r := echoswagger.New(echo.New(), "/doc", nil)
|
||||||
|
|
||||||
// Routes with parameters & responses
|
// Routes with parameters & responses
|
||||||
r.POST("/", createUser).
|
r.POST("/", createUser).
|
||||||
@ -56,7 +56,7 @@ func createUser(c echo.Context) error {
|
|||||||
## 用法
|
## 用法
|
||||||
#### 用`New()`创建`ApiRoot`,此方法是对`echo.New()`方法的封装
|
#### 用`New()`创建`ApiRoot`,此方法是对`echo.New()`方法的封装
|
||||||
```
|
```
|
||||||
r := echoswagger.New(echo.New(), "/v1", "doc/", nil)
|
r := echoswagger.New(echo.New(), "/doc", nil)
|
||||||
```
|
```
|
||||||
你可以用这个`ApiRoot`来:
|
你可以用这个`ApiRoot`来:
|
||||||
- 设置Security定义, 请求/响应Content-Type,UI选项,Scheme等。
|
- 设置Security定义, 请求/响应Content-Type,UI选项,Scheme等。
|
||||||
|
16
assets.go
16
assets.go
@ -51,11 +51,23 @@ const SwaggerUIContent = `{{define "swagger"}}
|
|||||||
if (!window.location.pathname.endsWith("/")) {
|
if (!window.location.pathname.endsWith("/")) {
|
||||||
specPath = "/" + specPath
|
specPath = "/" + specPath
|
||||||
}
|
}
|
||||||
var spec = "{{.spec}}"
|
var specStr = "{{.spec}}"
|
||||||
|
var spec = specStr ? JSON.parse(specStr) : undefined
|
||||||
|
if (spec) {
|
||||||
|
spec.host = window.location.host
|
||||||
|
var docPath = "{{.docPath}}"
|
||||||
|
var basePath = window.location.pathname
|
||||||
|
if (!docPath.endsWith("/")) { docPath += "/" }
|
||||||
|
if (!basePath.endsWith("/")) { basePath += "/" }
|
||||||
|
if (basePath.endsWith(docPath)) {
|
||||||
|
basePath = basePath.slice(0, -docPath.length)
|
||||||
|
}
|
||||||
|
spec.basePath = basePath
|
||||||
|
}
|
||||||
// Build a system
|
// Build a system
|
||||||
const ui = SwaggerUIBundle({
|
const ui = SwaggerUIBundle({
|
||||||
url: window.location.origin+window.location.pathname+specPath,
|
url: window.location.origin+window.location.pathname+specPath,
|
||||||
spec: spec ? JSON.parse(spec) : undefined,
|
spec: spec,
|
||||||
dom_id: '#swagger-ui',
|
dom_id: '#swagger-ui',
|
||||||
deepLinking: true,
|
deepLinking: true,
|
||||||
presets: [
|
presets: [
|
||||||
|
@ -36,7 +36,7 @@ func initServer() echoswagger.ApiRoot {
|
|||||||
|
|
||||||
se.SetExternalDocs("Find out more about Swagger", "http://swagger.io").
|
se.SetExternalDocs("Find out more about Swagger", "http://swagger.io").
|
||||||
SetResponseContentType("application/xml", "application/json").
|
SetResponseContentType("application/xml", "application/json").
|
||||||
SetUI(echoswagger.UISetting{HideTop: true}).
|
SetUI(echoswagger.UISetting{DetachSpec: true, HideTop: true}).
|
||||||
SetScheme("https", "http")
|
SetScheme("https", "http")
|
||||||
|
|
||||||
PetController{}.Init(se.Group("pet", "/pet"))
|
PetController{}.Init(se.Group("pet", "/pet"))
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
},
|
},
|
||||||
"version": "1.0.0"
|
"version": "1.0.0"
|
||||||
},
|
},
|
||||||
"host": "example.com",
|
|
||||||
"basePath": "/",
|
|
||||||
"schemes": [
|
"schemes": [
|
||||||
"https",
|
"https",
|
||||||
"http"
|
"http"
|
||||||
|
@ -59,6 +59,7 @@ func (r *Root) docHandler(docPath string) echo.HandlerFunc {
|
|||||||
return c.String(http.StatusInternalServerError, err.Error())
|
return c.String(http.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
params["spec"] = string(b)
|
params["spec"] = string(b)
|
||||||
|
params["docPath"] = docPath
|
||||||
params["hideTop"] = true
|
params["hideTop"] = true
|
||||||
} else {
|
} else {
|
||||||
params["hideTop"] = r.ui.HideTop
|
params["hideTop"] = r.ui.HideTop
|
||||||
|
23
spec.go
23
spec.go
@ -21,11 +21,20 @@ func (r *Root) specHandler(docPath string) echo.HandlerFunc {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return c.String(http.StatusInternalServerError, err.Error())
|
return c.String(http.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
|
var basePath string
|
||||||
|
if uri, err := url.ParseRequestURI(c.Request().Referer()); err == nil {
|
||||||
|
basePath = trimSuffixSlash(uri.Path, docPath)
|
||||||
|
spec.Host = uri.Host
|
||||||
|
} else {
|
||||||
|
basePath = trimSuffixSlash(c.Request().URL.Path, connectPath(docPath, SpecName))
|
||||||
|
spec.Host = c.Request().Host
|
||||||
|
}
|
||||||
|
spec.BasePath = basePath
|
||||||
return c.JSON(http.StatusOK, spec)
|
return c.JSON(http.StatusOK, spec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate swagger spec data
|
// Generate swagger spec data, without host & basePath info
|
||||||
func (r *Root) GetSpec(c echo.Context, docPath string) (Swagger, error) {
|
func (r *Root) GetSpec(c echo.Context, docPath string) (Swagger, error) {
|
||||||
r.once.Do(func() {
|
r.once.Do(func() {
|
||||||
r.err = r.genSpec(c)
|
r.err = r.genSpec(c)
|
||||||
@ -34,17 +43,7 @@ func (r *Root) GetSpec(c echo.Context, docPath string) (Swagger, error) {
|
|||||||
if r.err != nil {
|
if r.err != nil {
|
||||||
return Swagger{}, r.err
|
return Swagger{}, r.err
|
||||||
}
|
}
|
||||||
swagger := *r.spec
|
return *r.spec, nil
|
||||||
var basePath string
|
|
||||||
if uri, err := url.ParseRequestURI(c.Request().Referer()); err == nil {
|
|
||||||
basePath = trimSuffixSlash(uri.Path, docPath)
|
|
||||||
swagger.Host = uri.Host
|
|
||||||
} else {
|
|
||||||
basePath = trimSuffixSlash(c.Request().URL.Path, connectPath(docPath, SpecName))
|
|
||||||
swagger.Host = c.Request().Host
|
|
||||||
}
|
|
||||||
swagger.BasePath = connectPath(basePath)
|
|
||||||
return swagger, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Root) genSpec(c echo.Context) error {
|
func (r *Root) genSpec(c echo.Context) error {
|
||||||
|
33
spec_test.go
33
spec_test.go
@ -20,7 +20,7 @@ func TestSpec(t *testing.T) {
|
|||||||
req := httptest.NewRequest(echo.GET, "/doc/swagger.json", nil)
|
req := httptest.NewRequest(echo.GET, "/doc/swagger.json", nil)
|
||||||
rec := httptest.NewRecorder()
|
rec := httptest.NewRecorder()
|
||||||
c := e.NewContext(req, rec)
|
c := e.NewContext(req, rec)
|
||||||
j := `{"swagger":"2.0","info":{"title":"Project APIs","version":""},"host":"example.com","basePath":"/","paths":{}}`
|
j := `{"swagger":"2.0","info":{"title":"Project APIs","version":""},"host":"example.com","paths":{}}`
|
||||||
if assert.NoError(t, r.(*Root).specHandler("/doc/")(c)) {
|
if assert.NoError(t, r.(*Root).specHandler("/doc/")(c)) {
|
||||||
assert.Equal(t, http.StatusOK, rec.Code)
|
assert.Equal(t, http.StatusOK, rec.Code)
|
||||||
assert.JSONEq(t, j, rec.Body.String())
|
assert.JSONEq(t, j, rec.Body.String())
|
||||||
@ -33,7 +33,22 @@ func TestSpec(t *testing.T) {
|
|||||||
req := httptest.NewRequest(echo.GET, "/doc/swagger.json", nil)
|
req := httptest.NewRequest(echo.GET, "/doc/swagger.json", nil)
|
||||||
rec := httptest.NewRecorder()
|
rec := httptest.NewRecorder()
|
||||||
c := e.NewContext(req, rec)
|
c := e.NewContext(req, rec)
|
||||||
j := `{"swagger":"2.0","info":{"title":"Project APIs","version":""},"host":"example.com","basePath":"/","paths":{}}`
|
j := `{"swagger":"2.0","info":{"title":"Project APIs","version":""},"paths":{}}`
|
||||||
|
s, err := r.(*Root).GetSpec(c, "/doc/")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
rs, err := json.Marshal(s)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.JSONEq(t, j, string(rs))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("BasicIntegrated", func(t *testing.T) {
|
||||||
|
r := prepareApiRoot()
|
||||||
|
r.SetUI(UISetting{DetachSpec: false})
|
||||||
|
e := r.(*Root).echo
|
||||||
|
req := httptest.NewRequest(echo.GET, "/doc", nil)
|
||||||
|
rec := httptest.NewRecorder()
|
||||||
|
c := e.NewContext(req, rec)
|
||||||
|
j := `{"swagger":"2.0","info":{"title":"Project APIs","version":""},"paths":{}}`
|
||||||
s, err := r.(*Root).GetSpec(c, "/doc/")
|
s, err := r.(*Root).GetSpec(c, "/doc/")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
rs, err := json.Marshal(s)
|
rs, err := json.Marshal(s)
|
||||||
@ -83,7 +98,7 @@ func TestSpec(t *testing.T) {
|
|||||||
req := httptest.NewRequest(echo.GET, "/doc/swagger.json", nil)
|
req := httptest.NewRequest(echo.GET, "/doc/swagger.json", nil)
|
||||||
rec := httptest.NewRecorder()
|
rec := httptest.NewRecorder()
|
||||||
c := e.NewContext(req, rec)
|
c := e.NewContext(req, rec)
|
||||||
j := `{"swagger":"2.0","info":{"title":"Project APIs","version":""},"host":"example.com","basePath":"/","paths":{"/ping":{"get":{"responses":{"default":{"description":"successful operation"}}}},"/users/{id}":{"delete":{"tags":["Users"],"responses":{"default":{"description":"successful operation"}}}}},"tags":[{"name":"Users"}]}`
|
j := `{"swagger":"2.0","info":{"title":"Project APIs","version":""},"host":"example.com","paths":{"/ping":{"get":{"responses":{"default":{"description":"successful operation"}}}},"/users/{id}":{"delete":{"tags":["Users"],"responses":{"default":{"description":"successful operation"}}}}},"tags":[{"name":"Users"}]}`
|
||||||
if assert.NoError(t, r.(*Root).specHandler("/doc")(c)) {
|
if assert.NoError(t, r.(*Root).specHandler("/doc")(c)) {
|
||||||
assert.Equal(t, http.StatusOK, rec.Code)
|
assert.Equal(t, http.StatusOK, rec.Code)
|
||||||
assert.JSONEq(t, j, rec.Body.String())
|
assert.JSONEq(t, j, rec.Body.String())
|
||||||
@ -105,21 +120,21 @@ func TestReferer(t *testing.T) {
|
|||||||
host: "localhost:1323",
|
host: "localhost:1323",
|
||||||
docPath: "/doc",
|
docPath: "/doc",
|
||||||
name: "A",
|
name: "A",
|
||||||
basePath: "/",
|
basePath: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
referer: "http://localhost:1323/doc",
|
referer: "http://localhost:1323/doc",
|
||||||
host: "localhost:1323",
|
host: "localhost:1323",
|
||||||
docPath: "/doc/",
|
docPath: "/doc/",
|
||||||
name: "B",
|
name: "B",
|
||||||
basePath: "/",
|
basePath: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
referer: "http://localhost:1323/doc/",
|
referer: "http://localhost:1323/doc/",
|
||||||
host: "localhost:1323",
|
host: "localhost:1323",
|
||||||
docPath: "/doc",
|
docPath: "/doc",
|
||||||
name: "C",
|
name: "C",
|
||||||
basePath: "/",
|
basePath: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
referer: "http://localhost:1323/api/v1/doc",
|
referer: "http://localhost:1323/api/v1/doc",
|
||||||
@ -133,14 +148,14 @@ func TestReferer(t *testing.T) {
|
|||||||
host: "127.0.0.1",
|
host: "127.0.0.1",
|
||||||
docPath: "/doc",
|
docPath: "/doc",
|
||||||
name: "E",
|
name: "E",
|
||||||
basePath: "/",
|
basePath: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
referer: "http://user:pass@github.com",
|
referer: "http://user:pass@github.com",
|
||||||
host: "github.com",
|
host: "github.com",
|
||||||
docPath: "/",
|
docPath: "/",
|
||||||
name: "F",
|
name: "F",
|
||||||
basePath: "/",
|
basePath: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
referer: "https://www.github.com/v1/docs/?q=1",
|
referer: "https://www.github.com/v1/docs/?q=1",
|
||||||
@ -154,7 +169,7 @@ func TestReferer(t *testing.T) {
|
|||||||
host: "www.github.com",
|
host: "www.github.com",
|
||||||
docPath: "",
|
docPath: "",
|
||||||
name: "H",
|
name: "H",
|
||||||
basePath: "/",
|
basePath: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
referer: "https://www.github.com/",
|
referer: "https://www.github.com/",
|
||||||
|
@ -12,7 +12,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func prepareApiRoot() ApiRoot {
|
func prepareApiRoot() ApiRoot {
|
||||||
return New(echo.New(), "doc/", nil)
|
r := New(echo.New(), "doc/", nil)
|
||||||
|
r.SetUI(UISetting{DetachSpec: true})
|
||||||
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareApiGroup() ApiGroup {
|
func prepareApiGroup() ApiGroup {
|
||||||
|
Loading…
Reference in New Issue
Block a user