@@ -4,9 +4,10 @@ import (
44 "bytes"
55 "encoding/json"
66 "fmt"
7+ log "github.com/sirupsen/logrus"
78 "io"
89 "mokapi/media"
9- "mokapi/providers/openapi/schema"
10+ openApiSchema "mokapi/providers/openapi/schema"
1011 avro "mokapi/schema/avro/schema"
1112 "mokapi/schema/encoding"
1213 "mokapi/schema/json/generator"
@@ -20,21 +21,19 @@ type schemaInfo struct {
2021}
2122
2223type requestExample struct {
23- Name string `json:"name,omitempty"`
24- Format string `json:"format"`
25- Schema interface {} `json:"schema"`
24+ Name string
25+ Format string
26+ Schema interface {}
27+ ContentTypes []string
2628}
2729
28- func (h * handler ) getExampleData (w http.ResponseWriter , r * http.Request ) {
29- accept := r .Header .Get ("Accept" )
30- if len (accept ) == 0 {
31- accept = "application/json"
32- }
33- ct := media .ParseContentType (accept )
34- if ct .IsAny () {
35- ct = media .ParseContentType ("application/json" )
36- }
30+ type example struct {
31+ ContentType string `json:"contentType"`
32+ Value interface {} `json:"value"`
33+ Error string `json:"error,omitempty"`
34+ }
3735
36+ func (h * handler ) getExampleData (w http.ResponseWriter , r * http.Request ) {
3837 body , err := io .ReadAll (r .Body )
3938 if err != nil {
4039 http .Error (w , err .Error (), http .StatusBadRequest )
@@ -50,69 +49,106 @@ func (h *handler) getExampleData(w http.ResponseWriter, r *http.Request) {
5049 if re .Format == "" {
5150 re .Format = "application/schema+json;version=2020-12"
5251 }
53-
54- switch {
55- case ct .Subtype == "json" :
56- break
57- case ct .Subtype == "xml" :
58- break
59- case ct .Key () == "text/plain" :
60- break
61- case ct .Key () == "avro/binary" && isAvro (re .Format ):
62- break
63- case ct .Key () == "application/octet-stream" && isAvro (re .Format ):
64- break
65- default :
66- http .Error (w , fmt .Sprintf ("Content type %s with schema format %s is not supported" , ct , re .Format ), http .StatusBadRequest )
67- return
52+ if len (re .ContentTypes ) == 0 {
53+ re .ContentTypes = []string {"application/json" }
6854 }
6955
70- w .Header ().Set ("Content-Type" , ct .String ())
71-
72- var data []byte
73- switch s := re .Schema .(type ) {
74- case * schema.Ref :
75- data , err = getRandomByOpenApi (re .Name , s , ct )
56+ var s * jsonSchema.Schema
57+ switch t := re .Schema .(type ) {
58+ case * openApiSchema.Ref :
59+ s = openApiSchema .ConvertToJsonSchema (t )
7660 case * avro.Schema :
77- data , err = getRandomByJson ( re . Name , s . Convert (), ct )
61+ s = t . Convert ()
7862 default :
79- data , err = getRandomByJson (re .Name , s .(* jsonSchema.Schema ), ct )
63+ var ok bool
64+ s , ok = t .(* jsonSchema.Schema )
65+ if ! ok {
66+ http .Error (w , fmt .Sprintf ("unsupported schema type: %T" , t ), http .StatusBadRequest )
67+ return
68+ }
8069 }
8170
71+ rnd , err := generator .New (& generator.Request {
72+ Path : generator.Path {
73+ & generator.PathElement {Name : re .Name , Schema : s },
74+ },
75+ })
76+
77+ examples , err := encodeExample (rnd , re .Schema , re .Format , re .ContentTypes )
78+
8279 if err != nil {
8380 http .Error (w , err .Error (), http .StatusBadRequest )
8481 return
8582 }
8683
87- _ , err = w .Write (data )
88- if err != nil {
89- writeError (w , err , http .StatusInternalServerError )
90- }
91- }
84+ w .Header ().Set ("Content-Type" , "application/json" )
9285
93- func getRandomByOpenApi (name string , r * schema.Ref , ct media.ContentType ) ([]byte , error ) {
94- j := schema .ConvertToJsonSchema (r )
95- data , err := generator .New (& generator.Request {
96- Path : generator.Path {
97- & generator.PathElement {Name : name , Schema : j },
98- },
99- })
100- if err != nil {
101- return nil , err
102- }
103- return r .Marshal (data , ct )
86+ writeJsonBody (w , examples )
10487}
10588
106- func getRandomByJson (name string , r * jsonSchema.Schema , ct media.ContentType ) ([]byte , error ) {
107- data , err := generator .New (& generator.Request {
108- Path : generator.Path {
109- & generator.PathElement {Name : name , Schema : r },
110- },
111- })
112- if err != nil {
113- return nil , err
89+ func encodeExample (v interface {}, schema interface {}, schemaFormat string , contentTypes []string ) ([]example , error ) {
90+ var examples []example
91+ for _ , str := range contentTypes {
92+ ct := media .ParseContentType (str )
93+
94+ switch {
95+ case ct .Subtype == "json" :
96+ case ct .Subtype == "xml" :
97+ case ct .Key () == "text/plain" :
98+ case ct .Key () == "avro/binary" && isAvro (schemaFormat ):
99+ case ct .Key () == "application/octet-stream" && isAvro (schemaFormat ):
100+ case ct .IsAny ():
101+ ct = media .ParseContentType ("application/json" )
102+ default :
103+ examples = append (examples , example {
104+ ContentType : ct .String (),
105+ Error : fmt .Sprintf ("Content type %s with schema format %s is not supported" , ct , schemaFormat ),
106+ })
107+ continue
108+ }
109+
110+ var data []byte
111+ var err error
112+ switch t := schema .(type ) {
113+ case * openApiSchema.Ref :
114+ data , err = t .Marshal (v , ct )
115+ case * avro.Schema :
116+ switch {
117+ case ct .Subtype == "json" :
118+ data , err = encoding .NewEncoder (t .Convert ()).Write (v , ct )
119+ case ct .Key () == "avro/binary" || ct .Key () == "application/octet-stream" :
120+ data , err = t .Marshal (v )
121+ log .Infof ("string: %v" , string (data ))
122+ log .Infof ("bits: %v" , data )
123+ default :
124+ examples = append (examples , example {
125+ ContentType : ct .String (),
126+ Error : fmt .Sprintf ("unsupported schema type: %T" , t ),
127+ })
128+ continue
129+ }
130+ default :
131+ s , ok := schema .(* jsonSchema.Schema )
132+ if ! ok {
133+ return nil , fmt .Errorf ("unsupported schema type: %T" , t )
134+ }
135+ data , err = encoding .NewEncoder (s ).Write (v , ct )
136+
137+ }
138+
139+ if err != nil {
140+ examples = append (examples , example {
141+ ContentType : ct .String (),
142+ Error : err .Error (),
143+ })
144+ } else {
145+ examples = append (examples , example {
146+ ContentType : ct .String (),
147+ Value : data ,
148+ })
149+ }
114150 }
115- return encoding . NewEncoder ( r ). Write ( data , ct )
151+ return examples , nil
116152}
117153
118154func (s * schemaInfo ) UnmarshalJSON (data []byte ) error {
@@ -195,6 +231,11 @@ func (r *requestExample) UnmarshalJSON(data []byte) error {
195231 if err != nil {
196232 return err
197233 }
234+ case "contentTypes" :
235+ err = d .Decode (& r .ContentTypes )
236+ if err != nil {
237+ return err
238+ }
198239 }
199240 }
200241
@@ -207,7 +248,7 @@ func unmarshal(raw json.RawMessage, format string) (interface{}, error) {
207248 if raw != nil {
208249 switch {
209250 case isOpenApi (format ):
210- var r * schema .Ref
251+ var r * openApiSchema .Ref
211252 err := json .Unmarshal (raw , & r )
212253 return r , err
213254 case isAvro (format ):
0 commit comments