add gozero swagger demo

This commit is contained in:
1278651995
2022-03-02 15:18:04 +08:00
parent df72b696da
commit 16732e3523
5 changed files with 456 additions and 1 deletions

60
example/gozero/main.go Normal file
View File

@ -0,0 +1,60 @@
package main
import (
"fmt"
"github.com/zeromicro/go-zero/core/conf"
"github.com/zeromicro/go-zero/rest"
"github.com/zeromicro/go-zero/rest/httpx"
"io/ioutil"
"log"
"net/http"
"os"
)
const config = `{"Name": "gozero", "Host": "0.0.0.0", "Port": 8888}`
func main() {
var c rest.RestConf
var env string = "dev"
err := conf.LoadConfigFromYamlBytes([]byte(config), &c)
if err != nil {
panic(err)
}
server, err := rest.NewServer(c)
if err != nil {
panic(err)
}
defer server.Stop()
swaggerFile, err := os.Open("example/gozero/swagger.json")
if err != nil {
log.Println(err)
}
defer swaggerFile.Close()
SwaggerByte, err := ioutil.ReadAll(swaggerFile)
if err != nil {
log.Println(err)
}
server.AddRoutes([]rest.Route{
{
Method: http.MethodGet,
Path: "/swagger",
Handler: Doc("/swagger", env),
},
{
Method: http.MethodGet,
Path: "/swagger-json",
Handler: func(writer http.ResponseWriter, request *http.Request) {
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
_, err := writer.Write(SwaggerByte)
if err != nil {
httpx.Error(writer, err)
}
},
},
})
fmt.Printf("Starting server at http://%s:%d...\n", c.Host, c.Port)
server.Start()
}

132
example/gozero/swagger.go Normal file
View File

@ -0,0 +1,132 @@
package main
import (
"bytes"
"html/template"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
)
type Opts func(*swaggerConfig)
// SwaggerOpts configures the Doc gmiddlewares.
type swaggerConfig struct {
// SpecURL the url to find the spec for
SpecURL string
// SwaggerHost for the js that generates the swagger ui site, defaults to: http://petstore.swagger.io/
SwaggerHost string
}
func Doc(basePath, env string, opts ...Opts) http.HandlerFunc {
config := &swaggerConfig{
SpecURL: basePath + "-json",
SwaggerHost: "https://petstore.swagger.io",
}
for _, opt := range opts {
opt(config)
}
// swagger html
tmpl := template.Must(template.New("swaggerdoc").Parse(swaggerTemplateV2))
buf := bytes.NewBuffer(nil)
err := tmpl.Execute(buf, config)
uiHTML := buf.Bytes()
// permission
needPermission := false
if env == "prod" {
needPermission = true
}
return func(rw http.ResponseWriter, r *http.Request) {
if err != nil {
httpx.Error(rw, err)
return
}
if r.URL.Path == basePath {
if needPermission {
rw.WriteHeader(http.StatusOK)
rw.Header().Set("Content-Type", "text/plain")
_, err = rw.Write([]byte("Swagger not open on prod"))
if err != nil {
httpx.Error(rw, err)
}
return
}
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
_, err = rw.Write(uiHTML)
if err != nil {
httpx.Error(rw, err)
return
}
rw.WriteHeader(http.StatusOK)
return
}
}
}
const swaggerTemplateV2 = `
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>API documentation</title>
<link rel="stylesheet" type="text/css" href="{{ .SwaggerHost }}/swagger-ui.css" >
<link rel="icon" type="image/png" href="{{ .SwaggerHost }}/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="{{ .SwaggerHost }}/favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="{{ .SwaggerHost }}/swagger-ui-bundle.js"> </script>
<script src="{{ .SwaggerHost }}/swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
"dom_id": "#swagger-ui",
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout",
validatorUrl: null,
url: "{{ .SpecURL }}",
})
// End Swagger UI call region
window.ui = ui
}
</script>
</body>
</html>`

236
example/gozero/swagger.json Normal file
View File

@ -0,0 +1,236 @@
{
"swagger": "2.0",
"info": {
"title": "",
"version": ""
},
"schemes": [
"http",
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/api/user/login": {
"post": {
"summary": "登录",
"operationId": "login",
"responses": {
"200": {
"description": "A successful response.",
"schema": {}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/LoginReq"
}
}
],
"tags": [
"user-api"
]
}
},
"/api/user/register": {
"post": {
"summary": "注册",
"description": "注册一个用户",
"operationId": "register",
"responses": {
"200": {
"description": "A successful response.",
"schema": {}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/RegisterReq"
}
}
],
"tags": [
"user-api"
]
}
},
"/api/user/search": {
"get": {
"summary": "用户搜索",
"operationId": "searchUser",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/UserSearchReply"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/UserSearchReq"
}
}
],
"tags": [
"user-api"
]
}
},
"/api/user/{id}": {
"get": {
"summary": "获取用户信息",
"operationId": "getUserInfo",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/UserInfoReply"
}
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/UserInfoReq"
}
}
],
"tags": [
"user-api"
]
}
},
"/user/ping": {
"get": {
"operationId": "ping",
"responses": {
"200": {
"description": "A successful response.",
"schema": {}
}
},
"tags": [
"greet"
]
}
}
},
"definitions": {
"LoginReq": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"password": {
"type": "string"
}
},
"title": "LoginReq"
},
"RegisterReq": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"password": {
"type": "string"
},
"mobile": {
"type": "string"
}
},
"title": "RegisterReq"
},
"UserInfoReply": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer",
"format": "int32"
},
"birthday": {
"type": "string"
},
"description": {
"type": "string"
},
"tag": {
"type": "array",
"items": {
"type": "string"
}
}
},
"title": "UserInfoReply"
},
"UserInfoReq": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
},
"title": "UserInfoReq"
},
"UserSearchReply": {
"type": "object",
"properties": {
"KeyWord": {
"type": "array",
"items": {
"$ref": "#/definitions/UserInfoReply"
}
}
},
"title": "UserSearchReply"
},
"UserSearchReq": {
"type": "object",
"properties": {
"keyWord": {
"type": "string"
}
},
"title": "UserSearchReq"
}
},
"securityDefinitions": {
"apiKey": {
"type": "apiKey",
"description": "Enter JWT Bearer token **_only_**",
"name": "Authorization",
"in": "header"
}
}
}