@@ -2,6 +2,7 @@ package cmd
22
33import (
44 _ "embed"
5+ "encoding/json"
56 "fmt"
67 "html/template"
78 "io"
@@ -24,16 +25,30 @@ type Microservice struct {
2425 URL string `yaml:"url"`
2526}
2627
28+ type MicroserviceList struct {
29+ Name string
30+ Endpoint string
31+ Selected bool
32+ }
33+
34+ // OpenAPISpec represents the structure of the OpenAPI specification for extracting info fields.
35+ type OpenAPISpec struct {
36+ Info struct {
37+ ServiceTitle string `json:"title"`
38+ ServiceSummary string `json:"summary"`
39+ } `json:"info"`
40+ }
41+
2742// GetOASSpec retrieves the OpenAPI specification from the specified microservice URL
28- func GetOASSpec (url string ) ([]byte , error ) {
43+ func GetOASSpec (url string ) ([]byte , string , string , error ) {
2944 if ! strings .HasSuffix (url , "/" ) {
30- return nil , fmt .Errorf ("microservice URL doesn't have a trailing '/'" )
45+ return nil , "" , "" , fmt .Errorf ("microservice URL doesn't have a trailing '/'" )
3146 }
3247 requestURL := fmt .Sprintf ("%s%s" , url , apiSpecsPath )
3348 log .Debug ("Requesting " , requestURL )
3449 req , err := http .NewRequest ("GET" , requestURL , nil )
3550 if err != nil {
36- return nil , err
51+ return nil , "" , "" , err
3752 }
3853
3954 for key , value := range headers {
@@ -43,53 +58,47 @@ func GetOASSpec(url string) ([]byte, error) {
4358 client := & http.Client {}
4459 resp , err := client .Do (req )
4560 if err != nil {
46- return nil , err
61+ return nil , "" , "" , err
4762 }
4863 defer resp .Body .Close ()
4964
5065 if resp .StatusCode != http .StatusOK {
51- return nil , fmt .Errorf ("failed to retrieve OpenAPI spec: received status code %d" , resp .StatusCode )
66+ return nil , "" , "" , fmt .Errorf ("failed to retrieve OpenAPI spec: received status code %d" , resp .StatusCode )
5267 }
5368
5469 body , err := io .ReadAll (resp .Body )
5570 if err != nil {
56- return nil , err
71+ return nil , "" , "" , err
5772 }
5873
59- return body , nil
74+ var spec OpenAPISpec
75+ if err := json .Unmarshal (body , & spec ); err != nil {
76+ return nil , "" , "" , err
77+ }
78+
79+ return body , spec .Info .ServiceTitle , spec .Info .ServiceSummary , nil
6080}
6181
6282// GenerateHTML generates the HTML for viewing the OpenAPI spec using Swagger UI
63- func GenerateHTML (spec []byte , serviceURL string , selectedService string , message string ) (string , error ) {
64- type MicroserviceOption struct {
65- Name string
66- Selected bool
67- }
68-
83+ func GenerateHTML (spec []byte , microserviceList []MicroserviceList , serviceURL , selectedService , serviceSummary , message string ) (string , error ) {
6984 type SwaggerUIParams struct {
7085 Spec string
7186 Host string
7287 ProxyAddress string
7388 Headers map [string ]string
74- MicroserviceList []MicroserviceOption
89+ MicroserviceList []MicroserviceList
7590 SelectedService string
76- }
77-
78- microserviceOptions := []MicroserviceOption {}
79- for _ , ms := range services {
80- microserviceOptions = append (microserviceOptions , MicroserviceOption {
81- Name : ms .Name ,
82- Selected : ms .Name == selectedService ,
83- })
91+ ServiceSummary string
8492 }
8593
8694 params := SwaggerUIParams {
8795 Spec : string (spec ),
8896 Host : serviceURL ,
8997 ProxyAddress : proxyAddress + "/" ,
9098 Headers : headers ,
91- MicroserviceList : microserviceOptions ,
99+ MicroserviceList : microserviceList ,
92100 SelectedService : selectedService ,
101+ ServiceSummary : serviceSummary ,
93102 }
94103
95104 tmpl := htmlTemplate
@@ -116,33 +125,45 @@ func GenerateHTML(spec []byte, serviceURL string, selectedService string, messag
116125}
117126
118127func handler (w http.ResponseWriter , r * http.Request ) {
119- log .Debug ("path = " , r .URL .Path )
120- serviceName := strings .TrimPrefix (r .URL .Path , "/" )
121- log .Debug ("serviceName = " , serviceName )
122- microserviceURL := ""
128+ path := r .URL .Path
129+ log .Debug ("path = " , path )
130+
131+ message := ""
132+ var spec []byte
133+ var selectedSpec []byte
134+ var err error
135+ var serviceName , serviceSummary , microserviceURL string
136+
137+ microserviceList := []MicroserviceList {}
123138 for _ , service := range services {
124- if service .Name == serviceName {
139+ // Retrieve name and summary of each microservice to construct a drop-down list.
140+ spec , serviceName , serviceSummary , err = GetOASSpec (service .URL )
141+ if service .Endpoint == path {
125142 microserviceURL = service .URL
126- break
143+ // selectedSpec is the one which will be rendered by SwaggerUIBundle
144+ selectedSpec = spec
145+ if err != nil {
146+ message = "Could not retrieve OpenAPI spec: " + err .Error ()
147+ }
127148 }
149+ if err != nil {
150+ log .Error ("Could not retrieve OpenAPI spec: " + err .Error ())
151+ continue
152+ }
153+ microserviceList = append (microserviceList , MicroserviceList {
154+ Name : serviceName + " — " + serviceSummary ,
155+ Endpoint : service .Endpoint ,
156+ Selected : service .Endpoint == path ,
157+ })
128158 }
129159
130160 log .Debug ("microserviceURL = " , microserviceURL )
131161
132- message := ""
133- var spec []byte
134- var err error
135-
136162 if microserviceURL == "" {
137163 message = "Please select a service from the list."
138- } else {
139- spec , err = GetOASSpec (microserviceURL )
140- if err != nil {
141- message = "Could not retrieve OpenAPI spec: " + err .Error ()
142- }
143164 }
144165
145- html , err := GenerateHTML (spec , microserviceURL , serviceName , message )
166+ html , err := GenerateHTML (selectedSpec , microserviceList , microserviceURL , serviceName , serviceSummary , message )
146167 if err != nil {
147168 http .Error (w , "Could not generate HTML" , http .StatusInternalServerError )
148169 log .Error (err )
0 commit comments