从 zf-rest 模块上的 _embedded 资源中删除“_links”属性
Remove '_links' property from _embedded resources on zf-rest module
我正在使用 ZF2,结果为 "zfcampus/zf-rest":"1.2.0"
到 return 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',
],
],
],
UPDATE 来自 OP 的评论使这个答案变得多余。保留它可能对某人有帮助。如果您使用的是完整的 Apigility,那么这是给您的。
首先,V1.2.* 版本在 July 2016 中发布,因此我建议您从更新您的应用程序开始。
另外,你为什么要尝试 "clean" 呢?删除直接 links 以检索单个对象在获取集合时毫无用处。
您正在进行 "GET /tags" 调用(集合),但您想要获取单个对象。
要获取单件商品,请拨打 "GET /tags/:id" 电话,例如"GET /tags/1".
单个项目的响应应该是这样的(可能会有所不同,为此使用最新的 Apigility):
(注意,本地开发环境,这就是为什么 "http")
单次调用:"GET http://api.loc/coordinates/1"
{
"latitude": "33.6062068",
"longitude": "58.7053709",
"id": 1,
"_links": {
"self": {
"href": "http://api.loc/coordinates/1"
}
}
}
催收:"GET 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
class 生成链接,您可以通过配置为其使用策略。如果您使用的是 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
策略为对象提供 links,links 可用于 GET 调用等实例。
*Extract
策略直接确保实体与结果混合并返回,而不是 link。
专门用于删除 _links
位。如果您使用 zf-rest
是因为您使用的是 Apigility,因此 link 是由 zf-hal
的配置引起的,那么您可以使用 'force_self_link' => false
选项'zf-hal' => []
配置。这必须每组完成。
查看 this Apigility docs page 并搜索 "force_self_link"。
force_self_link - boolean; set whether a self-referencing link should be automatically generated for the entity. Defaults to true (since its recommended).
我同意文档:建议保持启用状态。
UPDATE 来自 OP 的评论使这个答案变得多余。保留它可能对某人有帮助。
当使用 ZF Hal 时,你会得到这样的渲染结果,因为自链接是 Hal-Json 标准的重要组成部分,你的 Tag
被认为是 Hal 资源,将被渲染为你的上面的例子。您可能为此 class 注册了 meta-data 和一个水化器,它们用于提取这样的实体。
如果您不想将 Tag
呈现为 Hal 资源,您的解决方案可以像删除 meta-data 和 class 的水化器一样简单,只需实现一个JsonSerializable
接口到您的 class 并添加一个 jsonSerialize 方法,该方法 returns 想要的结果。渲染器将在渲染时调用 jsonSerialize
...
当没有找到 Hydrator 并且对象实现了这个 JsonSerializable 接口时,这是提取对象的后备方法。
你可以看到 here in the extractEntity method:
if ($hydrator) {
return $hydrator->extract($entity);
}
if ($entity instanceof JsonSerializable) {
return $entity->jsonSerialize();
}
在 JsonSerializable 上查看此博客 post:https://www.sitepoint.com/use-jsonserializable-interface/
希望这对你有用,如果不方便发表评论,我可以看看是否可以提出替代解决方案。
我正在使用 ZF2,结果为 "zfcampus/zf-rest":"1.2.0"
到 return 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',
],
],
],
UPDATE 来自 OP 的评论使这个答案变得多余。保留它可能对某人有帮助。如果您使用的是完整的 Apigility,那么这是给您的。
首先,V1.2.* 版本在 July 2016 中发布,因此我建议您从更新您的应用程序开始。
另外,你为什么要尝试 "clean" 呢?删除直接 links 以检索单个对象在获取集合时毫无用处。
您正在进行 "GET /tags" 调用(集合),但您想要获取单个对象。
要获取单件商品,请拨打 "GET /tags/:id" 电话,例如"GET /tags/1".
单个项目的响应应该是这样的(可能会有所不同,为此使用最新的 Apigility):
(注意,本地开发环境,这就是为什么 "http")
单次调用:"GET http://api.loc/coordinates/1"
{
"latitude": "33.6062068",
"longitude": "58.7053709",
"id": 1,
"_links": {
"self": {
"href": "http://api.loc/coordinates/1"
}
}
}
催收:"GET 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
class 生成链接,您可以通过配置为其使用策略。如果您使用的是 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
策略为对象提供 links,links 可用于 GET 调用等实例。
*Extract
策略直接确保实体与结果混合并返回,而不是 link。
专门用于删除 _links
位。如果您使用 zf-rest
是因为您使用的是 Apigility,因此 link 是由 zf-hal
的配置引起的,那么您可以使用 'force_self_link' => false
选项'zf-hal' => []
配置。这必须每组完成。
查看 this Apigility docs page 并搜索 "force_self_link"。
force_self_link - boolean; set whether a self-referencing link should be automatically generated for the entity. Defaults to true (since its recommended).
我同意文档:建议保持启用状态。
UPDATE 来自 OP 的评论使这个答案变得多余。保留它可能对某人有帮助。
当使用 ZF Hal 时,你会得到这样的渲染结果,因为自链接是 Hal-Json 标准的重要组成部分,你的 Tag
被认为是 Hal 资源,将被渲染为你的上面的例子。您可能为此 class 注册了 meta-data 和一个水化器,它们用于提取这样的实体。
如果您不想将 Tag
呈现为 Hal 资源,您的解决方案可以像删除 meta-data 和 class 的水化器一样简单,只需实现一个JsonSerializable
接口到您的 class 并添加一个 jsonSerialize 方法,该方法 returns 想要的结果。渲染器将在渲染时调用 jsonSerialize
...
当没有找到 Hydrator 并且对象实现了这个 JsonSerializable 接口时,这是提取对象的后备方法。
你可以看到 here in the extractEntity method:
if ($hydrator) {
return $hydrator->extract($entity);
}
if ($entity instanceof JsonSerializable) {
return $entity->jsonSerialize();
}
在 JsonSerializable 上查看此博客 post:https://www.sitepoint.com/use-jsonserializable-interface/
希望这对你有用,如果不方便发表评论,我可以看看是否可以提出替代解决方案。