[英]FOSRestBundle: partial response in function of attributes asked in the request
我發現了許多關於使用FOSRest進行部分API響應的問題,所有答案都基於JMS序列化程序選項(exlude,include,groups等)。 它工作正常,但我試圖實現一些不那么“靜態”的東西。
假設我有一個具有以下屬性的用戶: id
username
firstname
lastname
age
sex
我使用端點GET /users/{id}
和以下方法檢索此用戶:
/**
* @View
*
* GET /users/{id}
* @param integer $user (uses ParamConverter)
*/
public function getUserAction(User $user) {
return $user;
}
該方法返回用戶的所有屬性。
現在我想允許這樣的東西: GET /users/{id}?attributes=id,username,sex
我是否錯過了FOSRestBUndle,JMSserializer或SensioFrameworkExtraBundle的功能來自動實現它? 請求中的注釋,方法,關鍵字或其他內容?
否則,實現它的最佳方法是什么?
我想做類似的事情:
/**
* @View
* @QueryParam(name="attributes")
*
* GET /users/{id}
*
* @param integer $user (uses ParamConverter)
*/
public function getUserAction(User $user, $attributes) {
$groups = $attributes ? explode(",", $attributes) : array("Default");
$view = $this->view($user, 200)
->setSerializationContext(SerializationContext::create()->setGroups($groups));
return $this->handleView($view);
}
並為每個屬性創建一個組:
use JMS\Serializer\Annotation\Groups;
class User {
/** @Groups({"id"}) */
protected $id;
/** @Groups({"username"}) */
protected $username;
/** @Groups({"firstname"}) */
protected $firstname;
//etc
}
我的實現基於Igor的答案 :
ExlusionStrategy:
use JMS\Serializer\Exclusion\ExclusionStrategyInterface;
use JMS\Serializer\Metadata\ClassMetadata;
use JMS\Serializer\Metadata\PropertyMetadata;
use JMS\Serializer\Context;
class FieldsExclusionStrategy implements ExclusionStrategyInterface {
private $fields = array();
public function __construct(array $fields) {
$this->fields = $fields;
}
public function shouldSkipClass(ClassMetadata $metadata, Context $navigatorContext) {
return false;
}
public function shouldSkipProperty(PropertyMetadata $property, Context $navigatorContext) {
if (empty($this->fields)) {
return false;
}
if (in_array($property->name, $this->fields)) {
return false;
}
return true;
}
}
控制器:
/**
* @View
* @QueryParam(name="fields")
*
* GET /users/{id}
*
* @param integer $user (uses ParamConverter)
*/
public function getUserAction(User $user, $fields) {
$context = new SerializationContext();
$context->addExclusionStrategy(new FieldsExclusionStrategy($fields ? explode(',', $fields) : array()));
return $this->handleView($this->view($user)->setSerializationContext($context));
}
終點:
GET /users/{id}?fields=id,username,sex
正如您所示,您可以通過群組進行此操作。 也許更優雅的解決方案是實現您自己的ExclusionStrategy 。 @Groups和其他也是ExclusionStrategyInterface的實現。
所以,比如你說你的策略是SelectFieldsStrategy 。 實現后,您可以非常輕松地將其添加到序列化上下文中:
$context = new SerializationContext();
$context->addExclusionStrategy(new SelectFieldsStrategy(['id', 'name', 'someotherfield']));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.