この記事では主に、PHP での JSONAPI のアプリケーションの詳細な分析を紹介します。必要な方は参考にしてください。
現在、サーバー プログラマーの主な仕事は、テンプレートを設定することではなく、JSON ベースの API インターフェイスを作成することです。 。残念ながら、インターフェイスの記述スタイルは人によって大きく異なることが多く、これによりシステム統合に多くの不必要な通信コストが発生します。同じような問題がある場合は、JSON に基づいて API を構築するための標準である JSONAPI に注目することをお勧めします。簡単な API インターフェイスはおおよそ次のとおりです:
JSONAPI
簡単な説明: ルート ノードのデータは、メイン オブジェクトのコンテンツを配置するために使用されます。ここで、type と id は必須フィールドであり、タイプと ID を表すために使用されます。メイン オブジェクトの識別、他のすべての単純な属性は属性に配置されます。メイン オブジェクトに 1 対 1、1 対多、およびその他の関連オブジェクトがある場合、それらはリレーションシップに配置されます。ただし、リンクのみが配置されます。 type フィールドと id フィールドを介して、関連付けられたオブジェクトの実際のコンテンツがルート ノードに組み込まれます。
JSONAPI を使用すると、データ解析プロセスが標準化され、不必要な通信コストが節約されます。ただし、JSONAPI データを手動で構築するのは依然として非常に面倒です。幸いなことに、Fractal を使用すると、実装プロセスは比較的自動化できます。おそらく、上記の例を Fractal で実装すると、次のようになります。私のお気に入りの PHP ツールキットを選択するには、Fractal がリストに含まれている必要があります。Fractal は実装の詳細を非表示にするため、ユーザーは JSONAPI プロトコルをまったく知らなくても使い始めることができます。ただし、Fractal を直接使用する代わりに、Fractalistic を自分のプロジェクトで使用したい場合は、Fractal をカプセル化して使いやすくする Fractalistic を試すことができます:
<?php use League\Fractal\Manager; use League\Fractal\Resource\Collection; $articles = [ [ 'id' => 1, 'title' => 'JSON API paints my bikeshed!', 'body' => 'The shortest article. Ever.', 'author' => [ 'id' => 42, 'name' => 'John', ], ], ]; $manager = new Manager(); $resource = new Collection($articles, new ArticleTransformer()); $manager->parseIncludes('author'); $manager->createData($resource)->toArray(); ?>
PHP を裸で書いている場合は、Fractalistic が基本的に最適ですただし、フルスタック フレームワークを使用している場合、Fractalistic はフレームワーク自体の既存の機能とより完全に統合できないため、十分にエレガントではない可能性があります。例として Lavaral には API リソース関数が組み込まれています。これに基づいて、フレームワークと完全に統合できる JsonApiSerializer を実装しました。コードは次のとおりです。
<?php Fractal::create() ->collection($articles) ->transformWith(new ArticleTransformer()) ->includeAuthor() ->toArray(); ?>
の対応するリソースは、戻り値が変更されたことを除いて、基本的に前と同じです。
<?php namespace App\Http\Serializers; use Illuminate\Http\Resources\MissingValue; use Illuminate\Http\Resources\Json\Resource; use Illuminate\Http\Resources\Json\ResourceCollection; use Illuminate\Pagination\AbstractPaginator; class JsonApiSerializer implements \JsonSerializable { protected $resource; protected $resourceValue; protected $data = []; protected static $included = []; public function __construct($resource, $resourceValue) { $this->resource = $resource; $this->resourceValue = $resourceValue; } public function jsonSerialize() { foreach ($this->resourceValue as $key => $value) { if ($value instanceof Resource) { $this->serializeResource($key, $value); } else { $this->serializeNonResource($key, $value); } } if (!$this->isRootResource()) { return $this->data; } $result = [ 'data' => $this->data, ]; if (static::$included) { $result['included'] = static::$included; } if (!$this->resource->resource instanceof AbstractPaginator) { return $result; } $paginated = $this->resource->resource->toArray(); $result['links'] = $this->links($paginated); $result['meta'] = $this->meta($paginated); return $result; } protected function serializeResource($key, $value, $type = null) { if ($type === null) { $type = $key; } if ($value->resource instanceof MissingValue) { return; } if ($value instanceof ResourceCollection) { foreach ($value as $k => $v) { $this->serializeResource($k, $v, $type); } } elseif (is_string($type)) { $included = $value->resolve(); $data = [ 'type' => $included['type'], 'id' => $included['id'], ]; if (is_int($key)) { $this->data['relationships'][$type]['data'][] = $data; } else { $this->data['relationships'][$type]['data'] = $data; } static::$included[] = $included; } else { $this->data[] = $value->resolve(); } } protected function serializeNonResource($key, $value) { switch ($key) { case 'id': $value = (string)$value; case 'type': case 'links': $this->data[$key] = $value; break; default: $this->data['attributes'][$key] = $value; } } protected function links($paginated) { return [ 'first' => $paginated['first_page_url'] ?? null, 'last' => $paginated['last_page_url'] ?? null, 'prev' => $paginated['prev_page_url'] ?? null, 'next' => $paginated['next_page_url'] ?? null, ]; } protected function meta($paginated) { return [ 'current_page' => $paginated['current_page'] ?? null, 'from' => $paginated['from'] ?? null, 'last_page' => $paginated['last_page'] ?? null, 'per_page' => $paginated['per_page'] ?? null, 'to' => $paginated['to'] ?? null, 'total' => $paginated['total'] ?? null, ]; } protected function isRootResource() { return isset($this->resource->isRoot) && $this->resource->isRoot; } } ?>
のコントローラーも、ルートを識別するための isRoot 属性が追加されている点を除いて、ほぼ同じであることがわかります。
<?php namespace App\Http\Resources; use App\Article; use Illuminate\Http\Resources\Json\Resource; use App\Http\Serializers\JsonApiSerializer; class ArticleResource extends Resource { public function toArray($request) { $value = [ 'type' => 'articles', 'id' => $this->id, 'name' => $this->name, 'author' => $this->whenLoaded('author'), ]; return new JsonApiSerializer($this, $value); } } ?>
プロセス全体は、Laravel のアーキテクチャにあまり介入しません。現時点で Laravel が JSONAPI を実装するのに最適なソリューションであると言われています。興味のある方は、JsonApiSerializer の実装を見てみましょう。コードは 100 行強しかありません。それを実現するための努力は、どの段階も大変な作業であると言えます。
上記は私があなたのためにまとめたものです。
関連記事:
Vueで背景画像を設定するvue+lessを使った簡単なスキン変更機能の実装方法angular、react、vueを使って同じインタビュー質問コンポーネントを実装する方法活用方法 jQueryは一番下までスクロールする際の自動読み込みを実装しますAngular2.0でモーダルダイアログボックスを実装する方法JSでモーションバッファリング効果を実装する方法(詳細なチュートリアル)以上がPHP で JSONAPI を使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。