从 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/

希望这对你有用,如果不方便发表评论,我可以看看是否可以提出替代解决方案。