handler.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package swagger_api
  2. import (
  3. "embed"
  4. "encoding/json"
  5. "net/http"
  6. "net/url"
  7. "github.com/go-kratos/kratos/v2/api/metadata"
  8. "github.com/go-kratos/kratos/v2/transport/http/binding"
  9. "github.com/gorilla/mux"
  10. )
  11. //go:embed q/swagger-ui/*
  12. var staticFS embed.FS
  13. // NewHandler creates a traditional handler with service selection dropdown
  14. func NewHandler(servicesList []string, skipError bool) http.Handler {
  15. service := New(skipError)
  16. r := mux.NewRouter()
  17. r.HandleFunc("/q/services", func(w http.ResponseWriter, r *http.Request) {
  18. if len(servicesList) > 0 {
  19. w.Header().Set("Content-Type", "application/json")
  20. w.WriteHeader(200)
  21. reply := map[string][]string{
  22. "services": servicesList,
  23. }
  24. json.NewEncoder(w).Encode(reply)
  25. } else {
  26. services, err := service.ListServices(r.Context(), &metadata.ListServicesRequest{})
  27. if err != nil {
  28. w.WriteHeader(500)
  29. w.Write([]byte(err.Error()))
  30. return
  31. }
  32. w.Header().Set("Content-Type", "application/json")
  33. w.WriteHeader(200)
  34. json.NewEncoder(w).Encode(services)
  35. }
  36. }).Methods("GET")
  37. r.HandleFunc("/q/service/{name}", func(w http.ResponseWriter, r *http.Request) {
  38. raws := mux.Vars(r)
  39. vars := make(url.Values, len(raws))
  40. for k, v := range raws {
  41. vars[k] = []string{v}
  42. }
  43. var in metadata.GetServiceDescRequest
  44. if err := binding.BindQuery(vars, &in); err != nil {
  45. w.WriteHeader(400)
  46. w.Write([]byte(err.Error()))
  47. return
  48. }
  49. content, err := service.GetServiceOpenAPI(r.Context(), &in)
  50. if err != nil {
  51. w.WriteHeader(500)
  52. w.Write([]byte(err.Error()))
  53. return
  54. }
  55. w.Header().Set("Content-Type", "application/json")
  56. w.WriteHeader(200)
  57. w.Write([]byte(content))
  58. }).Methods("GET")
  59. staticServer := http.FileServer(http.FS(staticFS))
  60. sh := http.StripPrefix("", staticServer)
  61. r.PathPrefix("/q/swagger-ui").Handler(sh)
  62. return r
  63. }
  64. // NewMergedHandler creates a handler that shows all services merged in one page
  65. func NewMergedHandler(servicesList []string, skipError bool) http.Handler {
  66. service := New(skipError)
  67. r := mux.NewRouter()
  68. // Return a single "merged" service for Swagger UI to load
  69. r.HandleFunc("/q/services", func(w http.ResponseWriter, r *http.Request) {
  70. w.Header().Set("Content-Type", "application/json")
  71. w.WriteHeader(200)
  72. reply := map[string][]string{
  73. "services": {"all"},
  74. }
  75. json.NewEncoder(w).Encode(reply)
  76. }).Methods("GET")
  77. // Handle the merged service request
  78. r.HandleFunc("/q/service/{name}", func(w http.ResponseWriter, r *http.Request) {
  79. raws := mux.Vars(r)
  80. serviceName := raws["name"]
  81. // Only handle "all" request
  82. if serviceName != "all" {
  83. w.WriteHeader(404)
  84. w.Write([]byte("only 'all' is supported in merged mode"))
  85. return
  86. }
  87. content, err := service.GetAllServicesOpenAPI(r.Context(), servicesList)
  88. if err != nil {
  89. w.WriteHeader(500)
  90. w.Write([]byte(err.Error()))
  91. return
  92. }
  93. w.Header().Set("Content-Type", "application/json")
  94. w.WriteHeader(200)
  95. w.Write([]byte(content))
  96. }).Methods("GET")
  97. staticServer := http.FileServer(http.FS(staticFS))
  98. sh := http.StripPrefix("", staticServer)
  99. r.PathPrefix("/q/swagger-ui").Handler(sh)
  100. return r
  101. }