原始Github问题:https://github.com/zfcampus/zf-apigility-doctrine/issues/215
在代码连接的API中,三个实体及其各自的服务:场地,产品和位置。
Venue与Location
有ManyToOne关系 /**
* @ORM\ManyToOne(targetEntity="Db\Entity\Location", cascade={"persist"})
* @ORM\JoinColumn(name="location_id", referencedColumnName="id")
*
* @var Db\Entity\Location $location
*/
protected $location;
public function getLocation() {...}
public function setLocation($location) {...}
Venue与Product
有很多关系/**
* @ORM\ManyToMany(targetEntity="Db\Entity\Product", inversedBy="venues", cascade={"persist"})
* @ORM\JoinTable(name="products_venues")
**/
protected $products;
public function getProducts() {...}
public function setProducts($products) {...}
public function addProduct(Product $product)
{
$product->addVenue($this);
$this->products[] = $product;
return $this;
}
产品与Venue有很多关系
/**
* @ORM\ManyToMany(targetEntity="Db\Entity\Venue", mappedBy="products", cascade={"persist"})
**/
protected $venues;
public function getVenues() {...}
public function setVenues($venues) {...}
public function addVenues($venue)
{
$this->venues[] = $venue;
return $this;
}
现在,我有两个问题: 1)我可以创建一个新的场地和位置信息,如下所示:
POST /venues
{
.
.
.
"location":{
"address":"123 Fake Street",
"city":"cityTest",
"country":"CountryTest",
"postalCode":"12345"
}
}
使用新的位置注册表创建一个新的Venue,当我获取刚刚创建的场地时,看到两个正确链接。 当我得到刚刚创建的Venue Id时,我在_embedded中找到了其id的位置对象,但是如果我需要编辑该地址并将Venue 1与位置2而不是最初创建的位置1链接起来呢? / p>
其次,我无法使用产品创建和链接产品与在最后一个创建的同一POST调用中的场所重现此过程。 虚空想出了如何将现有产品添加到特定场馆的产品系列中。 那么,哪种方式更合适? (“1次调用创建并将它们全部链接”vs“多次创建调用+ Patch调用将它们链接在一起”)并且我需要在Apigility + Doctrine中使它们发生什么?
呜!!这是一个有趣的发现。为了更新特定场地的位置,我必须在Venues服务中添加一个新的“位置”字段。
有了这个,我可以将一个位置对象作为额外属性与/ Venues所需的属性一起发布。或者通过添加location: {"id" : 123}
来指定id(这也适用于PATCH,这是我一直在寻找的。太棒了!)。但我意识到没有实际的验证可以检查具有指定Id的位置是否确实存在。如果没有找到,则新场地将链接到“空”位置。 :皱着眉头:
所以,在那之后,我看到了包含的Apigility Doctrine验证器。 :smile:ZF\Apigility\Doctrine\Server\Validator\ObjectExists
验证我发送的对象实际存在于DB中。 Yeeyyy!我所要做的就是将其添加为“位置”字段的验证器,并根据https://github.com/doctrine/DoctrineModule/blob/master/docs/validator.md指定两个选项
entity_class = Db\Entity\Location
因此验证者知道我正在尝试验证的实体,以及fields = id
,这就像验证标准。
现在,当我尝试发布会场时,我需要使用"location": {"id":123}
指定位置。这也适用于PATCH。当找不到具有指定Id的位置时,我收到一条很棒的错误消息,这很好。如果没有ID,则提供500个(一个问题,我猜...)。
现在,我一直在努力寻找如何将对象添加到实体集合中。 (比如,将产品添加到特定场所)。我试图将“产品”字段添加到场地服务中,但没有奏效。我一直没有收集任何产品的场地。 这就是我尝试PATCH的方式:
PATCH /venues/1
{
...
"products":[
{"id": 5}
]
...
}
有关于此的任何想法吗?
答案 0 :(得分:0)
在RESTful API中进行原子CRUD操作通常是一个好主意。
在您的情况下,这意味着最好通过名为POST|GET|DELETE|PUT /location
的单独API资源来CRUD您的Location实体。
然后,API客户端首先必须检索或创建一个位置,然后才发布场地。
示例:强>
第1步。 创建或检索位置。
POST /location
{
"address":"123 Fake Street",
"city":"cityTest",
"country":"CountryTest",
"postalCode":"12345"
}
或
GET /location/{somefilter}
第2步。 创建场地
POST /venues
{
...
"location": 2 //the location id
...
}