From bec73c48363a0504467258ba6784889b78d06f24 Mon Sep 17 00:00:00 2001 From: Fedorov Vladimir Date: Sat, 20 Jun 2026 15:53:39 +0700 Subject: [PATCH] add swagger docs --- Makefile | 2 +- README.md | 1 + api/main.proto | 2 +- cmd/${REPO_NAME_SNAKE}/main.go | 21 ++++++++++++++++++++- go.mod | 5 ++++- 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 29c9dcd..45c856a 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ generate: --go_out ./proto --go_opt paths=source_relative \ --go-grpc_out ./proto --go-grpc_opt paths=source_relative \ --grpc-gateway_out ./proto --grpc-gateway_opt paths=source_relative,generate_unbound_methods=true \ - --openapiv2_out ./proto --openapiv2_opt allow_merge=true,merge_file_name=main \ + --openapiv2_out=./cmd/${REPO_NAME_SNAKE} --openapiv2_opt allow_merge=true,merge_file_name=main \ ./api/main.proto run: diff --git a/README.md b/README.md index 5a88c83..3516175 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # template Шалон для Go сервисов (имя репо должно быть snake case) +Методы http должны быть с префиксом /api Инициализация diff --git a/api/main.proto b/api/main.proto index d1c41a5..32c7d94 100644 --- a/api/main.proto +++ b/api/main.proto @@ -9,7 +9,7 @@ option go_package = "pkg/proto"; service ${REPO_NAME_PASCAL} { rpc Ping(PingReq) returns (PingRsp) { option (google.api.http) = { - get: "/ping" + get: "/api/ping" }; } } diff --git a/cmd/${REPO_NAME_SNAKE}/main.go b/cmd/${REPO_NAME_SNAKE}/main.go index f46d64f..11e5732 100644 --- a/cmd/${REPO_NAME_SNAKE}/main.go +++ b/cmd/${REPO_NAME_SNAKE}/main.go @@ -2,6 +2,7 @@ package main import ( "context" + _ "embed" "log" "net" "net/http" @@ -14,17 +15,24 @@ import ( "github.com/joho/godotenv" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" + + "github.com/swaggest/swgui/v5emb" ) +//go:embed main.swagger.json +var swaggerJSON []byte + func main() { _ = godotenv.Load() + // PostgreSQL dbpool, err := pgxpool.New(context.Background(), os.Getenv("DATABASE_URL")) if err != nil { log.Fatalf("Unable to create connection pool: %v\n", err) } defer dbpool.Close() + // Test request to DB var greeting string if err = dbpool.QueryRow(context.Background(), "select 'Hello, world!'").Scan(&greeting); err != nil { log.Fatalf("QueryRow failed: %v\n", err) @@ -63,11 +71,22 @@ func main() { log.Fatalln("Failed to register gateway:", err) } + mainMux := http.NewServeMux() + + docsHandler := v5emb.New("API", "/swagger/doc.json", "/docs/") + mainMux.Handle("/docs/", docsHandler) + mainMux.HandleFunc("/swagger/doc.json", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Write(swaggerJSON) + }) + mainMux.Handle("/api/", gwmux) + gwServer := &http.Server{ Addr: ":8090", - Handler: gwmux, + Handler: mainMux, } log.Println("Serving gRPC-Gateway on http://0.0.0.0:8090") + log.Println("Serving docs on http://0.0.0.0:8090/docs") log.Fatalln(gwServer.ListenAndServe()) } diff --git a/go.mod b/go.mod index 29576c8..d3cc04f 100644 --- a/go.mod +++ b/go.mod @@ -9,12 +9,15 @@ require ( google.golang.org/protobuf v1.34.1 ) +require github.com/vearutop/statigz v1.4.0 // indirect + require ( github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.10.0 // indirect + github.com/jackc/pgx/v5 v5.10.0 github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/joho/godotenv v1.5.1 + github.com/swaggest/swgui v1.8.8 golang.org/x/net v0.23.0 // indirect golang.org/x/sync v0.17.0 // indirect golang.org/x/sys v0.18.0 // indirect