国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

深入淺析JSONAPI在PHP中的應用

2024-05-06 15:23:16
字體:
供稿:網(wǎng)友

現(xiàn)在服務端程序員的主要工作已經(jīng)不再是套模版,而是編寫基于 JSON 的 API 接口。可惜大家編寫接口的風格往往迥異,這就給系統(tǒng)集成帶來了很多不必要的溝通成本,如果你有類似的困擾,那么不妨關(guān)注一下 JSONAPI ,它是一個基于 JSON 構(gòu)建 API 的規(guī)范標準,一個簡單的 API 接口大致如下所示:

JSONAPI

簡單說明一下:根節(jié)點中的 data 用來放置主對象的內(nèi)容,其中 type 和 id 是必須要有的字段,用來表示主對象的類型和標識,其它簡單的屬性統(tǒng)統(tǒng)放置到 attributes 里,如果主對象存在一對一、一對多等關(guān)聯(lián)對象,那么放置到 relationships 里,不過只是通過 type 和 id 字段放置一個鏈接,關(guān)聯(lián)對象的實際內(nèi)容統(tǒng)統(tǒng)放置在根接點中的 included 里。

有了 JSONAPI,數(shù)據(jù)解析的過程變得規(guī)范起來,節(jié)省了不必要的溝通成本。不過如果要手動構(gòu)建 JSONAPI 數(shù)據(jù)還是很麻煩的,好在通過使用 Fractal 可以讓實現(xiàn)過程相對自動化一些,上面的例子如果用 Fractal 實現(xiàn)大概是這個樣子:

<?phpuse 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 工具包,F(xiàn)ractal 一定榜上有名,它隱藏了實現(xiàn)細節(jié),讓使用者完全不必了解 JSONAPI 協(xié)議即可上手。不過如果你想在自己的項目里使用的話,與直接使用 Fractal 相比,可以試試 Fractalistic ,它對 Fractal 進行了封裝,使其更好用:

<?phpFractal::create()  ->collection($articles)  ->transformWith(new ArticleTransformer())  ->includeAuthor()  ->toArray();?>

如果你是裸寫 PHP 的話,那么 Fractalistic 基本就是最佳選擇了,不過如果你使用了一些全棧框架的話,那么 Fractalistic 可能還不夠優(yōu)雅,因為它無法和框架本身已有的功能更完美的融合,以 Lavaral 為例,它本身內(nèi)置了一個 API Resources 功能,在此基礎上我實現(xiàn)了一個 JsonApiSerializer,可以和框架完美融合,代碼如下:

<?phpnamespace 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;  }}?>            
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 琼海市| 泰来县| 新兴县| 通山县| 云安县| 东台市| 扬中市| 定边县| 嘉禾县| 日土县| 扎兰屯市| 天祝| 皋兰县| 翁源县| 阿巴嘎旗| 东辽县| 杭锦旗| 辉南县| 土默特左旗| 余姚市| 敦煌市| 遂溪县| 托克托县| 德格县| 福建省| 内乡县| 诸暨市| 中牟县| 富顺县| 宜川县| 吉木萨尔县| 长寿区| 花莲县| 乌拉特后旗| 惠水县| 如皋市| 巴林左旗| 阳信县| 夹江县| 长宁区| 仁寿县|