1
0
mirror of https://github.com/flarum/core.git synced 2025-10-10 06:24:26 +02:00

Update API action architecture

- An API action handles a Flarum\Api\Request, which is a simple object
containing an array of params, the actor, and optionally an HTTP
request object
- Most API actions use SerializeAction as a base, which parses request
input according to the JSON-API spec (creates a JsonApiRequest object),
runs the child class method to get data, then serializes it and assigns
it to a JsonApiResponse (standard HTTP response with a
Tobscure\JsonApi\Document as content)
- The JSON-API request input parsing is subject to restrictions as
defined by public static properties on the action (i.e. extensible)
- Also the actor is given to the serializer instance now, instead of
being a static property
This commit is contained in:
Toby Zerner
2015-05-02 08:56:43 +09:30
parent 5ea864ba89
commit a426fa6560
23 changed files with 673 additions and 378 deletions

View File

@@ -0,0 +1,160 @@
<?php namespace Flarum\Api\Actions;
use Flarum\Api\Request;
use Flarum\Api\JsonApiRequest;
use Flarum\Api\JsonApiResponse;
use Tobscure\JsonApi\SerializerInterface;
use Tobscure\JsonApi\Criteria;
abstract class SerializeAction implements ActionInterface
{
/**
* The name of the serializer class to output results with.
*
* @var string
*/
public static $serializer;
/**
* The relations that are available to be included.
*
* @var array
*/
public static $includeAvailable = [];
/**
* The relations that are included by default.
*
* @var array
*/
public static $include = [];
/**
* The relations that are linked by default.
*
* @var array
*/
public static $link = [];
/**
* The maximum number of records that can be requested.
*
* @var integer
*/
public static $limitMax;
/**
* The number of records included by default.
*
* @var integer
*/
public static $limit;
/**
* The fields that are available to be sorted by.
*
* @var array
*/
public static $sortAvailable = [];
/**
* The default field to sort by.
*
* @var string
*/
public static $sort;
/**
* Handle an API request and return an API response.
*
* @param Flarum\Api\Request $request
* @return Flarum\Api\Response
*/
public function handle(Request $request)
{
$request = static::buildJsonApiRequest($request);
$data = $this->data($request, $response = new JsonApiResponse);
$serializer = new static::$serializer($request->actor, $request->include, $request->link);
$response->content->setData($this->serialize($serializer, $data));
return $response;
}
/**
* Get the data to be serialized and assigned to the response document.
*
* @param Flarum\Api\JsonApiRequest $request
* @param Flarum\Api\JsonApiResponse $response
* @return array
*/
abstract protected function data(JsonApiRequest $request, JsonApiResponse $response);
/**
* Serialize the data as appropriate.
*
* @param \Tobscure\JsonApi\SerializerInterface $serializer
* @param array $data
* @return \Tobscure\JsonApi\Elements\ElementInterface
*/
abstract protected function serialize(SerializerInterface $serializer, $data);
/**
* Extract parameters from the request input and assign them to the
* request, restricted by the action's specifications.
*
* @param Flarum\Api\Request $request
* @return void
*/
protected static function buildJsonApiRequest(Request $request)
{
$request = new JsonApiRequest($request->input, $request->actor, $request->httpRequest);
$criteria = new Criteria($request->input);
$request->include = static::sanitizeInclude($criteria->getInclude());
$request->sort = static::sanitizeSort($criteria->getSort());
$request->offset = $criteria->getOffset();
$request->limit = static::sanitizeLimit($criteria->getLimit());
$request->link = static::$link;
return $request;
}
/**
* Sanitize an array of included relationships according to the action's
* configuration.
*
* @param array $include
* @return array
*/
protected static function sanitizeInclude(array $include)
{
return array_intersect($include, static::$includeAvailable) ?: static::$include;
}
/**
* Sanitize an array of sort criteria according to the action's
* configuration.
*
* @param array $sort
* @return array
*/
protected static function sanitizeSort(array $sort)
{
return array_intersect_key($sort, array_flip(static::$sortAvailable)) ?: static::$sort;
}
/**
* Sanitize a limit according to the action's configuration.
*
* @param int $limit
* @return int
*/
protected static function sanitizeLimit($limit)
{
return min($limit, static::$limitMax) ?: static::$limit;
}
}