package swagger_api import ( "embed" "encoding/json" "net/http" "net/url" "github.com/go-kratos/kratos/v2/api/metadata" "github.com/go-kratos/kratos/v2/transport/http/binding" "github.com/gorilla/mux" ) //go:embed q/swagger-ui/* var staticFS embed.FS // NewHandler creates a traditional handler with service selection dropdown func NewHandler(servicesList []string, skipError bool) http.Handler { service := New(skipError) r := mux.NewRouter() r.HandleFunc("/q/services", func(w http.ResponseWriter, r *http.Request) { if len(servicesList) > 0 { w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) reply := map[string][]string{ "services": servicesList, } json.NewEncoder(w).Encode(reply) } else { services, err := service.ListServices(r.Context(), &metadata.ListServicesRequest{}) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) json.NewEncoder(w).Encode(services) } }).Methods("GET") r.HandleFunc("/q/service/{name}", func(w http.ResponseWriter, r *http.Request) { raws := mux.Vars(r) vars := make(url.Values, len(raws)) for k, v := range raws { vars[k] = []string{v} } var in metadata.GetServiceDescRequest if err := binding.BindQuery(vars, &in); err != nil { w.WriteHeader(400) w.Write([]byte(err.Error())) return } content, err := service.GetServiceOpenAPI(r.Context(), &in) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) w.Write([]byte(content)) }).Methods("GET") staticServer := http.FileServer(http.FS(staticFS)) sh := http.StripPrefix("", staticServer) r.PathPrefix("/q/swagger-ui").Handler(sh) return r } // NewMergedHandler creates a handler that shows all services merged in one page // title: the title for the merged API document // description: the description for the merged API document func NewMergedHandler(servicesList []string, title, description string, skipError bool) http.Handler { service := New(skipError) r := mux.NewRouter() // Return a single "merged" service for Swagger UI to load r.HandleFunc("/q/services", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) reply := map[string][]string{ "services": {"all"}, } json.NewEncoder(w).Encode(reply) }).Methods("GET") // Handle the merged service request r.HandleFunc("/q/service/{name}", func(w http.ResponseWriter, r *http.Request) { raws := mux.Vars(r) serviceName := raws["name"] // Only handle "all" request if serviceName != "all" { w.WriteHeader(404) w.Write([]byte("only 'all' is supported in merged mode")) return } content, err := service.GetAllServicesOpenAPI(r.Context(), servicesList, title, description) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) w.Write([]byte(content)) }).Methods("GET") staticServer := http.FileServer(http.FS(staticFS)) sh := http.StripPrefix("", staticServer) r.PathPrefix("/q/swagger-ui").Handler(sh) return r }