Skip to content

Commit 9db0e32

Browse files
authored
[php-flight] fix: always set http status in streaming response and use http status from spec (#18604)
This additionally adds streaming stubs for all methods (rather err on the side of too much stubs).
1 parent ac649b2 commit 9db0e32

File tree

7 files changed

+489
-65
lines changed

7 files changed

+489
-65
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PhpFlightServerCodegen.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.openapitools.codegen.CodegenModel;
3535
import org.openapitools.codegen.CodegenOperation;
3636
import org.openapitools.codegen.CodegenProperty;
37+
import org.openapitools.codegen.CodegenResponse;
3738
import org.openapitools.codegen.CodegenType;
3839
import org.openapitools.codegen.SupportingFile;
3940
import org.openapitools.codegen.meta.GeneratorMetadata;
@@ -202,11 +203,14 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
202203
List<CodegenOperation> operationList = operations.getOperation();
203204
operationList.forEach(operation -> {
204205
operation.vendorExtensions.put("x-path", mapToFlightPath(operation.path));
205-
String returnType = operation.responses.stream().filter(r -> r.is2xx && r.dataType != null).map(r -> this.getTypeHint(r.dataType, false, false)).filter(t -> !t.isEmpty()).map(t -> t + "|null").findFirst().orElse("void");
206+
CodegenResponse defaultResponse = operation.responses.stream().filter(r -> r.is2xx && r.dataType != null && !this.getTypeHint(r.dataType, false, false).isEmpty()).findFirst().orElse(null);
207+
String returnType = defaultResponse != null ? this.getTypeHint(defaultResponse.dataType, false, false) + "|null" : "void";
206208
operation.vendorExtensions.put("x-return-type", returnType);
207209
operation.vendorExtensions.put("x-return-type-is-void", returnType.equals("void"));
208-
operation.vendorExtensions.put("x-return-type-comment",
209-
operation.responses.stream().filter(r -> r.is2xx && r.dataType != null).map(r -> this.getTypeHint(r.dataType, true, false)).filter(t -> !t.isEmpty()).map(t -> t + "|null").findFirst().orElse("void"));
210+
operation.vendorExtensions.put("x-return-type-comment", defaultResponse != null ? this.getTypeHint(defaultResponse.dataType, true, false) + "|null" : "void");
211+
operation.vendorExtensions.put("x-default-media-type", defaultResponse != null ? (
212+
defaultResponse.getContent().containsKey("application/json") ? "application/json" : defaultResponse.getContent().keySet().stream().findFirst().orElse(null)) : null);
213+
operation.vendorExtensions.put("x-default-status-code", defaultResponse != null ? defaultResponse.code : operation.responses.stream().filter(r -> !r.isDefault).findFirst().map(r -> r.code).orElse("200"));
210214
operation.vendorExtensions.put("x-nonFormParams", operation.allParams.stream().filter(p -> !p.isFormParam).toArray());
211215

212216
operation.allParams.forEach(param -> {

modules/openapi-generator/src/main/resources/php-flight/api.mustache

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ namespace {{apiPackage}};
1111
{{#operation}}
1212
/**
1313
* Operation {{{operationId}}}
14-
* Path: {{{path}}}
14+
*
15+
* Path: `{{{path}}}`
1516
*
1617
{{#summary}}
1718
* {{{summary}}}
@@ -31,10 +32,11 @@ namespace {{apiPackage}};
3132
throw new \Exception('Not implemented');
3233
}
3334

34-
{{#returnContainer}}
3535
/**
3636
* Operation {{{operationId}}} (stream)
3737
*
38+
* Path: `{{{path}}}`
39+
*
3840
{{#summary}}
3941
* {{{summary}}}
4042
*
@@ -51,7 +53,6 @@ namespace {{apiPackage}};
5153
{
5254
throw new \Exception('Not implemented');
5355
}
54-
{{/returnContainer}}
5556
{{/operation}}
5657
}
5758
{{/operations}}

modules/openapi-generator/src/main/resources/php-flight/register_routes.mustache

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,16 @@ class RegisterRoutes {
2727
);
2828
{{^vendorExtensions.x-return-type-is-void}}
2929
if ($result === null) {
30-
\Flight::halt(204);
30+
\Flight::halt({{{vendorExtensions.x-default-status-code}}});
3131
} else {
32-
\Flight::json($result);
32+
\Flight::json($result, {{{vendorExtensions.x-default-status-code}}});
3333
}
3434
{{/vendorExtensions.x-return-type-is-void}}
3535
{{#vendorExtensions.x-return-type-is-void}}
36-
\Flight::halt(204);
36+
\Flight::halt({{{vendorExtensions.x-default-status-code}}});
3737
{{/vendorExtensions.x-return-type-is-void}}
3838
});
3939
}
40-
{{#returnContainer}}
4140
if (declaresMethod($reflectionClass, '{{operationId}}Stream')) {
4241
\Flight::route('{{httpMethod}} {{vendorExtensions.x-path}}', function ({{#pathParams}}string ${{paramName}}{{^-last}}, {{/-last}}{{/pathParams}}) use ($handler) {
4342
$r = \Flight::request();
@@ -47,9 +46,8 @@ class RegisterRoutes {
4746
{{/vendorExtensions.x-nonFormParams}}
4847
);
4948
// ignore return value: streaming expected
50-
})->streamWithHeaders(['Content-Type' => 'application/json']);
49+
})->streamWithHeaders(['status' => {{{vendorExtensions.x-default-status-code}}}{{#vendorExtensions.x-default-media-type}}, 'Content-Type' => '{{{vendorExtensions.x-default-media-type}}}'{{/vendorExtensions.x-default-media-type}}]);
5150
}
52-
{{/returnContainer}}
5351

5452
{{/operation}}
5553
{{/operations}}

samples/server/petstore/php-flight/Api/AbstractPetApi.php

Lines changed: 105 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ abstract class AbstractPetApi
2323

2424
/**
2525
* Operation addPet
26-
* Path: /pet
26+
*
27+
* Path: `/pet`
2728
*
2829
* Add a new pet to the store
2930
*
@@ -36,9 +37,24 @@ public function addPet(\OpenAPIServer\Model\Pet $pet): \OpenAPIServer\Model\Pet|
3637
throw new \Exception('Not implemented');
3738
}
3839

40+
/**
41+
* Operation addPet (stream)
42+
*
43+
* Path: `/pet`
44+
*
45+
* Add a new pet to the store
46+
*
47+
* @param \OpenAPIServer\Model\Pet $pet Pet object that needs to be added to the store (required)
48+
*
49+
*/
50+
public function addPetStream(\OpenAPIServer\Model\Pet $pet): void
51+
{
52+
throw new \Exception('Not implemented');
53+
}
3954
/**
4055
* Operation deletePet
41-
* Path: /pet/{petId}
56+
*
57+
* Path: `/pet/{petId}`
4258
*
4359
* Deletes a pet
4460
*
@@ -52,9 +68,25 @@ public function deletePet(int $petId, ?string $apiKey): void
5268
throw new \Exception('Not implemented');
5369
}
5470

71+
/**
72+
* Operation deletePet (stream)
73+
*
74+
* Path: `/pet/{petId}`
75+
*
76+
* Deletes a pet
77+
*
78+
* @param int $petId Pet id to delete (required)
79+
* @param ?string $apiKey (optional)
80+
*
81+
*/
82+
public function deletePetStream(int $petId, ?string $apiKey): void
83+
{
84+
throw new \Exception('Not implemented');
85+
}
5586
/**
5687
* Operation findPetsByStatus
57-
* Path: /pet/findByStatus
88+
*
89+
* Path: `/pet/findByStatus`
5890
*
5991
* Finds Pets by status
6092
*
@@ -70,6 +102,8 @@ public function findPetsByStatus(array $status): array|null
70102
/**
71103
* Operation findPetsByStatus (stream)
72104
*
105+
* Path: `/pet/findByStatus`
106+
*
73107
* Finds Pets by status
74108
*
75109
* @param array $status Status values that need to be considered for filter (required) (deprecated)
@@ -81,7 +115,8 @@ public function findPetsByStatusStream(array $status): void
81115
}
82116
/**
83117
* Operation findPetsByTags
84-
* Path: /pet/findByTags
118+
*
119+
* Path: `/pet/findByTags`
85120
*
86121
* Finds Pets by tags
87122
*
@@ -98,6 +133,8 @@ public function findPetsByTags(array $tags): array|null
98133
/**
99134
* Operation findPetsByTags (stream)
100135
*
136+
* Path: `/pet/findByTags`
137+
*
101138
* Finds Pets by tags
102139
*
103140
* @param array $tags Tags to filter by (required)
@@ -110,7 +147,8 @@ public function findPetsByTagsStream(array $tags): void
110147
}
111148
/**
112149
* Operation getPetById
113-
* Path: /pet/{petId}
150+
*
151+
* Path: `/pet/{petId}`
114152
*
115153
* Find pet by ID
116154
*
@@ -123,9 +161,24 @@ public function getPetById(int $petId): \OpenAPIServer\Model\Pet|null
123161
throw new \Exception('Not implemented');
124162
}
125163

164+
/**
165+
* Operation getPetById (stream)
166+
*
167+
* Path: `/pet/{petId}`
168+
*
169+
* Find pet by ID
170+
*
171+
* @param int $petId ID of pet to return (required)
172+
*
173+
*/
174+
public function getPetByIdStream(int $petId): void
175+
{
176+
throw new \Exception('Not implemented');
177+
}
126178
/**
127179
* Operation updatePet
128-
* Path: /pet
180+
*
181+
* Path: `/pet`
129182
*
130183
* Update an existing pet
131184
*
@@ -138,9 +191,24 @@ public function updatePet(\OpenAPIServer\Model\Pet $pet): \OpenAPIServer\Model\P
138191
throw new \Exception('Not implemented');
139192
}
140193

194+
/**
195+
* Operation updatePet (stream)
196+
*
197+
* Path: `/pet`
198+
*
199+
* Update an existing pet
200+
*
201+
* @param \OpenAPIServer\Model\Pet $pet Pet object that needs to be added to the store (required)
202+
*
203+
*/
204+
public function updatePetStream(\OpenAPIServer\Model\Pet $pet): void
205+
{
206+
throw new \Exception('Not implemented');
207+
}
141208
/**
142209
* Operation updatePetWithForm
143-
* Path: /pet/{petId}
210+
*
211+
* Path: `/pet/{petId}`
144212
*
145213
* Updates a pet in the store with form data
146214
*
@@ -153,9 +221,24 @@ public function updatePetWithForm(int $petId): void
153221
throw new \Exception('Not implemented');
154222
}
155223

224+
/**
225+
* Operation updatePetWithForm (stream)
226+
*
227+
* Path: `/pet/{petId}`
228+
*
229+
* Updates a pet in the store with form data
230+
*
231+
* @param int $petId ID of pet that needs to be updated (required)
232+
*
233+
*/
234+
public function updatePetWithFormStream(int $petId): void
235+
{
236+
throw new \Exception('Not implemented');
237+
}
156238
/**
157239
* Operation uploadFile
158-
* Path: /pet/{petId}/uploadImage
240+
*
241+
* Path: `/pet/{petId}/uploadImage`
159242
*
160243
* uploads an image
161244
*
@@ -168,4 +251,18 @@ public function uploadFile(int $petId): \OpenAPIServer\Model\ApiResponse|null
168251
throw new \Exception('Not implemented');
169252
}
170253

254+
/**
255+
* Operation uploadFile (stream)
256+
*
257+
* Path: `/pet/{petId}/uploadImage`
258+
*
259+
* uploads an image
260+
*
261+
* @param int $petId ID of pet to update (required)
262+
*
263+
*/
264+
public function uploadFileStream(int $petId): void
265+
{
266+
throw new \Exception('Not implemented');
267+
}
171268
}

samples/server/petstore/php-flight/Api/AbstractStoreApi.php

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ abstract class AbstractStoreApi
2323

2424
/**
2525
* Operation deleteOrder
26-
* Path: /store/order/{orderId}
26+
*
27+
* Path: `/store/order/{orderId}`
2728
*
2829
* Delete purchase order by ID
2930
*
@@ -36,9 +37,24 @@ public function deleteOrder(string $orderId): void
3637
throw new \Exception('Not implemented');
3738
}
3839

40+
/**
41+
* Operation deleteOrder (stream)
42+
*
43+
* Path: `/store/order/{orderId}`
44+
*
45+
* Delete purchase order by ID
46+
*
47+
* @param string $orderId ID of the order that needs to be deleted (required)
48+
*
49+
*/
50+
public function deleteOrderStream(string $orderId): void
51+
{
52+
throw new \Exception('Not implemented');
53+
}
3954
/**
4055
* Operation getInventory
41-
* Path: /store/inventory
56+
*
57+
* Path: `/store/inventory`
4258
*
4359
* Returns pet inventories by status
4460
*
@@ -53,6 +69,8 @@ public function getInventory(): void
5369
/**
5470
* Operation getInventory (stream)
5571
*
72+
* Path: `/store/inventory`
73+
*
5674
* Returns pet inventories by status
5775
*
5876
*
@@ -63,7 +81,8 @@ public function getInventoryStream(): void
6381
}
6482
/**
6583
* Operation getOrderById
66-
* Path: /store/order/{orderId}
84+
*
85+
* Path: `/store/order/{orderId}`
6786
*
6887
* Find purchase order by ID
6988
*
@@ -76,9 +95,24 @@ public function getOrderById(int $orderId): \OpenAPIServer\Model\Order|null
7695
throw new \Exception('Not implemented');
7796
}
7897

98+
/**
99+
* Operation getOrderById (stream)
100+
*
101+
* Path: `/store/order/{orderId}`
102+
*
103+
* Find purchase order by ID
104+
*
105+
* @param int $orderId ID of pet that needs to be fetched (required)
106+
*
107+
*/
108+
public function getOrderByIdStream(int $orderId): void
109+
{
110+
throw new \Exception('Not implemented');
111+
}
79112
/**
80113
* Operation placeOrder
81-
* Path: /store/order
114+
*
115+
* Path: `/store/order`
82116
*
83117
* Place an order for a pet
84118
*
@@ -91,4 +125,18 @@ public function placeOrder(\OpenAPIServer\Model\Order $order): \OpenAPIServer\Mo
91125
throw new \Exception('Not implemented');
92126
}
93127

128+
/**
129+
* Operation placeOrder (stream)
130+
*
131+
* Path: `/store/order`
132+
*
133+
* Place an order for a pet
134+
*
135+
* @param \OpenAPIServer\Model\Order $order order placed for purchasing the pet (required)
136+
*
137+
*/
138+
public function placeOrderStream(\OpenAPIServer\Model\Order $order): void
139+
{
140+
throw new \Exception('Not implemented');
141+
}
94142
}

0 commit comments

Comments
 (0)