API

正如介绍所述,Flarum 有一个公开的 JSON API 允许你读写论坛数据。它符合 JSON-API 1.0 规范

在本节中我们将深入探讨如何扩展 Flarum 的 API。

JSON-API 和序列化程序(Serializers)

Flarum 使用 tobscure/json-api 库来输出符合 JSON-API 规范的格式化数据。这涉及序列化程序的使用,该程序是 Flarum\Api\Serializers 命名空间下的一个类,能将 Flarum 的数据转换成一个可被公开接受的格式。

属性

可使用 ApiAttributes 事件对序列化程序进行增改:

  1. use Flarum\Api\Serializers\DiscussionSerializer;
  2. use Flarum\Events\ApiAttributes;
  3. $events->listen(ApiAttributes::class, function (ApiAttributes $event) {
  4. if ($event->serializer instanceof DiscussionSerializer) {
  5. $event->attributes['isSticky'] = (bool) $event->model->is_sticky;
  6. $event->attributes['canSticky'] = $event->model->can($event->actor, 'sticky');
  7. }
  8. });

关系

可使用 ApiRelationship 事件来添加新的关系模型。Flarum 的底层 Serializer 类提供了两个方便的方法(hasOnehasMany) ,可构建一个 Tobscure\JsonApi\Relationship 对象,用来处理模型之间的关系。

  1. use Flarum\Api\Serializers\DiscussionSerializer;
  2. use Flarum\Events\ApiRelationship;
  3. $events->listen(ApiRelationship::class, function (ApiRelationship $event) {
  4. if ($event->serializer instanceof DiscussionSerializer && $event->relationship === 'tags') {
  5. return $event->serializer->hasMany('Flarum\Tags\Api\TagSerializer');
  6. }
  7. });

为使这些关系能被对应文档所链接或包含,你必须把关系与适当的行为加以联系 ―― 阅读下面。

行为

Flarum 的 API 端点(endpoint) 在 Flarum\Api\ApiServiceProvider 中定义。通过路由(route),每个端点都与一个对应的行为(Action)类相连接,该类实际上是一个控制器。这个行为类可以接受一个 Flarum\Api\Request 对象,并以 PSR-7 格式响应。

Flarum\Api\Action 命名空间下有大量的抽象行为类,可以扩展这些类来方便地实现数据库操作(译注:原文作 CRUD actions, 请参见维基百科)。其中包括 SerializeResourceActionSerializeCollectionAction 类,这两个类将为你进行设置和在序列化程序中传递数据的所有工作。初学者仅需实现 data 方法并以 Eloquent 模型(译注:此为 Laravel 功能,请参见官方文档) 或集合(Collection)形式返回即可。

更改行为属性

data 方法接受一个请求对象和几个额外的参数:sortincludelinklimitoffset。这些参数使用行为类中的配置来进行处理,扩展程序可以使用 BuildApiAction 事件修改这些配置,以允许添加新的关系、新的可排序字段,诸如此类。

  1. use Flarum\Api\Actions\Discussions;
  2. use Flarum\Events\BuildApiAction;
  3. $events->listen(BuildApiAction::class, function (BuildApiAction $event) {
  4. if ($event->action instanceof Discussions\IndexAction ||
  5. $event->action instanceof Discussions\ShowAction ||
  6. $event->action instanceof Discussions\CreateAction ||
  7. $event->action instanceof Discussions\UpdateAction) {
  8. // Include the tags relationship on discussion resources by default
  9. $event->addInclude('tags');
  10. }
  11. });

添加 API 端点

如果您需要添加一个新的 API 端点,可从任何 Action 基类加以扩展,然后使用 RegisterApiRoutes 事件注册新路由即可:

  1. use Flarum\Events\RegisterApiRoutes;
  2. $events->listen(RegisterApiRoutes::class, function (RegisterApiRoutes $event) {
  3. $event->get(
  4. '/tags', // The endpoint URI
  5. 'api.tags.index', // A unique name for the endpoint
  6. 'Flarum\Tags\Api\IndexAction' // The Action class to handle the request
  7. );
  8. });

译者:@ttnl