我正在将ZF2与"zfcampus/zf-rest":"1.2.0"
一起使用以返回API结果。
对于名为Tag
的资源,我收到以下响应:
{
"_links": {
"self": {
"href": "http://mydomain/article/tags"
}
},
"_embedded": {
"tags": [
{
"id": 1,
"tag": "news",
"isOfficial": true,
"_links": {
"self": {
"href": "http://mydomain/article/tags"
}
}
}
]
},
"total_items": 1
}
但是,我想摆脱标签资源下的_links
属性,以便获得更干净的输出。
我想要实现的目标看起来像这样;
{
"_links": {
"self": {
"href": "http://mydomain/article/tags"
}
},
"_embedded": {
"tags": [
{
"id": 1,
"tag": "news",
"isOfficial": true
}
]
},
"total_items": 1
}
如何实现此行为?
请注意,端点的路由器实现为:
'api.rest.article.tags' => [
'type' => 'Segment',
'options' => [
'route' => '/article/tags',
'defaults' => [
'controller' => 'Api\V1\ArticleTag\Controller',
],
],
],
答案 0 :(得分:1)
在使用ZF Hal时,您将得到这样的渲染结果,因为自链接是Hal-Json标准的重要组成部分,并且您的Tag
被视为Hal资源,并且将按照上面的示例进行渲染。您可能为此类注册了元数据和水化器,并使用它们来提取这样的实体。
如果您不想将Tag
呈现为Hal资源,那么您的解决方案就很简单,只需删除该类的元数据和水化器,然后在您的目录中实现一个JsonSerializable
接口类,并添加一个返回所需结果的jsonSerialize方法。呈现器将在呈现它的同时调用jsonSerialize
...
当未找到Hydrator且对象实现此JsonSerializable接口时,这是提取对象的后备。
您可以看到here in the extractEntity method:
if ($hydrator) {
return $hydrator->extract($entity);
}
if ($entity instanceof JsonSerializable) {
return $entity->jsonSerialize();
}
在JsonSerializable上查看此博客文章:https://www.sitepoint.com/use-jsonserializable-interface/
希望这对您有用,如果您不能随意发表评论,我可以看看是否可以建议其他解决方案。
答案 1 :(得分:0)
更新来自OP的评论使此答案变得多余。保留它可能会帮助某人。如果您使用的是完整的Apigility,则适合您。
其中一个是,V1.2。*版本已在July 2016中发布,因此我建议您从更新应用程序开始。
此外,为什么您要尝试“清理”它呢?获取集合时,删除用于检索单个对象的直接链接毫无用处。
您正在执行“ GET / tags”调用(集合),但您想获得一个对象。
要获取单个商品,请执行“ GET / tags /:id”调用,例如“ GET / tags / 1”。
单个项目的响应应该是这样的(可能有所不同,为此使用最新的适应性):
(请注意,本地开发环境,这就是“ http”的原因)
单次通话:“获取http://api.loc/coordinates/1”
{
"latitude": "33.6062068",
"longitude": "58.7053709",
"id": 1,
"_links": {
"self": {
"href": "http://api.loc/coordinates/1"
}
}
}
催缴电话:“获取http://api.loc/coordinates”
{
"_links": {
"self": {
"href": "http://api.loc/coordinates?page=1"
},
"first": {
"href": "http://api.loc/coordinates"
},
"last": {
"href": "http://api.loc/coordinates?page=10"
},
"next": {
"href": "http://api.loc/coordinates?page=2"
}
},
"_embedded": {
"coordinates": [
{
"latitude": "33.6062068",
"longitude": "58.7053709",
"id": 1,
"_links": {
"self": {
"href": "http://api.loc/coordinates/1"
}
}
},
{
"latitude": "60.1948871",
"longitude": "19.2423547",
"id": 2,
"_links": {
"self": {
"href": "http://api.loc/coordinates/2"
}
}
},
{ ... } another 247 results
]
},
"page_count": 10,
"page_size": 25,
"total_items": 249,
"page": 1
}
链接应使用LinkExtractor
类生成,您可以通过配置类来应用策略。如果您使用的是Apigility(使用您提到的zfcampus/zf-rest
模块),则可以应用如下策略:
[ ... ] // more config
'doctrine-hydrator' => [
'Company\\V1\\Rest\\Company\\CompanyHydrator' => [
'entity_class' => \Path\To\Company::class,
'object_manager' => 'doctrine.entitymanager.orm_default',
'by_value' => true,
'strategies' => [
'country' => \ZF\Doctrine\Hydrator\Strategy\EntityExtract::class,
'currency' => \ZF\Doctrine\Hydrator\Strategy\EntityLink::class,
'currencies' => \ZF\Doctrine\Hydrator\Strategy\CollectionExtract::class,
],
[ ... ] // more config
它们是由汤姆·安德森(Tom Anderson)的ZF Doctrine Hydrator包裹提供的。
*Link
策略提供了指向对象的链接,例如可以在GET调用中使用的链接。
*Extract
策略直接确保将实体合并到结果中并返回而不是链接。
专门用于删除该_links
位。如果使用zf-rest
是因为使用了Apigility,则链接是由zf-hal
的配置引起的,则可以在{{1}中使用'force_self_link' => false
选项}配置。这必须按组完成。
请参见this Apigility docs page并搜索“ force_self_link”。
force_self_link-布尔值;设置是否应为实体自动生成自引用链接。默认为true(因为推荐)。
我同意docs:建议保持启用状态。
更新来自OP的评论使此答案变得多余。保留它可能会帮助某人。