Skip to content

Commit e0738a6

Browse files
authored
[Go-Server] Support for an endpoint returning a file to the client - #15206 (#16748)
* Support for an endpoint returning a file to a client. * Spaces to tabs conversion * Add an example endpoint for download a file * Regenerate after merging main
1 parent 1dd9590 commit e0738a6

File tree

14 files changed

+251
-6
lines changed

14 files changed

+251
-6
lines changed

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ nb-configuration.xml
4949
/target
5050
/generated-files
5151
test-output/
52+
nbactions.xml
53+
test-output/
5254

5355
# website
5456
website/build/
@@ -71,6 +73,7 @@ samples/client/petstore/build
7173
samples/client/petstore/cpp-qt/PetStore/moc_*
7274
samples/client/petstore/cpp-qt/PetStore/*.o
7375
samples/client/petstore/cpp-qt/build-*
76+
samples/client/petstore/cpp-qt/build-*
7477
samples/client/petstore/cpp-qt/PetStore/PetStore
7578
samples/client/petstore/cpp-qt/PetStore/Makefile
7679
samples/client/petstore/cpp-qt/PetStore/PetStore.pro.user
@@ -97,14 +100,17 @@ samples/client/petstore/java/jersey2/build/
97100
samples/client/petstore/java/okhttp-gson/.gradle/
98101
samples/client/petstore/java/okhttp-gson/build/
99102
samples/client/petstore/java/feign/build/
103+
samples/client/petstore/java/feign10x/build/
100104
samples/client/petstore/java/feign/project/
105+
samples/client/petstore/java/feign10x/project/
101106
samples/client/petstore/java/retrofit/build/
102107
samples/client/petstore/java/retrofit2/build/
103108
samples/client/petstore/java/retrofit2/hello.txt
104109
samples/client/petstore/java/retrofit2rx/build/
105110
samples/client/petstore/java/default/build/
106111
samples/client/petstore/scala/build/
107112
samples/client/petstore/java/resttemplate/hello.txt
113+
samples/client/petstore/java/retrofit2/hello.txt
108114
samples/client/petstore/java/feign/hello.txt
109115
samples/client/petstore/java/jersey2-java6/project/
110116
samples/client/petstore/java/jersey2-java8/project/
@@ -187,7 +193,6 @@ samples/server/petstore/php-slim4/composer.lock
187193
samples/server/petstore/php-symfony/SymfonyBundle-php/composer.lock
188194
samples/server/petstore/php-mezzio-ph/composer.lock
189195
samples/server/petstore/php-mezzio-ph-modern/composer.lock
190-
samples/client/petstore/php-nextgen/OpenAPIClient-php/.phplint.cache/
191196

192197
# ts
193198
samples/client/petstore/typescript-angular2/npm/npm-debug.log

modules/openapi-generator/src/main/resources/go-server/routers.mustache

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,18 +89,33 @@ func NewRouter(routers ...Router) {{#routers}}{{#mux}}*mux.Router{{/mux}}{{#chi}
8989

9090
// EncodeJSONResponse uses the json encoder to write an interface to the http response with an optional status code
9191
func EncodeJSONResponse(i interface{}, status *int,{{#addResponseHeaders}} headers map[string][]string,{{/addResponseHeaders}} w http.ResponseWriter) error {
92-
{{#addResponseHeaders}}
9392
wHeader := w.Header()
93+
{{#addResponseHeaders}}
9494
for key, values := range headers {
9595
for _, value := range values {
9696
wHeader.Add(key, value)
9797
}
9898
}
99-
wHeader.Set("Content-Type", "application/json; charset=UTF-8")
100-
{{/addResponseHeaders}}
101-
{{^addResponseHeaders}}
102-
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
10399
{{/addResponseHeaders}}
100+
101+
f, ok := i.(*os.File)
102+
if ok {
103+
data, err := io.ReadAll(f)
104+
if err != nil {
105+
return err
106+
}
107+
wHeader.Set("Content-Type", http.DetectContentType(data))
108+
wHeader.Set("Content-Disposition", "attachment; filename="+f.Name())
109+
if status != nil {
110+
w.WriteHeader(*status)
111+
} else {
112+
w.WriteHeader(http.StatusOK)
113+
}
114+
_, err = w.Write(data)
115+
return err
116+
}
117+
wHeader.Set("Content-Type", "application/json; charset=UTF-8")
118+
104119
if status != nil {
105120
w.WriteHeader(*status)
106121
} else {

modules/openapi-generator/src/test/resources/3_0/go-server/petstore.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,32 @@ paths:
332332
description: file to upload
333333
type: string
334334
format: binary
335+
get:
336+
tags:
337+
- pet
338+
summary: Returns the image for the Pet that has been previously uploaded
339+
description: Returns the image for the Pet that has been previously uploaded
340+
operationId: getPetImageById
341+
parameters:
342+
- name: petId
343+
in: path
344+
description: ID of pet to return
345+
required: true
346+
schema:
347+
type: integer
348+
format: int64
349+
responses:
350+
'200':
351+
description: successful operation
352+
content:
353+
image/jpeg:
354+
schema:
355+
type: string
356+
format: binary
357+
'400':
358+
description: Invalid ID supplied
359+
'404':
360+
description: Pet not found
335361
/store/inventory:
336362
get:
337363
tags:

samples/openapi3/server/petstore/go/go-petstore/go/routers.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,25 @@ func EncodeJSONResponse(i interface{}, status *int, headers map[string][]string,
6464
wHeader.Add(key, value)
6565
}
6666
}
67+
68+
f, ok := i.(*os.File)
69+
if ok {
70+
data, err := io.ReadAll(f)
71+
if err != nil {
72+
return err
73+
}
74+
wHeader.Set("Content-Type", http.DetectContentType(data))
75+
wHeader.Set("Content-Disposition", "attachment; filename="+f.Name())
76+
if status != nil {
77+
w.WriteHeader(*status)
78+
} else {
79+
w.WriteHeader(http.StatusOK)
80+
}
81+
_, err = w.Write(data)
82+
return err
83+
}
6784
wHeader.Set("Content-Type", "application/json; charset=UTF-8")
85+
6886
if status != nil {
6987
w.WriteHeader(*status)
7088
} else {

samples/server/petstore/go-api-server/api/openapi.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,34 @@ paths:
298298
tags:
299299
- pet
300300
/pet/{petId}/uploadImage:
301+
get:
302+
description: Returns the image for the Pet that has been previously uploaded
303+
operationId: getPetImageById
304+
parameters:
305+
- description: ID of pet to return
306+
explode: false
307+
in: path
308+
name: petId
309+
required: true
310+
schema:
311+
format: int64
312+
type: integer
313+
style: simple
314+
responses:
315+
"200":
316+
content:
317+
image/jpeg:
318+
schema:
319+
format: binary
320+
type: string
321+
description: successful operation
322+
"400":
323+
description: Invalid ID supplied
324+
"404":
325+
description: Pet not found
326+
summary: Returns the image for the Pet that has been previously uploaded
327+
tags:
328+
- pet
301329
post:
302330
description: ""
303331
operationId: uploadFile

samples/server/petstore/go-api-server/go/api.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type PetAPIRouter interface {
2828
// Deprecated
2929
FindPetsByTags(http.ResponseWriter, *http.Request)
3030
GetPetById(http.ResponseWriter, *http.Request)
31+
GetPetImageById(http.ResponseWriter, *http.Request)
3132
UpdatePet(http.ResponseWriter, *http.Request)
3233
UpdatePetWithForm(http.ResponseWriter, *http.Request)
3334
UploadFile(http.ResponseWriter, *http.Request)
@@ -69,6 +70,7 @@ type PetAPIServicer interface {
6970
// Deprecated
7071
FindPetsByTags(context.Context, []string) (ImplResponse, error)
7172
GetPetById(context.Context, int64) (ImplResponse, error)
73+
GetPetImageById(context.Context, int64) (ImplResponse, error)
7274
UpdatePet(context.Context, Pet) (ImplResponse, error)
7375
UpdatePetWithForm(context.Context, int64, string, string) (ImplResponse, error)
7476
UploadFile(context.Context, int64, string, *os.File) (ImplResponse, error)

samples/server/petstore/go-api-server/go/api_pet.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ func (c *PetAPIController) Routes() Routes {
8080
"/v2/pet/{petId}",
8181
c.GetPetById,
8282
},
83+
"GetPetImageById": Route{
84+
strings.ToUpper("Get"),
85+
"/v2/pet/{petId}/uploadImage",
86+
c.GetPetImageById,
87+
},
8388
"UpdatePet": Route{
8489
strings.ToUpper("Put"),
8590
"/v2/pet",
@@ -249,6 +254,27 @@ func (c *PetAPIController) GetPetById(w http.ResponseWriter, r *http.Request) {
249254
EncodeJSONResponse(result.Body, &result.Code, result.Headers, w)
250255
}
251256

257+
// GetPetImageById - Returns the image for the Pet that has been previously uploaded
258+
func (c *PetAPIController) GetPetImageById(w http.ResponseWriter, r *http.Request) {
259+
params := mux.Vars(r)
260+
petIdParam, err := parseNumericParameter[int64](
261+
params["petId"],
262+
WithRequire[int64](parseInt64),
263+
)
264+
if err != nil {
265+
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
266+
return
267+
}
268+
result, err := c.service.GetPetImageById(r.Context(), petIdParam)
269+
// If an error occurred, encode the error with the status code
270+
if err != nil {
271+
c.errorHandler(w, r, err, &result)
272+
return
273+
}
274+
// If no error, encode the body and the result code
275+
EncodeJSONResponse(result.Body, &result.Code, result.Headers, w)
276+
}
277+
252278
// UpdatePet - Update an existing pet
253279
func (c *PetAPIController) UpdatePet(w http.ResponseWriter, r *http.Request) {
254280
petParam := Pet{}

samples/server/petstore/go-api-server/go/api_pet_service.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,23 @@ func (s *PetAPIService) GetPetById(ctx context.Context, petId int64) (ImplRespon
112112
return Response(http.StatusNotImplemented, nil), errors.New("GetPetById method not implemented")
113113
}
114114

115+
// GetPetImageById - Returns the image for the Pet that has been previously uploaded
116+
func (s *PetAPIService) GetPetImageById(ctx context.Context, petId int64) (ImplResponse, error) {
117+
// TODO - update GetPetImageById with the required logic for this service method.
118+
// Add api_pet_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation.
119+
120+
// TODO: Uncomment the next line to return response Response(200, *os.File{}) or use other options such as http.Ok ...
121+
// return Response(200, *os.File{}), nil
122+
123+
// TODO: Uncomment the next line to return response Response(400, {}) or use other options such as http.Ok ...
124+
// return Response(400, nil),nil
125+
126+
// TODO: Uncomment the next line to return response Response(404, {}) or use other options such as http.Ok ...
127+
// return Response(404, nil),nil
128+
129+
return Response(http.StatusNotImplemented, nil), errors.New("GetPetImageById method not implemented")
130+
}
131+
115132
// UpdatePet - Update an existing pet
116133
func (s *PetAPIService) UpdatePet(ctx context.Context, pet Pet) (ImplResponse, error) {
117134
// TODO - update UpdatePet with the required logic for this service method.

samples/server/petstore/go-api-server/go/routers.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,25 @@ func EncodeJSONResponse(i interface{}, status *int, headers map[string][]string,
6868
wHeader.Add(key, value)
6969
}
7070
}
71+
72+
f, ok := i.(*os.File)
73+
if ok {
74+
data, err := io.ReadAll(f)
75+
if err != nil {
76+
return err
77+
}
78+
wHeader.Set("Content-Type", http.DetectContentType(data))
79+
wHeader.Set("Content-Disposition", "attachment; filename="+f.Name())
80+
if status != nil {
81+
w.WriteHeader(*status)
82+
} else {
83+
w.WriteHeader(http.StatusOK)
84+
}
85+
_, err = w.Write(data)
86+
return err
87+
}
7188
wHeader.Set("Content-Type", "application/json; charset=UTF-8")
89+
7290
if status != nil {
7391
w.WriteHeader(*status)
7492
} else {

samples/server/petstore/go-chi-server/api/openapi.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,34 @@ paths:
298298
tags:
299299
- pet
300300
/pet/{petId}/uploadImage:
301+
get:
302+
description: Returns the image for the Pet that has been previously uploaded
303+
operationId: getPetImageById
304+
parameters:
305+
- description: ID of pet to return
306+
explode: false
307+
in: path
308+
name: petId
309+
required: true
310+
schema:
311+
format: int64
312+
type: integer
313+
style: simple
314+
responses:
315+
"200":
316+
content:
317+
image/jpeg:
318+
schema:
319+
format: binary
320+
type: string
321+
description: successful operation
322+
"400":
323+
description: Invalid ID supplied
324+
"404":
325+
description: Pet not found
326+
summary: Returns the image for the Pet that has been previously uploaded
327+
tags:
328+
- pet
301329
post:
302330
description: ""
303331
operationId: uploadFile

0 commit comments

Comments
 (0)