chore: add multiple api example (#207)
* chore: add multiple api example * chore: update README.md
This commit is contained in:
parent
bd7f2153bf
commit
88c9ed2643
|
|
@ -143,6 +143,9 @@ Demo project tree, `swag init` is run at relative `.`
|
||||||
└── main.go
|
└── main.go
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Multiple APIs
|
||||||
|
This feature where introduced in swag v1.7.9
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
You can configure Swagger using different configuration options
|
You can configure Swagger using different configuration options
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
# Multiple API feature
|
||||||
|
Since swag 1.7.9 we are allowing registration of multiple endpoints into the same server.
|
||||||
|
|
||||||
|
Generate documentation for v1 endpoints
|
||||||
|
```shell
|
||||||
|
swag i -g main.go -dir api/v1 --instanceName v1
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Generate documentation for v2 endpoints
|
||||||
|
```shell
|
||||||
|
swag i -g main.go -dir api/v2 --instanceName v2
|
||||||
|
```
|
||||||
|
|
||||||
|
Run example
|
||||||
|
```shell
|
||||||
|
go run main.go
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can access the v1 swagger here [http://localhost:8080/swagger/v1/index.html](http://localhost:8080/swagger/v1/index.html) ,
|
||||||
|
and v2 swagger here [http://localhost:8080/swagger/v2/index.html](http://localhost:8080/swagger/v2/index.html)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Book struct {
|
||||||
|
ID int `json:"id,omitempty"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Author string `json:"author"`
|
||||||
|
Year *uint16 `json:"year"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// @Summary Get a list of books in the the store
|
||||||
|
// @Description get string by ID
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {array} Book "ok"
|
||||||
|
// @Router /books [get]
|
||||||
|
func GetBooks(ctx *gin.Context) {
|
||||||
|
ctx.JSON(200, []Book{
|
||||||
|
{ID: 1, Title: "Book 1", Author: "Author 1", Year: nil},
|
||||||
|
{ID: 2, Title: "Book 2", Author: "Author 2", Year: nil},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @title Swagger Example API
|
||||||
|
// @version 1.0
|
||||||
|
// @description This is a sample server.
|
||||||
|
// @termsOfService http://swagger.io/terms/
|
||||||
|
|
||||||
|
// @contact.name API Support
|
||||||
|
// @contact.url http://www.swagger.io/support
|
||||||
|
// @contact.email support@swagger.io
|
||||||
|
|
||||||
|
// @license.name Apache 2.0
|
||||||
|
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
|
// @BasePath /v1
|
||||||
|
|
||||||
|
func Register(router *gin.Engine) {
|
||||||
|
v1 := router.Group("v1")
|
||||||
|
|
||||||
|
v1.GET("/books", GetBooks)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Book struct {
|
||||||
|
ID int `json:"id,omitempty"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Author string `json:"author"`
|
||||||
|
Year *uint16 `json:"year"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// @Summary Get a list of books in the the store
|
||||||
|
// @Description get string by ID
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {array} Book "ok"
|
||||||
|
// @Router /books [get]
|
||||||
|
func GetBooks(ctx *gin.Context) {
|
||||||
|
ctx.JSON(200, []Book{
|
||||||
|
{ID: 1, Title: "Book 3", Author: "Author 3", Year: nil},
|
||||||
|
{ID: 2, Title: "Book 4", Author: "Author 4", Year: nil},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @title Swagger Example API
|
||||||
|
// @version 2.0
|
||||||
|
// @description This is a sample server.
|
||||||
|
// @termsOfService http://swagger.io/terms/
|
||||||
|
|
||||||
|
// @contact.name API Support
|
||||||
|
// @contact.url http://www.swagger.io/support
|
||||||
|
// @contact.email support@swagger.io
|
||||||
|
|
||||||
|
// @license.name Apache 2.0
|
||||||
|
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
|
// @BasePath /v2
|
||||||
|
|
||||||
|
func Register(router *gin.Engine) {
|
||||||
|
v2 := router.Group("v2")
|
||||||
|
|
||||||
|
v2.GET("/books", GetBooks)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
// Package docs GENERATED BY SWAG; DO NOT EDIT
|
||||||
|
// This file was generated by swaggo/swag
|
||||||
|
package docs
|
||||||
|
|
||||||
|
import "github.com/swaggo/swag"
|
||||||
|
|
||||||
|
const docTemplatev1 = `{
|
||||||
|
"schemes": {{ marshal .Schemes }},
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"description": "{{escape .Description}}",
|
||||||
|
"title": "{{.Title}}",
|
||||||
|
"termsOfService": "http://swagger.io/terms/",
|
||||||
|
"contact": {
|
||||||
|
"name": "API Support",
|
||||||
|
"url": "http://www.swagger.io/support",
|
||||||
|
"email": "support@swagger.io"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "Apache 2.0",
|
||||||
|
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||||
|
},
|
||||||
|
"version": "{{.Version}}"
|
||||||
|
},
|
||||||
|
"host": "{{.Host}}",
|
||||||
|
"basePath": "{{.BasePath}}",
|
||||||
|
"paths": {
|
||||||
|
"/books": {
|
||||||
|
"get": {
|
||||||
|
"description": "get string by ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"summary": "Get a list of books in the the store",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "ok",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/v1.Book"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"definitions": {
|
||||||
|
"v1.Book": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"author": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"year": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
// SwaggerInfov1 holds exported Swagger Info so clients can modify it
|
||||||
|
var SwaggerInfov1 = &swag.Spec{
|
||||||
|
Version: "1.0",
|
||||||
|
Host: "",
|
||||||
|
BasePath: "/v1",
|
||||||
|
Schemes: []string{},
|
||||||
|
Title: "Swagger Example API",
|
||||||
|
Description: "This is a sample server.",
|
||||||
|
InfoInstanceName: "v1",
|
||||||
|
SwaggerTemplate: docTemplatev1,
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
swag.Register(SwaggerInfov1.InstanceName(), SwaggerInfov1)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
{
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"description": "This is a sample server.",
|
||||||
|
"title": "Swagger Example API",
|
||||||
|
"termsOfService": "http://swagger.io/terms/",
|
||||||
|
"contact": {
|
||||||
|
"name": "API Support",
|
||||||
|
"url": "http://www.swagger.io/support",
|
||||||
|
"email": "support@swagger.io"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "Apache 2.0",
|
||||||
|
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||||
|
},
|
||||||
|
"version": "1.0"
|
||||||
|
},
|
||||||
|
"basePath": "/v1",
|
||||||
|
"paths": {
|
||||||
|
"/books": {
|
||||||
|
"get": {
|
||||||
|
"description": "get string by ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"summary": "Get a list of books in the the store",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "ok",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/v1.Book"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"definitions": {
|
||||||
|
"v1.Book": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"author": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"year": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
basePath: /v1
|
||||||
|
definitions:
|
||||||
|
v1.Book:
|
||||||
|
properties:
|
||||||
|
author:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
year:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
info:
|
||||||
|
contact:
|
||||||
|
email: support@swagger.io
|
||||||
|
name: API Support
|
||||||
|
url: http://www.swagger.io/support
|
||||||
|
description: This is a sample server.
|
||||||
|
license:
|
||||||
|
name: Apache 2.0
|
||||||
|
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
termsOfService: http://swagger.io/terms/
|
||||||
|
title: Swagger Example API
|
||||||
|
version: "1.0"
|
||||||
|
paths:
|
||||||
|
/books:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: get string by ID
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ok
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/v1.Book'
|
||||||
|
type: array
|
||||||
|
summary: Get a list of books in the the store
|
||||||
|
swagger: "2.0"
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
// Package docs GENERATED BY SWAG; DO NOT EDIT
|
||||||
|
// This file was generated by swaggo/swag
|
||||||
|
package docs
|
||||||
|
|
||||||
|
import "github.com/swaggo/swag"
|
||||||
|
|
||||||
|
const docTemplatev2 = `{
|
||||||
|
"schemes": {{ marshal .Schemes }},
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"description": "{{escape .Description}}",
|
||||||
|
"title": "{{.Title}}",
|
||||||
|
"termsOfService": "http://swagger.io/terms/",
|
||||||
|
"contact": {
|
||||||
|
"name": "API Support",
|
||||||
|
"url": "http://www.swagger.io/support",
|
||||||
|
"email": "support@swagger.io"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "Apache 2.0",
|
||||||
|
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||||
|
},
|
||||||
|
"version": "{{.Version}}"
|
||||||
|
},
|
||||||
|
"host": "{{.Host}}",
|
||||||
|
"basePath": "{{.BasePath}}",
|
||||||
|
"paths": {
|
||||||
|
"/books": {
|
||||||
|
"get": {
|
||||||
|
"description": "get string by ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"summary": "Get a list of books in the the store",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "ok",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/v2.Book"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"definitions": {
|
||||||
|
"v2.Book": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"author": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"year": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
// SwaggerInfov2 holds exported Swagger Info so clients can modify it
|
||||||
|
var SwaggerInfov2 = &swag.Spec{
|
||||||
|
Version: "2.0",
|
||||||
|
Host: "",
|
||||||
|
BasePath: "/v2",
|
||||||
|
Schemes: []string{},
|
||||||
|
Title: "Swagger Example API",
|
||||||
|
Description: "This is a sample server.",
|
||||||
|
InfoInstanceName: "v2",
|
||||||
|
SwaggerTemplate: docTemplatev2,
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
swag.Register(SwaggerInfov2.InstanceName(), SwaggerInfov2)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
{
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"description": "This is a sample server.",
|
||||||
|
"title": "Swagger Example API",
|
||||||
|
"termsOfService": "http://swagger.io/terms/",
|
||||||
|
"contact": {
|
||||||
|
"name": "API Support",
|
||||||
|
"url": "http://www.swagger.io/support",
|
||||||
|
"email": "support@swagger.io"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "Apache 2.0",
|
||||||
|
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||||
|
},
|
||||||
|
"version": "2.0"
|
||||||
|
},
|
||||||
|
"basePath": "/v2",
|
||||||
|
"paths": {
|
||||||
|
"/books": {
|
||||||
|
"get": {
|
||||||
|
"description": "get string by ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"summary": "Get a list of books in the the store",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "ok",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/v2.Book"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"definitions": {
|
||||||
|
"v2.Book": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"author": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"year": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
basePath: /v2
|
||||||
|
definitions:
|
||||||
|
v2.Book:
|
||||||
|
properties:
|
||||||
|
author:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
year:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
info:
|
||||||
|
contact:
|
||||||
|
email: support@swagger.io
|
||||||
|
name: API Support
|
||||||
|
url: http://www.swagger.io/support
|
||||||
|
description: This is a sample server.
|
||||||
|
license:
|
||||||
|
name: Apache 2.0
|
||||||
|
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
termsOfService: http://swagger.io/terms/
|
||||||
|
title: Swagger Example API
|
||||||
|
version: "2.0"
|
||||||
|
paths:
|
||||||
|
/books:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: get string by ID
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ok
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/v2.Book'
|
||||||
|
type: array
|
||||||
|
summary: Get a list of books in the the store
|
||||||
|
swagger: "2.0"
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
swaggerFiles "github.com/swaggo/files"
|
||||||
|
ginSwagger "github.com/swaggo/gin-swagger"
|
||||||
|
v1 "github.com/swaggo/gin-swagger/example/multiple/api/v1"
|
||||||
|
v2 "github.com/swaggo/gin-swagger/example/multiple/api/v2"
|
||||||
|
_ "github.com/swaggo/gin-swagger/example/multiple/docs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// New gin router
|
||||||
|
router := gin.New()
|
||||||
|
|
||||||
|
// Register api/v1 endpoints
|
||||||
|
v1.Register(router)
|
||||||
|
router.GET("/swagger/v1/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, ginSwagger.InstanceName("v1")))
|
||||||
|
|
||||||
|
// Register api/v2 endpoints
|
||||||
|
v2.Register(router)
|
||||||
|
router.GET("/swagger/v2/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, ginSwagger.InstanceName("v2")))
|
||||||
|
|
||||||
|
// Listen and Server in
|
||||||
|
_ = router.Run()
|
||||||
|
}
|
||||||
62
swagger.go
62
swagger.go
|
|
@ -36,36 +36,36 @@ type Config struct {
|
||||||
PersistAuthorization bool
|
PersistAuthorization bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Config) toSwaggerConfig() swaggerConfig {
|
func (config Config) toSwaggerConfig() swaggerConfig {
|
||||||
return swaggerConfig{
|
return swaggerConfig{
|
||||||
URL: c.URL,
|
URL: config.URL,
|
||||||
DeepLinking: c.DeepLinking,
|
DeepLinking: config.DeepLinking,
|
||||||
DocExpansion: c.DocExpansion,
|
DocExpansion: config.DocExpansion,
|
||||||
DefaultModelsExpandDepth: c.DefaultModelsExpandDepth,
|
DefaultModelsExpandDepth: config.DefaultModelsExpandDepth,
|
||||||
Oauth2RedirectURL: "`${window.location.protocol}//${window.location.host}$" +
|
Oauth2RedirectURL: "`${window.location.protocol}//${window.location.host}$" +
|
||||||
"{window.location.pathname.split('/').slice(0, window.location.pathname.split('/').length - 1).join('/')}" +
|
"{window.location.pathname.split('/').slice(0, window.location.pathname.split('/').length - 1).join('/')}" +
|
||||||
"/oauth2-redirect.html`",
|
"/oauth2-redirect.html`",
|
||||||
Title: c.Title,
|
Title: config.Title,
|
||||||
PersistAuthorization: c.PersistAuthorization,
|
PersistAuthorization: config.PersistAuthorization,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// URL presents the url pointing to API definition (normally swagger.json or swagger.yaml).
|
// URL presents the url pointing to API definition (normally swagger.json or swagger.yaml).
|
||||||
func URL(url string) func(c *Config) {
|
func URL(url string) func(*Config) {
|
||||||
return func(c *Config) {
|
return func(c *Config) {
|
||||||
c.URL = url
|
c.URL = url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DocExpansion list, full, none.
|
// DocExpansion list, full, none.
|
||||||
func DocExpansion(docExpansion string) func(c *Config) {
|
func DocExpansion(docExpansion string) func(*Config) {
|
||||||
return func(c *Config) {
|
return func(c *Config) {
|
||||||
c.DocExpansion = docExpansion
|
c.DocExpansion = docExpansion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepLinking set the swagger deep linking configuration.
|
// DeepLinking set the swagger deep linking configuration.
|
||||||
func DeepLinking(deepLinking bool) func(c *Config) {
|
func DeepLinking(deepLinking bool) func(*Config) {
|
||||||
return func(c *Config) {
|
return func(c *Config) {
|
||||||
c.DeepLinking = deepLinking
|
c.DeepLinking = deepLinking
|
||||||
}
|
}
|
||||||
|
|
@ -73,7 +73,7 @@ func DeepLinking(deepLinking bool) func(c *Config) {
|
||||||
|
|
||||||
// DefaultModelsExpandDepth set the default expansion depth for models
|
// DefaultModelsExpandDepth set the default expansion depth for models
|
||||||
// (set to -1 completely hide the models).
|
// (set to -1 completely hide the models).
|
||||||
func DefaultModelsExpandDepth(depth int) func(c *Config) {
|
func DefaultModelsExpandDepth(depth int) func(*Config) {
|
||||||
return func(c *Config) {
|
return func(c *Config) {
|
||||||
c.DefaultModelsExpandDepth = depth
|
c.DefaultModelsExpandDepth = depth
|
||||||
}
|
}
|
||||||
|
|
@ -81,39 +81,40 @@ func DefaultModelsExpandDepth(depth int) func(c *Config) {
|
||||||
|
|
||||||
// InstanceName set the instance name that was used to generate the swagger documents
|
// InstanceName set the instance name that was used to generate the swagger documents
|
||||||
// Defaults to swag.Name ("swagger").
|
// Defaults to swag.Name ("swagger").
|
||||||
func InstanceName(name string) func(c *Config) {
|
func InstanceName(name string) func(*Config) {
|
||||||
return func(c *Config) {
|
return func(c *Config) {
|
||||||
c.InstanceName = name
|
c.InstanceName = name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PersistAuthorization If set to true, it persists authorization data and it would not be lost on browser close/refresh
|
// PersistAuthorization Persist authorization information over browser close/refresh.
|
||||||
// Defaults to false.
|
// Defaults to false.
|
||||||
func PersistAuthorization(persistAuthorization bool) func(c *Config) {
|
func PersistAuthorization(persistAuthorization bool) func(*Config) {
|
||||||
return func(c *Config) {
|
return func(c *Config) {
|
||||||
c.PersistAuthorization = persistAuthorization
|
c.PersistAuthorization = persistAuthorization
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WrapHandler wraps `http.Handler` into `gin.HandlerFunc`.
|
// WrapHandler wraps `http.Handler` into `gin.HandlerFunc`.
|
||||||
func WrapHandler(handler *webdav.Handler, options ...func(c *Config)) gin.HandlerFunc {
|
func WrapHandler(handler *webdav.Handler, options ...func(*Config)) gin.HandlerFunc {
|
||||||
defaultConfig := Config{
|
var config = Config{
|
||||||
URL: "doc.json",
|
URL: "doc.json",
|
||||||
DeepLinking: true,
|
|
||||||
DocExpansion: "list",
|
DocExpansion: "list",
|
||||||
DefaultModelsExpandDepth: 1,
|
|
||||||
InstanceName: swag.Name,
|
InstanceName: swag.Name,
|
||||||
Title: "Swagger UI",
|
Title: "Swagger UI",
|
||||||
|
DefaultModelsExpandDepth: 1,
|
||||||
|
DeepLinking: true,
|
||||||
|
PersistAuthorization: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range options {
|
for _, c := range options {
|
||||||
c(&defaultConfig)
|
c(&config)
|
||||||
}
|
}
|
||||||
|
|
||||||
return CustomWrapHandler(&defaultConfig, handler)
|
return CustomWrapHandler(&config, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomWrapHandler wraps `http.Handler` into `gin.HandlerFunc`
|
// CustomWrapHandler wraps `http.Handler` into `gin.HandlerFunc`.
|
||||||
func CustomWrapHandler(config *Config, handler *webdav.Handler) gin.HandlerFunc {
|
func CustomWrapHandler(config *Config, handler *webdav.Handler) gin.HandlerFunc {
|
||||||
var once sync.Once
|
var once sync.Once
|
||||||
|
|
||||||
|
|
@ -126,10 +127,9 @@ func CustomWrapHandler(config *Config, handler *webdav.Handler) gin.HandlerFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a template with name
|
// create a template with name
|
||||||
t := template.New("swagger_index.html")
|
index, _ := template.New("swagger_index.html").Parse(swaggerIndexTpl)
|
||||||
index, _ := t.Parse(swagger_index_templ)
|
|
||||||
|
|
||||||
var rexp = regexp.MustCompile(`(.*)(index\.html|doc\.json|favicon-16x16\.png|favicon-32x32\.png|/oauth2-redirect\.html|swagger-ui\.css|swagger-ui\.css\.map|swagger-ui\.js|swagger-ui\.js\.map|swagger-ui-bundle\.js|swagger-ui-bundle\.js\.map|swagger-ui-standalone-preset\.js|swagger-ui-standalone-preset\.js\.map)[?|.]*`)
|
var matcher = regexp.MustCompile(`(.*)(index\.html|doc\.json|favicon-16x16\.png|favicon-32x32\.png|/oauth2-redirect\.html|swagger-ui\.css|swagger-ui\.css\.map|swagger-ui\.js|swagger-ui\.js\.map|swagger-ui-bundle\.js|swagger-ui-bundle\.js\.map|swagger-ui-standalone-preset\.js|swagger-ui-standalone-preset\.js\.map)[?|.]*`)
|
||||||
|
|
||||||
return func(ctx *gin.Context) {
|
return func(ctx *gin.Context) {
|
||||||
if ctx.Request.Method != http.MethodGet {
|
if ctx.Request.Method != http.MethodGet {
|
||||||
|
|
@ -138,7 +138,7 @@ func CustomWrapHandler(config *Config, handler *webdav.Handler) gin.HandlerFunc
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
matches := rexp.FindStringSubmatch(ctx.Request.RequestURI)
|
matches := matcher.FindStringSubmatch(ctx.Request.RequestURI)
|
||||||
|
|
||||||
if len(matches) != 3 {
|
if len(matches) != 3 {
|
||||||
ctx.String(http.StatusNotFound, http.StatusText(http.StatusNotFound))
|
ctx.String(http.StatusNotFound, http.StatusText(http.StatusNotFound))
|
||||||
|
|
@ -175,7 +175,7 @@ func CustomWrapHandler(config *Config, handler *webdav.Handler) gin.HandlerFunc
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.JSON(http.StatusOK, doc)
|
ctx.String(http.StatusOK, doc)
|
||||||
default:
|
default:
|
||||||
handler.ServeHTTP(ctx.Writer, ctx.Request)
|
handler.ServeHTTP(ctx.Writer, ctx.Request)
|
||||||
}
|
}
|
||||||
|
|
@ -183,7 +183,7 @@ func CustomWrapHandler(config *Config, handler *webdav.Handler) gin.HandlerFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisablingWrapHandler turn handler off
|
// DisablingWrapHandler turn handler off
|
||||||
// if specified environment variable passed
|
// if specified environment variable passed.
|
||||||
func DisablingWrapHandler(handler *webdav.Handler, envName string) gin.HandlerFunc {
|
func DisablingWrapHandler(handler *webdav.Handler, envName string) gin.HandlerFunc {
|
||||||
if os.Getenv(envName) != "" {
|
if os.Getenv(envName) != "" {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
|
|
@ -197,8 +197,8 @@ func DisablingWrapHandler(handler *webdav.Handler, envName string) gin.HandlerFu
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisablingCustomWrapHandler turn handler off
|
// DisablingCustomWrapHandler turn handler off
|
||||||
// if specified environment variable passed
|
// if specified environment variable passed.
|
||||||
func DisablingCustomWrapHandler(config *Config, h *webdav.Handler, envName string) gin.HandlerFunc {
|
func DisablingCustomWrapHandler(config *Config, handler *webdav.Handler, envName string) gin.HandlerFunc {
|
||||||
if os.Getenv(envName) != "" {
|
if os.Getenv(envName) != "" {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
// Simulate behavior when route unspecified and
|
// Simulate behavior when route unspecified and
|
||||||
|
|
@ -207,10 +207,10 @@ func DisablingCustomWrapHandler(config *Config, h *webdav.Handler, envName strin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CustomWrapHandler(config, h)
|
return CustomWrapHandler(config, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
const swagger_index_templ = `<!-- HTML for static distribution bundle build -->
|
const swaggerIndexTpl = `<!-- HTML for static distribution bundle build -->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package ginSwagger
|
package ginSwagger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -42,12 +43,18 @@ func TestWrapCustomHandler(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, http.StatusInternalServerError, performRequest(http.MethodGet, "/doc.json", router).Code)
|
assert.Equal(t, http.StatusInternalServerError, performRequest(http.MethodGet, "/doc.json", router).Code)
|
||||||
|
|
||||||
swag.Register(swag.Name, &mockedSwag{})
|
doc := &mockedSwag{}
|
||||||
|
swag.Register(swag.Name, doc)
|
||||||
|
|
||||||
w2 := performRequest(http.MethodGet, "/doc.json", router)
|
w2 := performRequest(http.MethodGet, "/doc.json", router)
|
||||||
assert.Equal(t, http.StatusOK, w2.Code)
|
assert.Equal(t, http.StatusOK, w2.Code)
|
||||||
assert.Equal(t, w2.Header()["Content-Type"][0], "application/json; charset=utf-8")
|
assert.Equal(t, w2.Header()["Content-Type"][0], "application/json; charset=utf-8")
|
||||||
|
|
||||||
|
// Perform body rendering validation
|
||||||
|
w2Body, err := ioutil.ReadAll(w2.Body)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, doc.ReadDoc(), string(w2Body))
|
||||||
|
|
||||||
w3 := performRequest(http.MethodGet, "/favicon-16x16.png", router)
|
w3 := performRequest(http.MethodGet, "/favicon-16x16.png", router)
|
||||||
assert.Equal(t, http.StatusOK, w3.Code)
|
assert.Equal(t, http.StatusOK, w3.Code)
|
||||||
assert.Equal(t, w3.Header()["Content-Type"][0], "image/png")
|
assert.Equal(t, w3.Header()["Content-Type"][0], "image/png")
|
||||||
|
|
@ -85,10 +92,10 @@ func TestDisablingWrapHandler(t *testing.T) {
|
||||||
|
|
||||||
router.GET("/disabling/*any", DisablingWrapHandler(swaggerFiles.Handler, disablingKey))
|
router.GET("/disabling/*any", DisablingWrapHandler(swaggerFiles.Handler, disablingKey))
|
||||||
|
|
||||||
assert.Equal(t, 404, performRequest(http.MethodGet, "/disabling/index.html", router).Code)
|
assert.Equal(t, http.StatusNotFound, performRequest(http.MethodGet, "/disabling/index.html", router).Code)
|
||||||
assert.Equal(t, 404, performRequest(http.MethodGet, "/disabling/doc.json", router).Code)
|
assert.Equal(t, http.StatusNotFound, performRequest(http.MethodGet, "/disabling/doc.json", router).Code)
|
||||||
assert.Equal(t, 404, performRequest(http.MethodGet, "/disabling/oauth2-redirect.html", router).Code)
|
assert.Equal(t, http.StatusNotFound, performRequest(http.MethodGet, "/disabling/oauth2-redirect.html", router).Code)
|
||||||
assert.Equal(t, 404, performRequest(http.MethodGet, "/disabling/notfound", router).Code)
|
assert.Equal(t, http.StatusNotFound, performRequest(http.MethodGet, "/disabling/notfound", router).Code)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDisablingCustomWrapHandler(t *testing.T) {
|
func TestDisablingCustomWrapHandler(t *testing.T) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue