Explorar el Código

fix(openapi): 204 不再输出响应体,声明 204 就不再输出默认的 200

两处都是上一版「2xx 按成功口径渲染」引入的误伤:

- RFC 9110 规定 204 / 205 的响应 MUST NOT 带消息体,但它们被当成普通 2xx
  套上了成功 schema。现在这两个码只给 description,不给 content。
- v3 分支无条件输出 200,于是 return response()->noContent() 的端点在规格里
  既有 204 又有 200 + data schema,前端会以为可以读 body。现在声明了
  @responseStatus 204 就不再输出默认的 200。

生成出来的前端类型因此是 `204: { content?: never }`,与实现一致。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
visuddhinanda hace 3 semanas
padre
commit
ecdb7f60e3
Se han modificado 1 ficheros con 11 adiciones y 2 borrados
  1. 11 2
      openapi/scripts/generate.php

+ 11 - 2
openapi/scripts/generate.php

@@ -857,7 +857,10 @@ function buildOperation(array $route, string $httpMethod): array
             ]
             : ['type' => 'object', 'properties' => ['data' => $data]];
 
-        $responses = [
+        // 声明了 204 就不再输出默认的 200——控制器 return response()->noContent()
+        // 的端点没有 200 这个口径,留着会让前端以为可以读 body
+        $declared = $info['tags']['responses'] ?? [];
+        $responses = isset($declared[204]) ? [] : [
             '200' => [
                 'description' => '成功',
                 'content' => ['application/json' => ['schema' => $success]],
@@ -873,8 +876,14 @@ function buildOperation(array $route, string $httpMethod): array
         }
         // @responseStatus 声明的额外状态码。2xx 是另一种成功口径(如 201 Created),
         // 响应体与 200 同形;其余是错误,响应体是 Problem Details。
-        foreach ($info['tags']['responses'] ?? [] as $code => $desc) {
+        foreach ($declared as $code => $desc) {
             $isSuccess = $code >= 200 && $code < 300;
+            // 204 / 205 按 RFC 9110 MUST NOT 带消息体,不给 content
+            if ((int) $code === 204 || (int) $code === 205) {
+                $responses[(string) $code] = ['description' => $desc !== '' ? $desc : '成功,无响应体'];
+
+                continue;
+            }
             $responses[(string) $code] = $isSuccess
                 ? [
                     'description' => $desc !== '' ? $desc : '成功',