API平台关系方法GET

API platform relations method GET

我正在使用 API 平台创建一个 API 以在 JSON 文件中显示我所有的开发项目。
我已经完成了我的实体和关系,它工作得很好。
但问题是当我尝试获取所有项目时,在建立关系的地方它显示 API url 和 id 而不是显示名称。

这是返回的 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"
      ]
    }
  ]
}

这是 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?

当且仅当 nameTechnologie 的唯一 属性 您可以将标识符从 idname:

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, ...
}

在这种情况下,输出将如下所示(假设名称的值为 superbe):

// ... beginning
"technologies": [
    "/api/technologies/superbe",
    // ... other technologies
],
// ... ending

消费者必须向 /api/technologies/superbe 发出 GET 请求,以获取具有给定名称的资源 Technologie。只是标识符不是id,而是name。

设计 REST 时 API 您应该提前考虑如何使用它。
如果我向 /api/projets/78 发出 GET 请求,是否需要检索所有相关的 technologiesoutils?这将避免消费者发出大量昂贵的 HTTP 请求,但结果将相当庞大,他们可能不一定需要所有这些。
或者我是否可以向我需要的那些资源发出进一步的 GET 请求。然后我会得到更轻的响应,但必须发出额外的 HTTP 请求。

您可能会阅读有关 HATEOAS 的维基百科文章,该文章与您的问题部分相关。