0

即使在调试之后,我也有点迷失在定义、生成的代码和许多有点像黑匣子的东西之间。

但让我们从头开始。我有一个使用 NestJS 作为框架的节点编写的 API。NestJS 自动创建 swagger/openapi json 文件。我使用 swagger-codegen 创建了一个 PHP 类来从另一台服务器访问 API。就像简单 API 请求的魅力一样。

现在的问题是 API 请求返回更大的响应,即来自一个或多个 DB 的 >1000 行。不要让客户端等待很长时间,并在我已切换到 NDJSON 的服务器上创建一个大的 JSON 响应,它将响应拆分为较小的 JSON 部分,每个部分都在它自己的行上。当我使用 curl 或使用 fopen 和 fread 在 PHP 中使用 HTTP 包装器手动创建我的请求时,这也适用。响应类型为 application/x-ndjson。

但是 swagger-codegen 生成的代码总是等到收到整个响应。更糟糕的是,因为它无法使用 json_decode() 解码 NDJSON 并且只返回 null。下面使用 Guzzle,它使用 PSR7 流作为响应。

现在我可以跳过 NDJSON 端点的自动生成代码。但我不希望添加特殊处理并丢失所有有用的生成检查。

那么是否有可能让 swagger-codegen 访问响应流?我是否缺少 codegen 的参数或招摇 JSON 中的某些内容?它确实有一个带有 application/x-ndjson 的产品。

4

1 回答 1

0

回答我自己的问题是可能的,但不容易 - 这意味着没有选项或参数。

首先创建一个扩展自动生成的 API 类的类。在那里,您可以访问所有受保护的方法。我们假设调用了端点或 api 方法testMethodGet。唯一可以重用的是请求方法,即testMethodGetRequest,但它完成了所有客户端验证和输入数据的转换,所以这已经是一个巨大的胜利。还可以获得一些样板结果验证,您可以复制“http info 方法”,即testMethodGetWithHttpInfo(如果您愿意,请使用异步版本)。在返回后删除 if/else 块,$responseBody = $response->getBody();将 ObjectSearializer 行替换为 just $responseBody

您现在得到的是作为 PSR7 流的主体,但还有最后一个捕获。默认情况下,整个响应被排入一个临时文件。要在创建的方法中真正从服务器流式传输结果主体,请在 $options 中添加一个选项:$options['stream'] = true;现在该方法会在主体启动后立即返回。无需等待全身内容。

还有一件事。结果是一个 PSR7 流,$stream->detach()如果您更喜欢使用普通文件和流方法,您可以使用它来获取 PHP 流资源。

于 2020-08-10T18:10:35.760 回答