<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                現在服務端程序員的主要工作已經不再是套模版,而是編寫基于 JSON 的 API 接口。可惜大家編寫接口的風格往往迥異,這就給系統集成帶來了很多不必要的溝通成本,如果你有類似的困擾,那么不妨關注一下 JSONAPI,它是一個基于 JSON 構建 API 的規范標準,一個簡單的 API 接口大致如下所示: ![](https://box.kancloud.cn/eb9bd477ea2ca15120c880b439fab53b_713x696.jpeg) 簡單說明一下:根節點中的 data 用來放置主對象的內容,其中 type 和 id 是必須要有的字段,用來表示主對象的類型和標識,其它簡單的屬性統統放置到 attributes 里,如果主對象存在一對一、一對多等關聯對象,那么放置到 relationships 里,不過只是通過 type 和 id 字段放置一個鏈接,關聯對象的實際內容統統放置在根接點中的 included 里。 有了 JSONAPI,數據解析的過程變得規范起來,節省了不必要的溝通成本。不過如果要手動構建 JSONAPI 數據還是很麻煩的,好在通過使用 Fractal 可以讓實現過程相對自動化一些,上面的例子如果用 Fractal 實現大概是這個樣子: ~~~ <?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 工具包,Fractal 一定榜上有名,它隱藏了實現細節,讓使用者完全不必了解 JSONAPI 協議即可上手。不過如果你想在自己的項目里使用的話,與直接使用 Fractal 相比,可以試試 Fractalistic,它對 Fractal 進行了封裝,使其更好用: ~~~ <?php Fractal::create() ->collection($articles) ->transformWith(new ArticleTransformer()) ->includeAuthor() ->toArray(); ?> ~~~ 如果你是裸寫 PHP 的話,那么 Fractalistic 基本就是最佳選擇了,不過如果你使用了一些全棧框架的話,那么 Fractalistic 可能還不夠優雅,因為它無法和框架本身已有的功能更完美的融合,以 Lavaral 為例,它本身內置了一個 API Resources 功能,在此基礎上我實現了一個 JsonApiSerializer,可以和框架完美融合,代碼如下: ~~~ <?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 $value; protected $isRoot; protected $data = []; protected static $included = []; public function __construct($value) { static $count = 0; $this->value = $value; $this->isRoot = (++$count == 1); } public function jsonSerialize() { foreach ($this->value as $key => $value) { if ($value instanceof Resource) { $this->serializeResource($key, $value); } else { $this->serializeNonResource($key, $value); } } if (!$this->isRoot) { return $this->data; } $result = [ 'data' => $this->data, ]; if (static::$included) { $result['included'] = static::$included; } 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; } } } ?> ~~~ 對應的 Resource 基本還和以前一樣,只是返回值改了一下: ~~~ <?php namespace App\Http\Resources; 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' => new AuthorResource($this->whenLoaded('author')), ]; return new JsonApiSerializer($value); } } ?> 對應的 Controller 也和原來差不多: <?php namespace App\Http\Controllers; use App\Article; use App\Http\Resources\ArticleResource; class ArticleController extends Controller { protected $article; public function __construct(Article $article) { $this->article = $article; } public function show($id) { $article = $this->article->with('author')->findOrFail($id); $resource = new ArticleResource($article); // $resource->additional(['meta' => [...]]); return $resource; } } ?> ~~~ 整個過程沒有對 Laravel 的架構進行太大的侵入,可以說是目前 Laravel 實現 JSONAPI 的最優解決方案了,有興趣的可以研究一下 JsonApiSerializer 的實現,雖然只有一百多行代碼,但是我卻費了好大的力氣才實現,可以說是行行皆辛苦啊。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看