All Projects → tuyakhov → Yii2 Json Api

tuyakhov / Yii2 Json Api

Implementation of JSON API specification for the Yii framework

Projects that are alternatives of or similar to Yii2 Json Api

Json.h
🗄️ single header json parser for C and C++
Stars: ✭ 387 (+178.42%)
Mutual labels:  json-api, json
Flutter login
100% Shared Code Android/iOS Login Example - JSON API
Stars: ✭ 589 (+323.74%)
Mutual labels:  json-api, json
Json Api Php
JSON-API (http://jsonapi.org) responses in PHP.
Stars: ✭ 426 (+206.47%)
Mutual labels:  json-api, json
Tslog
📝 tslog - Expressive TypeScript Logger for Node.js.
Stars: ✭ 321 (+130.94%)
Mutual labels:  json-api, json
Dictfier
Python library to convert/serialize class instances(Objects) both flat and nested into a dictionary data structure. It's very useful in converting Python Objects into JSON format
Stars: ✭ 67 (-51.8%)
Mutual labels:  json-api, json
Pyjfuzz
PyJFuzz - Python JSON Fuzzer
Stars: ✭ 342 (+146.04%)
Mutual labels:  json-api, json
Getty
a netty like asynchronous network I/O library based on tcp/udp/websocket; a bidirectional RPC framework based on JSON/Protobuf; a microservice framework based on zookeeper/etcd
Stars: ✭ 532 (+282.73%)
Mutual labels:  json-api, json
Safrs
SqlAlchemy Flask-Restful Swagger Json:API OpenAPI
Stars: ✭ 255 (+83.45%)
Mutual labels:  json-api, json
Json Api Dart
JSON:API client for Dart/Flutter
Stars: ✭ 53 (-61.87%)
Mutual labels:  json-api, json
Jsonapi parameters
Rails-way to consume JSON:API input
Stars: ✭ 50 (-64.03%)
Mutual labels:  json-api, json
Laravel5 Jsonapi
Laravel 5 JSON API Transformer Package
Stars: ✭ 313 (+125.18%)
Mutual labels:  json-api, json
Athena Express
athena-express makes it easier to execute SQL queries on Amazon Athena by chaining together a bunch of methods in the AWS SDK. This allows you to execute SQL queries AND fetch JSON results in the same synchronous call - well suited for web applications.
Stars: ✭ 111 (-20.14%)
Mutual labels:  json-api, json
Mojojson
A simple and fast JSON parser.
Stars: ✭ 271 (+94.96%)
Mutual labels:  json-api, json
Polr
🚡 A modern, powerful, and robust URL shortener
Stars: ✭ 4,147 (+2883.45%)
Mutual labels:  json-api, json
Spine
A Swift library for working with JSON:API APIs. It supports mapping to custom model classes, fetching, advanced querying, linking and persisting.
Stars: ✭ 267 (+92.09%)
Mutual labels:  json-api, json
Element Api
Create a JSON API/Feed for your elements in Craft.
Stars: ✭ 493 (+254.68%)
Mutual labels:  json-api, json
Iotwifi
Raspberry Pi (arm) wifi configuration container. Configure and control wifi connectivity with a JSON based REST api.
Stars: ✭ 236 (+69.78%)
Mutual labels:  json-api, json
Jsonapi Rails
Rails gem for fast jsonapi-compliant APIs.
Stars: ✭ 242 (+74.1%)
Mutual labels:  json-api, json
Api
姬长信API For Docker 一个基于多种编程语言开源免费不限制提供生活常用,出行服务,开发工具,金融服务,通讯服务和公益大数据的平台.
Stars: ✭ 743 (+434.53%)
Mutual labels:  json-api, json
Rki Covid Api
🦠🇩🇪📈 An API for the spread of covid-19 in Germany. Data from Robert-Koch-Institut.
Stars: ✭ 98 (-29.5%)
Mutual labels:  json-api, json

Implementation of JSON API specification for the Yii framework

Latest Stable Version Scrutinizer Code Quality Build Status Total Downloads

Installation

The preferred way to install this extension is through composer.

Either run

php composer.phar require --prefer-dist tuyakhov/yii2-json-api "*"

or add

"tuyakhov/yii2-json-api": "*"

to the require section of your composer.json file.

Data Serializing and Content Negotiation:

Controller:

class Controller extends \yii\rest\Controller
{
    public $serializer = 'tuyakhov\jsonapi\Serializer';
    
    public function behaviors()
    {
        return ArrayHelper::merge(parent::behaviors(), [
            'contentNegotiator' => [
                'class' => ContentNegotiator::className(),
                'formats' => [
                    'application/vnd.api+json' => Response::FORMAT_JSON,
                ],
            ]
        ]);
    }
}

By default, the value of type is automatically pluralized. You can change this behavior by setting tuyakhov\jsonapi\Serializer::$pluralize property:

class Controller extends \yii\rest\Controller
{
    public $serializer = [
        'class' => 'tuyakhov\jsonapi\Serializer',
        'pluralize' => false,  // makes {"type": "user"}, instead of {"type": "users"}
    ];
}

Defining models:

  1. Let's define User model and declare an articles relation
use tuyakhov\jsonapi\ResourceTrait;
use tuyakhov\jsonapi\ResourceInterface;

class User extends ActiveRecord implements ResourceInterface
{
    use ResourceTrait;
    
    public function getArticles()
    {
        return $this->hasMany(Article::className(), ['author_id' => 'id']);
    }
}
  1. Now we need to define Article model
use tuyakhov\jsonapi\ResourceTrait;
use tuyakhov\jsonapi\ResourceInterface;

class Article extends ActiveRecord implements ResourceInterface
{
    use ResourceTrait;
}
  1. As the result User model will be serialized into the proper json api resource object:
{
  "data": {
    "type": "users",
    "id": "1",
    "attributes": {
      // ... this user's attributes
    },
    "relationships": {
      "articles": {
        // ... this user's articles
      }
    }
  }
}

Controlling JSON API output

The JSON response is generated by the tuyakhov\jsonapi\JsonApiResponseFormatter class which will use the yii\helpers\Json helper internally. This formatter can be configured with different options like for example the $prettyPrint option, which is useful on development for better readable responses, or $encodeOptions to control the output of the JSON encoding.

The formatter can be configured in the yii\web\Response::formatters property of the response application component in the application configuration like the following:

'response' => [
    // ...
    'formatters' => [
        \yii\web\Response::FORMAT_JSON => [
            'class' => 'tuyakhov\jsonapi\JsonApiResponseFormatter',
            'prettyPrint' => YII_DEBUG, // use "pretty" output in debug mode
            'encodeOptions' => JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE,
        ],
    ],
],

Links

Your resource classes may support HATEOAS by implementing the LinksInterface. The interface contains getLinks() method which should return a list of links. Typically, you should return at least the self link representing the URL to the resource object itself. In order to appear the links in relationships getLinks() method should return self link. Based on this link each relationship will generate self and related links. By default it happens by appending a relationship name at the end of the self link of the primary model, you can simply change that behavior by overwriting getRelationshipLinks() method. For example,

class User extends ActiveRecord implements ResourceInterface, LinksInterface
{
    use ResourceTrait;
    
    public function getLinks()
    {
        return [
            Link::REL_SELF => Url::to(['user/view', 'id' => $this->id], true),
        ];
    }
}

As the result:

{
  "data": {
    "type": "users",
    "id": "1",
    // ... this user's attributes
    "relationships": {
      "articles": {
        // ... article's data
        "links": {
            "self": {"href": "http://yourdomain.com/users/1/relationships/articles"},
            "related": {"href": "http://yourdomain.com/users/1/articles"}
        }
      }
    }
    "links": {
        "self": {"href": "http://yourdomain.com/users/1"}
    }
  }
}

Pagination

The page query parameter family is reserved for pagination. This library implements a page-based strategy and allows the usage of query parameters such as page[number] and page[size]
Example: http://yourdomain.com/users?page[number]=3&page[size]=10

Enabling JSON API Input

To let the API accept input data in JSON API format, configure the [[yii\web\Request::$parsers|parsers]] property of the request application component to use the [[tuyakhov\jsonapi\JsonApiParser]] for JSON input

'request' => [
  'parsers' => [
      'application/vnd.api+json' => 'tuyakhov\jsonapi\JsonApiParser',
  ]
]

By default it parses a HTTP request body so that you can populate model attributes with user inputs. For example the request body:

{
  "data": {
    "type": "users",
    "id": "1",
    "attributes": {
        "first-name": "Bob",
        "last-name": "Homster"
    }
  }
}

Will be resolved into the following array:

// var_dump($_POST);
[
    "User" => [
        "first_name" => "Bob", 
        "last_name" => "Homster"
    ]
]

So you can access request body by calling \Yii::$app->request->post() and simply populate the model with input data:

$model = new User();
$model->load(\Yii::$app->request->post());

By default type users will be converted into User (singular, camelCase) which corresponds to the model's formName() method (which you may override). You can override the JsonApiParser::formNameCallback property which refers to a callback that converts 'type' member to form name. Also you could change the default behavior for conversion of member names to variable names ('first-name' converts into 'first_name') by setting JsonApiParser::memberNameCallback property.

Examples

Controller:

class UserController extends \yii\rest\Controller
{
    public $serializer = 'tuyakhov\jsonapi\Serializer';

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return ArrayHelper::merge(parent::behaviors(), [
            'contentNegotiator' => [
                'class' => ContentNegotiator::className(),
                'formats' => [
                    'application/vnd.api+json' => Response::FORMAT_JSON,
                ],
            ]
        ]);
    }
    
    /**
     * @inheritdoc
     */
    public function actions()
    {
        return [
            'create' => [
                'class' => 'tuyakhov\jsonapi\actions\CreateAction',
                'modelClass' => ExampleModel::className()
            ],
            'update' => [
                'class' => 'tuyakhov\jsonapi\actions\UpdateAction',
                'modelClass' => ExampleModel::className()
            ],
            'view' => [
                'class' => 'tuyakhov\jsonapi\actions\ViewAction',
                'modelClass' => ExampleModel::className(),
            ],
            'delete' => [
                'class' => 'tuyakhov\jsonapi\actions\DeleteAction',
                'modelClass' => ExampleModel::className(),
            ],
            'view-related' => [
                'class' => 'tuyakhov\jsonapi\actions\ViewRelatedAction',
                'modelClass' => ExampleModel::className()
            ],
            'update-relationship' => [
                'class' => 'tuyakhov\jsonapi\actions\UpdateRelationshipAction',
                'modelClass' => ExampleModel::className()
            ],
            'delete-relationship' => [
                'class' => 'tuyakhov\jsonapi\actions\DeleteRelationshipAction',
                'modelClass' => ExampleModel::className()
            ],
            'options' => [
                'class' => 'yii\rest\OptionsAction',
            ],
        ];
    }
}

Model:

class User extends ActiveRecord implements LinksInterface, ResourceInterface
{
    use ResourceTrait;
    
    public function getLinks()
    {
        $reflect = new \ReflectionClass($this);
        $controller = Inflector::camel2id($reflect->getShortName());
        return [
            Link::REL_SELF => Url::to(["$controller/view", 'id' => $this->getId()], true)
        ];
    }
}

Configuration file config/main.php:

return [
    // ...
    'components' => [
        'request' => [
            'parsers' => [
                'application/vnd.api+json' => 'tuyakhov\jsonapi\JsonApiParser',
            ]
        ],
        'response' => [
            'format' => \yii\web\Response::FORMAT_JSON,
            'formatters' => [
                \yii\web\Response::FORMAT_JSON => 'tuyakhov\jsonapi\JsonApiResponseFormatter'
            ]
        ],
        'urlManager' => [
            'rules' => [
                [
                    'class' => 'tuyakhov\jsonapi\UrlRule',
                    'controller' => ['user'],
                ],

            ]
        ]
        // ...
    ]
    // ...
]
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].