在页面API请求中包含相关的模型数据

时间:2016-02-25 22:07:48

标签: php api silverstripe

我使用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有很多Widget s
  • Widget包含我想要的Page
  • 内容

1 个答案:

答案 0 :(得分:2)

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

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