symfony搭配api platform开发API(3),分组 langziyang Symfony博客 282 views 上一节我们添加了Book实体,也通过iri添加了一本书到id为1的分类里,查询时返回了这本书的信息,但是书的分类也是一个iri 如果想要返回这本书的分类名称怎么处理呢?很简单,这一节我们用序列化分组来表示,首先我们在Book.php上进行修改 ```php #src/Entity/Book.php use Symfony\Component\Serializer\Annotation\Groups; #[ApiResource( normalizationContext: ['groups'=>'book.read'], )] class Book { #[Groups(['book.read'])] private ?int $id = null; #[Groups(['book.read'])] private ?string $name = null; #[Groups(['book.read'])] private ?Category $category = null; #[Groups(['book.read'])] private ?string $cover = null; #[Groups(['book.read'])] private ?\DateTimeImmutable $createdAt = null; } ``` 然后我们去Category.php里修改 ```php #src/Entity/Category.php use Symfony\Component\Serializer\Annotation\Groups; class Category { #[Groups(['book.read'])] private ?string $name = null; } ``` 可以看到我们在Book.php的ApiResource里添加了一个normalizationContext: ['groups'=>'book.read'],该参数表示序列化分组,添加完这个参数后, 我们会给需要序列化的属性添加#[Groups(['book.read'])],这样就保证了每一次返回该实体的哪些属性,我们给Category.php的name属性也添加了#[Groups(['book.read'])]。 然后去读取数据就会看到不一样的数据: ```text { "@id": "/api/books/1", "@type": "Book", "id": 1, "name": "Symfony开发入门", "category": { "@id": "/api/categories/1", "@type": "Category", "name": "编程语言" }, "createdAt": "2023-09-17T02:02:18+08:00" } ``` 分类的name被返回过来了,你可能会觉得返回数据的格式和我们平时手写时返回的数据不一样,甚至会觉得返回的数据很奇怪,是的,我第一次接触时也有这种想法, 为什么不返回 "category":"编程语言"?,如果我们在category里除了name还有其它数据需要返回呢?id、description、cover...., 你也许会发现返回Book实体中的createdAt格式并不是我们想要的,如果我们想格式化一下怎么做呢?根据序列化过程,你可以写一个自定义序列化过程,但是我们 在这里使用一个简单的方式: ```php #src/Entity/Book.php use Symfony\Component\Serializer\Annotation\Context; use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; class Book { #[Context([DateTimeNormalizer::FORMAT_KEY=>'Y-m-d'])] private ?\DateTimeImmutable $createdAt = null; } ``` 同时你可能会发现,在序列化后,空值为什么没返回,比如添加书时我们没有添加cover值,这是因为api platform默认不返回空值(根据版本差异不同)。 修改一下: ```php #src/Entity/Book.php #[ApiResource( normalizationContext: ['groups'=>'book.read', 'skip_null_values' => false] )] ``` 那么Book这个实体就会返回空值字段了,如果你想全局配置返回,需要配置yaml文件 ```yaml #/config/packages/api_platform.yaml api_platform: defaults: normalization_context: skip_null_values: true ``` 我们上面是讲的序列化分组,对应的也有反序列化分组,即提交数据时有一些字段不需要或者不允许用户提交,比如说createdAt,一般为自动生成,只需要添加: ```php #[ApiResource( normalizationContext: ['groups'=>'book.read', 'skip_null_values' => false], denormalizationContext: ['groups'=>'book.write'] )] ``` 序列化与反序列化分组就完成了,这样的写法表示在所有CRUD过程中都按这个分组来操作,如果你想给每一个操作都定义一个不同的分组,则需要按以下方式写: ```php #[ApiResource( operations: [ new GetCollection(normalizationContext: ['groups'=>'book.list']), new Get(normalizationContext: ['groups.item']), new Post(normalizationContext: ['groups.item'],denormalizationContext: ['groups'=>'groups.post']), new Patch(normalizationContext: ['groups.item'],denormalizationContext: ['groups'=>'groups.patch']), ] )] ``` 这样你可以对整个过程进行更精细的控制 帮助PHPZlc项目! 与任何开源项目一样, 贡献代码 或 文档 是最常见的帮助方式, 但我们也有广泛的 赞助机会。 3 赞赏 加入技术群 评论 去登录