定制 ride/lib-http-jsonapi 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

ride/lib-http-jsonapi

最新稳定版本:1.2.0

Composer 安装命令:

composer require ride/lib-http-jsonapi

包简介

JSON API library of the Ride framework

README 文档

README

JSON API library of the PHP Ride framework.

Check http://jsonapi.org for a full reference of the standard.

What's In This Library?

JsonApi

The JsonApi class is the starting point for your implementation. It's the container for the resource adapters and a factory for other instances of the library. You should register your resource adapters before doing anything else with the API.

JsonApiResourceAdapter

The only interface in this library is the JsonApiResourceAdapter interface. The implementations of this interface converts data entries from your data model into JSON API resources. You need an instance of this interface for each data type you want to expose with your API.

JsonApiResource

The JsonApiResource class is the data container for a resource, eg a data entry from your data model. The instances of this class are set to the responding document of an API request, either as a single instance, or in an array for a collection of resources.

JsonApiDocument

The JsonApiDocument is the container of the responding document of an API request. You can set your resource(s) or error(s) as content to this document. The content of your document can even be strictly meta.

The JsonApiDocument instance holds your JsonApi instance and a JsonApiQuery instance. It's passed on to the resource adapter when converting entries into resources. Using the JsonApi instance and the JsonApiQuery, the JsonApiResourceAdapter can create the JsonApiResource instance as the client requested.

JsonApiQuery

Create a JsonApiQuery instance from your incoming query parameters. The JsonApiQuery instance will give you easy access to the requested resources and pagination, sort and filter values.

Code Sample

Process The Incoming Request

A controller for your API could be something like this:

<?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;
    }

}

Implement A Resource Adapter

The resource adapter for the blog posts in the previous example could be something like this:

<?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;
    }
    
}

Implementations

For more examples, you can check the following implementations of this library:

Installation

You can use Composer to install this library.

composer require ride/lib-http-jsonapi

统计信息

  • 总下载量: 2.4k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 6
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 11
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2015-08-05