在 Page API 请求中包含相关模型数据
Including related model data in Page API request
我有一个相对简单的设置 运行 使用 SilverStripe 3.2.1 和 restfulserver addon and using a variety of widgets which are associated to a Page using the elemental addon。
当我通过 API 发出 GET 请求以检索第 1 页的一些数据时,我可以看到关联的 ElementAreaID:
# GET /api/v1/Page/1.json?fields=Title,URLSegment,Content,ElementArea
{
"Title": "Welcome",
"URLSegment": "home",
"Content": "A bunch of HTML here from all the widgets in the page...",
"ElementArea": {
"className": "ElementalArea",
"href": "http://ss.local:3000/api/v1/ElementalArea/11.json",
"id": "11"
}
}
如果我通过 ElementalArea API 调用跟踪链接,它将列出我页面中的所有元素:
# GET /api/v1/ElementalArea/11.json
{
"ID": "11",
"Widgets": [
{
"className": "Widget",
"href": "http://ss.local:3000/api/v1/Widget/9.json",
"id": 9
},
{
"className": "Widget",
"href": "http://ss.local:3000/api/v1/Widget/8.json",
"id": 8
},
...
]
}
如果我遵循这些 API 路径,它将提供每个小部件的最新版本的内容。
我的问题是如何将 Widget DataObjects 中的某些字段包含在原始页面字段列表中?
理想情况下,我希望每个 Widget 的内容字段与初始页面 API 请求一起返回到数组中。
供参考:
- 一个页面有一个
ElementArea
- 一个
ElementArea
有很多Widget
个
Widget
包含我想要的 Page
内容
序言: 目前似乎没有办法用 RESTful 服务器模块输出类似数组的数据结构(当然关系除外)。提议的解决方案是一种滥用 JSONDataFormatter
格式化输出的方式。
由于 JSONDataFormatter
在将字段转换为 JSON 之前使用 forTemplate
渲染字段,我们可以创建自己的对象渲染器 returns 数组而不是字符串通过 forTemplate
。这可能看起来像这样:
class FlatJSONDataList extends ViewableData
{
protected $list;
public function __construct(array $list)
{
parent::__construct();
$this->list = $list;
}
public function forTemplate()
{
return $this->list;
}
}
然后在你的页面中,有一个额外的方法就足够了,像这样:
public function getWidgetContents()
{
return FlatJSONDataList::create(
$this->ElementArea()->Widgets()->column('Content')
);
}
然后您可以在您的字段列表中包含 WidgetContents
以获取数组中的所有小部件 Content
字段:
GET /api/v1/Page/1.json?fields=Title,URLSegment,Content,WidgetContents
我有一个相对简单的设置 运行 使用 SilverStripe 3.2.1 和 restfulserver addon and using a variety of widgets which are associated to a Page using the elemental addon。
当我通过 API 发出 GET 请求以检索第 1 页的一些数据时,我可以看到关联的 ElementAreaID:
# GET /api/v1/Page/1.json?fields=Title,URLSegment,Content,ElementArea
{
"Title": "Welcome",
"URLSegment": "home",
"Content": "A bunch of HTML here from all the widgets in the page...",
"ElementArea": {
"className": "ElementalArea",
"href": "http://ss.local:3000/api/v1/ElementalArea/11.json",
"id": "11"
}
}
如果我通过 ElementalArea API 调用跟踪链接,它将列出我页面中的所有元素:
# GET /api/v1/ElementalArea/11.json
{
"ID": "11",
"Widgets": [
{
"className": "Widget",
"href": "http://ss.local:3000/api/v1/Widget/9.json",
"id": 9
},
{
"className": "Widget",
"href": "http://ss.local:3000/api/v1/Widget/8.json",
"id": 8
},
...
]
}
如果我遵循这些 API 路径,它将提供每个小部件的最新版本的内容。
我的问题是如何将 Widget DataObjects 中的某些字段包含在原始页面字段列表中?
理想情况下,我希望每个 Widget 的内容字段与初始页面 API 请求一起返回到数组中。
供参考:
- 一个页面有一个
ElementArea
- 一个
ElementArea
有很多Widget
个 Widget
包含我想要的Page
内容
序言: 目前似乎没有办法用 RESTful 服务器模块输出类似数组的数据结构(当然关系除外)。提议的解决方案是一种滥用 JSONDataFormatter
格式化输出的方式。
由于 JSONDataFormatter
在将字段转换为 JSON 之前使用 forTemplate
渲染字段,我们可以创建自己的对象渲染器 returns 数组而不是字符串通过 forTemplate
。这可能看起来像这样:
class FlatJSONDataList extends ViewableData
{
protected $list;
public function __construct(array $list)
{
parent::__construct();
$this->list = $list;
}
public function forTemplate()
{
return $this->list;
}
}
然后在你的页面中,有一个额外的方法就足够了,像这样:
public function getWidgetContents()
{
return FlatJSONDataList::create(
$this->ElementArea()->Widgets()->column('Content')
);
}
然后您可以在您的字段列表中包含 WidgetContents
以获取数组中的所有小部件 Content
字段:
GET /api/v1/Page/1.json?fields=Title,URLSegment,Content,WidgetContents