php - 我可以通过 API 平台获取违规条目的 IRI 吗?
问题描述
我有一个 Symfony 5 项目,它使用symfony/api
(API 平台)和一个带有UniqueEntity
约束的实体(见下文。为了更好的易读性,我省略了字段注释,因为它们在这里不相关。):
/**
* @ORM\Entity(repositoryClass=CartItemRepository::class)
* @ApiResource(
* collectionOperations={"get","post"},
* itemOperations={"get","patch"},
* normalizationContext={"groups"={"cart_item:read"}}
* )
* @UniqueEntity(fields={"product","cart"})
*/
class CartItem
{
private $id;
private $product;
private $quantity;
private $cart;
/* ... */
}
假设我有一些数据:
----------------------------------------
| id | product_id | cart_id | quantity |
| 1 | 3 | 2 | 1 |
| 2 | 2 | 2 | 2 |
----------------------------------------
现在如果我发送这个 POST 请求:
{
"product": "/api/products/3",
"quantity": 1,
"cart": "/api/carts/2"
}
我当然会期待这个响应,因为400
插入这个条目会破坏ID 1 已经使用的唯一性:[product_id,cart_id]
[3,2]
{
"@context": "/api/contexts/ConstraintViolationList",
"@type": "ConstraintViolationList",
"hydra:title": "An error occurred",
"hydra:description": "product: This value is already used.",
"violations": [
{
"propertyPath": "product",
"message": "This value is already used."
}
]
}
我的问题是:我是否有办法获取“重复”的实体的 IRI 或 ID?(这里,ID 应该是 1,IRI 应该是/api/cart_items/1
)。我想要实现的是ON DUPLICATE KEY UPDATE quantity = quantity + :quantity
通过检测此错误并在发生时发送请求来重现 MySQL 的行为,PATCH
但是要发送PATCH
请求,我需要 IRI,或者至少需要我想要修补的项目的 ID。
编辑 :
我在 Profiler 中看到这是可见的(请参见cause
下面的字段),但我无法获得 API 的响应......
Symfony\Component\Validator\ConstraintViolation {#2332 ▼
-message: "This value is already used."
-messageTemplate: "This value is already used."
-parameters: [▶]
-plural: null
-root: App\Entity\CartItem {#675 ▼
-id: null
-product: App\Entity\Product {#1888 …}
-quantity: 1
-cart: App\Entity\Cart {#2119 …}
}
-propertyPath: "product"
-invalidValue: App\Entity\Product {#1888 …}
-constraint: Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity {#2130 …}
-code: "23bd9dbf-6b9b-41cd-a99e-4844bcf3077f"
-cause: [▼
App\Entity\CartItem {#2330 ▼
-id: 2
-product: App\Entity\Product {#1888 …}
-quantity: 2
-cart: App\Entity\Cart {#2119 …}
}
]
}
解决方案
在这种情况下,我总是使用 API 过滤器(https://api-platform.com/docs/core/filters/)。在发送 POST 请求之前,发送 GET 请求以检查实体是否存在。例如,为过滤器添加注释:
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
/**
* @ORM\Entity(repositoryClass=CartItemRepository::class)
* @ApiResource(
* collectionOperations={"get","post"},
* itemOperations={"get","patch"},
* normalizationContext={"groups"={"cart_item:read"}}
* )
* @UniqueEntity(fields={"product","cart"})
*
* @ApiFilter(SearchFilter::class, properties={"product": "exact", "cart": "exact"})
*/
class CartItem
{
private $id;
private $product;
private $quantity;
private $cart;
/* ... */
}
并使用 URL 获取现有实体,如下所示:GET /cart_items?product=3&cart=2
你应该得到一个集合。因此,如果 "hydra:totalItems" > 0
从响应中,您可以从"hydra:member"[0]
推荐阅读
- debugging - 有没有办法确定尝试连接到“HTTP 服务器”的协议?
- apache-karaf - 在 Jboss Fuse 6.3 上实现 REST OSGI 服务
- sql - Postgres:选择多列并与数组进行比较
- laravel - 无法在 Laravel 的 groupBy 函数中合并列数据
- excel - 从 powerpoint 演示文稿(VBA、powerpoint)打开 Excel 文档
- java - Java Client-Server:实时流式传输音频文件
- python - 通过在 matplotlib 中用 X 替换数字来隐藏数字的第一个值
- javascript - 如何在不折叠的情况下禁用所有 Kendo TreeView 节点
- php - 如何使用 <= - mysql 从数据库中查询值
- python-3.x - 将 wav 转换为文本