【问题标题】:Including related model data in Page API request在 Page API 请求中包含相关模型数据
【发布时间】:2016-06-08 22:31:33
【问题描述】:

我使用 SilverStripe 3.2.1 和 restfulserver addon 运行了一个相对简单的设置,并使用了各种与使用 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 的 Content 字段与初始 Page API 请求一起以数组形式返回。


供参考:

  • 一个页面有一个ElementArea
  • 一个ElementArea有很多Widgets
  • Widget 包含我想要用于我的Page 的内容

【问题讨论】:

  • 那个额外的数组会包含什么?只是内容?还是带有 Widget-ID、href 和 Content 字段的对象?
  • 真的不用大惊小怪。最终,我需要通过 ElementalArea 数据透视表将页面中小部件中的内容与页面一起返回。

标签: php api silverstripe


【解决方案1】:

序言:目前似乎没有一种方法可以使用 RESTful 服务器模块输出类似数组的数据结构(当然,关系除外)。提议的解决方案是一种滥用JSONDataFormatter 格式输出的hack。

由于JSONDataFormatter 使用forTemplate 在将字段转换为JSON 之前对其进行渲染,因此我们可以创建自己的对象渲染器,该渲染器通过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 

【讨论】:

  • 谢谢 - 今天晚些时候我会试一试。我假设因为 Widget 本身不是 Page 的关系(而是 ElementalArea ),所以默认情况下它在 Page 的字段列表中不可用?
  • @RobbieAverill 是的,似乎还没有实现大于一级的关系深度,否则这样的东西可能是一个有效的字段名称:ElementArea.Widgets。现在我认为你被黑客所困,或者你可以实现自己的DataFormatter 子类。后者意味着您将不得不编写更多代码,但可能不太容易因未来的更新而中断。
  • 谢谢 - 您的回答非常有帮助。不幸的是,事实证明 Elemental 插件对不同的数据类型使用不同的字段名称,所以我不得不添加一个静态属性来定义要返回的字段,并在格式化之前循环检索每个字段的 Elements。虽然它很有魅力 - 非常有用的答案!
猜你喜欢
  • 1970-01-01
  • 2014-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多