在渲染之前重新安排对象上的 CakePHP JSON 响应
Re-arrange a CakePHP JSON response on object prior to render
我正在开发基于 API 的 CakePHP REST/CRUD。它在 /config/routes.php
中使用 $routes->setExtensions(['json']);
将它的响应变成 json 个对象。
我正在处理几个具有复杂模式的对象,我需要在提交给 CakeORM 之前对其进行预处理,以便为最终用户简化 API 集成。
例如,以下是 json 需要使用 $this->ImportSettings->patchEntity($importSetting, $requestData[2])
修补到 ORM 的 blob:
{
"id": 2,
"generic_setting": "Hello World",
"import_source_google_setting": null,
"import_source_csv_ordered_setting": null,
"import_source_csv_headed_setting": {
"id": 1,
"import_settings_id": 2,
"delimiterId": 1
},
"import_destination_user_setting": null,
"import_destination_asset_setting": {
"id": 2,
"import_settings_id": 2,
"defaultValueId": 1
}
}
导入设置中可以定义多个来源之一和多个指定设置之一。为了简化 API 用户的操作,我允许他们提交以下内容:
{
"id": 2,
"generic_setting": "Hello World",
"import_source_setting": {
"id": 1,
"import_settings_id": 2,
"delimiterId": 1
},
"import_destination_setting": {
"id": 2,
"import_settings_id": 2,
"defaultValueId": 1
}
}
我已经在 beforeMarshal 上为 ImportSesttings 编写了一个事件侦听器代码,它能够判断索引“import_source_setting”是否属于 table 中的“[=35” =]”、“import_source_csv_ordered_setting”或“import_source_google_setting”,同样,资产和用户设置进入“import_destination_setting”。
这很适合在请求进入 ORM 之前处理请求中的重新组织数据。但是,我现在想在显示数据之前对数据执行相同的操作,因此 API 用户不需要查看其他源和目标设置。
我已经通过在系统另一部分的类似用例中使用中间件来实现这一点。然而,中间件似乎是附加到路由上的,我的使用似乎更像是应该与模型生命周期相关联的东西,因此只要返回导入设置并正确修改输出,它就会运行,即使嵌套时也是如此。
考虑到我正在寻找的内容,我应该将重新组织 json 对 table 的 ORM 查询结果的响应的逻辑放在 Cake 的哪一部分?你能告诉我这方面的文档吗?
我在另一个论坛上使用 CakePHP's calculated fields 找到了这个问题的答案。看起来 formatResults() 函数可以附加到带有回调的查询,以便在查询 运行 后重新组织结果。我继续将它附加到 beforeFind() 事件中的查询,这似乎有效。
参见下面的示例:
<?php
class ImportSettingsListener implements Cake\Event\EventListenerInterface
{
public function implementedEvents(): array
{
return [
'Model.beforeFind' => 'generateQuery',
];
}
public function generateQuery(Event $event, Query $query, ArrayObject $options, bool $primary): void
{
$query->formatResults(function (CollectionInterface $results) {
return $results->map(function ($setting) {
// Re-format $setting here
return $setting;
});
});
}
}
我正在开发基于 API 的 CakePHP REST/CRUD。它在 /config/routes.php
中使用 $routes->setExtensions(['json']);
将它的响应变成 json 个对象。
我正在处理几个具有复杂模式的对象,我需要在提交给 CakeORM 之前对其进行预处理,以便为最终用户简化 API 集成。
例如,以下是 json 需要使用 $this->ImportSettings->patchEntity($importSetting, $requestData[2])
修补到 ORM 的 blob:
{
"id": 2,
"generic_setting": "Hello World",
"import_source_google_setting": null,
"import_source_csv_ordered_setting": null,
"import_source_csv_headed_setting": {
"id": 1,
"import_settings_id": 2,
"delimiterId": 1
},
"import_destination_user_setting": null,
"import_destination_asset_setting": {
"id": 2,
"import_settings_id": 2,
"defaultValueId": 1
}
}
导入设置中可以定义多个来源之一和多个指定设置之一。为了简化 API 用户的操作,我允许他们提交以下内容:
{
"id": 2,
"generic_setting": "Hello World",
"import_source_setting": {
"id": 1,
"import_settings_id": 2,
"delimiterId": 1
},
"import_destination_setting": {
"id": 2,
"import_settings_id": 2,
"defaultValueId": 1
}
}
我已经在 beforeMarshal 上为 ImportSesttings 编写了一个事件侦听器代码,它能够判断索引“import_source_setting”是否属于 table 中的“[=35” =]”、“import_source_csv_ordered_setting”或“import_source_google_setting”,同样,资产和用户设置进入“import_destination_setting”。
这很适合在请求进入 ORM 之前处理请求中的重新组织数据。但是,我现在想在显示数据之前对数据执行相同的操作,因此 API 用户不需要查看其他源和目标设置。
我已经通过在系统另一部分的类似用例中使用中间件来实现这一点。然而,中间件似乎是附加到路由上的,我的使用似乎更像是应该与模型生命周期相关联的东西,因此只要返回导入设置并正确修改输出,它就会运行,即使嵌套时也是如此。
考虑到我正在寻找的内容,我应该将重新组织 json 对 table 的 ORM 查询结果的响应的逻辑放在 Cake 的哪一部分?你能告诉我这方面的文档吗?
我在另一个论坛上使用 CakePHP's calculated fields 找到了这个问题的答案。看起来 formatResults() 函数可以附加到带有回调的查询,以便在查询 运行 后重新组织结果。我继续将它附加到 beforeFind() 事件中的查询,这似乎有效。
参见下面的示例:
<?php
class ImportSettingsListener implements Cake\Event\EventListenerInterface
{
public function implementedEvents(): array
{
return [
'Model.beforeFind' => 'generateQuery',
];
}
public function generateQuery(Event $event, Query $query, ArrayObject $options, bool $primary): void
{
$query->formatResults(function (CollectionInterface $results) {
return $results->map(function ($setting) {
// Re-format $setting here
return $setting;
});
});
}
}