我正在使用API平台创建一个API,以在JSON文件中显示我所有的开发项目。
我已经完成了我的实体和关系,完美地工作了。
但是问题是当我尝试获取所有项目时,在建立关系的地方,它显示带有ID的API URL,而不是显示名称。
这是返回的JSON:
{
"@context": "/api/contexts/Projets",
"@id": "/api/projets",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/projets/78",
"@type": "Projets",
"id": 78,
"titre": "Pwet",
"date": "2021-01-01T00:00:00+01:00",
"description": "jtyrtjhetrjrtj",
"image": "rtjrtjrt",
"lienGit": "rtjrtjrtjrtj",
"lienProjet": "rtjtrjtrjtrjrtj",
"technologies": [
"/api/technologies/10", <- I would like the technologie name
"/api/technologies/17",
"/api/technologies/18",
"/api/technologies/19",
"/api/technologies/20",
"/api/technologies/21",
"/api/technologies/22",
"/api/technologies/23",
"/api/technologies/24",
"/api/technologies/25",
"/api/technologies/26",
"/api/technologies/36",
"/api/technologies/37"
],
"outils": [
"/api/outils/4", <- I would like the outil name
"/api/outils/5"
]
}
]
}
答案 0 :(得分:2)
这是API平台的默认行为。除非您在代码中指定,否则它无法知道您真正想要的是什么。不幸的是,您尚未为实体提供代码,因此稍后我将在一个示例中作一些即兴的演示。
首先,您必须了解REST API设计的一些原则。提供类似/api/technologies/37
之类的内容将使使用者可以发出另一个HTTP GET请求来检索资源 Technologie (或 Technology )。 Outil (或 Tool )也是如此。
如果仅提供技术名称,那么消费者将如何获得该资源的其他属性?
您可以使用Groups
指定应显示的属性。它可能类似于以下示例:
Projet.php
namespace App\Entity; // just an example, your namespace might differ
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ApiResource(
* attributes={
* "normalization_context"={"groups"={"read"}},
* }
* )
*/
class Projet
{
/**
* @Groups({"read"})
*/
private $id;
/**
* @Groups({"read"})
*/
private $titre;
// other fields ...
/**
* @Groups({"read"})
*/
private $technologies;
// more fields, getters, setters, ...
}
Technologie.php
namespace App\Entity; // just an example, your namespace might differ
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ApiResource(
* attributes={
* "normalization_context"={"groups"={"read"}},
* }
* )
*/
class Technologie
{
private $id;
/**
* @Groups({"read"})
*/
private $name;
private $someOtherProperty;
// otehr fields, getters, setters, ...
}
现在,这将检索属性名称的值,例如:
// ... beginning
"technologies": [
{
"@id": "technologies/10",
"@type": "Technologie",
"name": "Une technologie superbe"
},
// ... other technologies
],
// ... ending
documentation中对此方法进行了很好的解释。
在这里,您最终将在代码示例之前想到这个问题。消费者使用的名称是什么?他们是否需要了解有关该技术的所有信息?他们会发出额外的GET请求来获取资源 Technologie 吗?
当且仅当 name 是 Technologie 的唯一属性,您才可以将标识符从 id 更改为 name :
namespace App\Entity; // just an example, your namespace might differ
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiProperty;
/**
* @ApiResource()
*/
class Technologie
{
/**
* @ApiProperty(identifier=false)
*/
private $id;
/**
* @ApiProperty(identifier=true)
*/
private $name;
// otehr fields, getters, setters, ...
}
在这种情况下,输出将看起来像(假设name的值为 superbe ):
// ... beginning
"technologies": [
"/api/technologies/superbe",
// ... other technologies
],
// ... ending
消费者必须向/api/technologies/superbe
发出GET请求,以获取具有给定名称的资源 Technologie 。只是标识符不是ID,而是名称。
在设计REST API时,您应该提前考虑如何使用它。
如果我向/api/projets/78
发出GET请求,是否需要检索所有相关的technologies
和outils
?这样可以节省使用者发出大量昂贵的HTTP请求的时间,但结果将是非常庞大的,它们可能不一定需要所有这些请求。
还是可以给我所需的那些资源发出进一步的GET请求的可能性。然后,我会得到较轻的响应,但是必须发出其他HTTP请求。
您可能会阅读有关HATEOAS的Wikipedia文章,该文章与您的问题部分相关。