ride / lib-http-jsonapi
Ride框架的JSON API库
1.2.0
2024-06-26 08:52 UTC
README
PHP Ride框架的JSON API库。
请访问https://jsonapi.fullstack.org.cn 获取标准的完整参考。
本库包含哪些内容?
JsonApi
JsonApi 类是您实现的开端。它是资源适配器的容器,也是库中其他实例的工厂。您应该在执行任何其他API操作之前注册您的资源适配器。
JsonApiResourceAdapter
本库中唯一的接口是 JsonApiResourceAdapter 接口。该接口的实现将数据模型中的数据条目转换为JSON API资源。您需要为每个要通过API公开的数据类型提供一个此接口的实例。
JsonApiResource
JsonApiResource 类是资源的数据容器,例如来自您的数据模型的数据条目。该类的实例设置为API请求的响应文档,可以是单个实例,也可以是资源集合的数组。
JsonApiDocument
JsonApiDocument 是API请求响应文档的容器。您可以将资源或错误内容设置到该文档中。文档的内容甚至可以是严格意义上的元数据。
JsonApiDocument 实例持有您的 JsonApi 实例和一个 JsonApiQuery 实例。在将条目转换为资源时,它会被传递给资源适配器。使用 JsonApi 实例和 JsonApiQuery,JsonApiResourceAdapter 可以根据客户端请求创建 JsonApiResource 实例。
JsonApiQuery
从您的传入查询参数中创建一个 JsonApiQuery 实例。该 JsonApiQuery 实例将为您提供对请求资源、分页、排序和筛选值的便捷访问。
代码示例
处理传入请求
您的API控制器可能如下所示
<?php include ride\library\http\jsonapi\JsonApiQuery; include ride\library\http\jsonapi\JsonApi; /** * Controller for the blog post API */ class BlogPostController { /** * Constructs a new controller * @param ride\library\http\jsonapi\JsonApi $api */ public function __construct(JsonApi $api) { $this->api = $api; } /** * Action to fetch a collection of blog posts */ public function indexAction() { $query = $this->api->createQuery($_GET); $document = $this->api->createDocument($query); $blogPosts = $this->getBlogPosts($query, $total); $document->setResourceCollection(BlogPostResourceAdapter::TYPE, $blogPosts); $document->setMeta('total', $total); http_status_code($document->getStatusCode()); if ($document->hasContent()) { header('Content-Type: ' . JsonApi::CONTENT_TYPE); echo json_encode($document); } } /** * Gets the blog posts from the data source * @param ride\library\http\jsonapi\JsonApiQuery $query Requested query * @param integer $total Total results before pagination * @return array */ private function getBlogPosts(JsonApiQuery $query, &$total) { // static data as an example $blogPosts = array( 1 => array( 'id' => 1, 'title' => 'Lorum Ipsum', 'author' => array( 'id' => 1, 'name' => 'John Doe', ), 'tags' => array( 1 => array( 'id' => 1, 'name' => 'lorum', ), 2 => array( 'id' => 2, 'name' => 'ipsum', ), ), ), // ... ); // count the total $total = count($blogPosts); // apply pagination $blogPosts = array_slice($blogPosts, $query->getOffset(), $query->getLimit(10, 100)); // return the result return $blogPosts; } }
实现资源适配器
上一个示例中博客文章的资源适配器可能如下所示
<?php include ride\library\http\jsonapi\JsonApiDocument; include ride\library\http\jsonapi\JsonApiResourceAdapter; /** * Resource adapter for a blog post */ class BlogPostResourceAdapter implements JsonApiResourceAdapter { /** * Type of this resource * @var string */ const TYPE = 'blog-posts'; /** * Gets a resource instance for the provided model data * @param mixed $data Data to adapt * @param ride\library\http\jsonapi\JsonApiDocument $document Requested document * @param string $relationshipPath dot-separated list of relationship names * @return ride\library\http\jsonapi\JsonApiResource */ public function getResource($data, JsonApiDocument $document, $relationshipPath = null) { $api = $document->getApi(); $query = $document->getQuery(); // create the resource for the entry $resource = $api->createResource(self::TYPE, $data['id']); $resource->setLink('self', 'http://your-resource-url'); // check for an attribute and set when requested if ($query->isFieldRequested(self::TYPE, 'title')) { $resource->setAttribute('title', $data['title']); } // check for a relationship and set when requested if ($query->isFieldRequested(self::TYPE, 'author') && $query->isIncluded($relationshipPath)) { // append the field to the relationship path $fieldRelationshipPath = ($relationshipPath ? $relationshipPath . '.' : '') . 'author'; // retrieve the resource $peopleResourceAdapter = $api->getResourceAdapter('people'); $author = $peopleResourceAdapter->getResource($data['author'], $document, $fieldRelationshipPath); // create the relationship $relationship = $api->createRelationship(); $relationship->setResource($author); $relationship->setLink('self', 'http://your-relationship-url'); $relationship->setLink('related', 'http://your-related-url'); // add the relationship to your resource $resource->setRelationship('author', $relationship); } // set a relationship collection value if ($query->isFieldRequested(self::TYPE, 'tags') && $query->isIncluded($relationshipPath)) { $fieldRelationshipPath = ($relationshipPath ? $relationshipPath . '.' : '') . 'tags'; $tagResourceAdapter = $api->getResourceAdapter('tags'); $tags = $data['tags']; foreach ($tags as $tag) { $tags[$tagIndex] = $tagResourceAdapter->getResource($tag, $document); } $relationship = $api->createRelationship(); $relationship->setResourceCollection($tags); $relationship->setLink('self', 'http://your-relationship-url'); $relationship->setLink('related', 'http://your-related-url'); $resource->setRelationship('tags', $relationship); } // return the resource return $resource; } }
实现
对于更多示例,您可以检查以下库的实现
安装
您可以使用 Composer 来安装此库。
composer require ride/lib-http-jsonapi