2015-07-19 83 views
0

原始Github上问题的工作:https://github.com/zfcampus/zf-apigility-doctrine/issues/215与相关/嵌入实体

在代码连接API,包括三个实体各自的服务:地点,产品和位置。

地点与地点一个多对一关系

/** 
    * @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) {...} 

场馆与产品多对多关系

/** 
* @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; 
} 

和产品有场地多对多关系现在

/** 
* @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" 
    } 
} 

和一个新的场地是一个新的位置注册表中创建,并同时看到正确链接,当我刚刚创建的场所。 当我刚刚创建了场地Id时,我发现位置对象的ID在_embedded中,但如果我需要编辑该地址并将场地1与位置2相连接,而不是最初创建的位置1,该怎么办?

其次,我无法复制这个过程,产品创建和链接产品与场地在同一个POST调用中创建最后一个。 下界想出了如何将现有产品添加到特定场所的产品集合中。 那么,哪种方式更合适? (“1次调用创建并链接它们”与“多次创建调用+修补程序调用将它们链接在一起”)以及我需要在Apigility + Doctrine中使它们发生的事情?

更新7月20日:

Woo !!这是有趣的发现。为了更新特定场地的位置,我必须在Venues服务中添加一个新的“位置”字段。 有了这个,我可以将一个位置对象作为一个额外的属性和/ Venues所需的属性一起发布。或者通过添加location: {"id" : 123}来指定ID(这也适用于PATCH,这正是我一直在寻找的,太棒了!)。但是我意识到没有实际的验证来检查具有指定Id的位置实际上是否存在。如果没有找到,那么新场地将被链接到“空”位置。 :皱眉:

所以,在那之后,我看到了包含Apigility Doctrine验证器。 :smile:ZF\Apigility\Doctrine\Server\Validator\ObjectExists验证我发送的对象实际上存在于数据库中。 Yeeyyy!我所要做的就是将其添加为“位置”字段的验证器,并根据https://github.com/doctrine/DoctrineModule/blob/master/docs/validator.md entity_class = Db\Entity\Location指定两个选项,以便验证程序知道我要验证的实体以及fields = id,这与验证标准相似。

现在,当我尝试发布场地时,我需要使用"location": {"id":123}指定位置。这也与PATCH合作。当找不到指定ID的位置时,我会收到一个很棒的错误消息,这很好。如果没有提供身份证,则有500人(我想,时间上有一个问题,我猜...)。

现在,我一直试图找到如何将对象添加到实体集合。 (比如,将产品添加到特定场所)。我试图将“产品”字段添加到场馆服务中,但没有奏效。我一直在收集场地中没有任何产品。 这是我正在努力修补程序:

PATCH /venues/1 
{ 
... 
"products":[ 
    {"id": 5} 
] 
... 
} 

在这个任何想法?

回答

0

通常在RESTful API中具有原子CRUD操作是一个好主意。

对您而言,这意味着您最好通过一个名为POST|GET|DELETE|PUT /location的单独API资源来CRUD您的位置实体。

然后,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 
    ... 
    } 
+0

是,它使一个很大的意义的REST API,以这样的工作,但在这种情况下,我在我的项目中使用Apigility与Doctrine模块(zf-apigility-doctrine),我无法找到实现它的方式那个。 我可以创建Venue和Address,也可以通过在Venue字段+位置执行POST /场所来链接它们。我只是无法找到执行PATCH /场馆/ 2 _ {“location”:123} _ 的方法有意义吗? – arthos4g

+0

你的'PATCH /场馆/ {id}'端点是否有'位置'字段? – Mark

+0

在我看来,一旦你在你的服务中创建了一个'/ location'端点,然后在你的'/ venues'端点上添加一个'location'字段,那么一切都应该起作用。 ***注意:***不要忘记删除旧的'location'字段,因为那个人需要一个'array'而不是一个整数, – Mark