>웹 프론트엔드 >JS 튜토리얼 >PHP에서 JSONAPI를 사용하는 방법

PHP에서 JSONAPI를 사용하는 방법

php中世界最好的语言
php中世界最好的语言원래의
2018-04-13 16:03:091944검색

이번에는 PHP에서 JSONAPI를 사용하는 방법을 알려드리겠습니다. PHP에서 JSONAPI를 사용할 때 주의사항은 무엇인가요?

이제 서버 프로그래머의 주요 업무는 더 이상 템플릿을 설정하는 것이 아니라 JSON 기반 API를 작성하는 것입니다. 인터페이스. 불행하게도 모든 사람은 매우 다른 스타일의 인터페이스를 가지고 있어 시스템 통합에 불필요한 통신 비용이 많이 발생합니다. 비슷한 문제가 있는 경우 JSONAPI에 주의를 기울이는 것이 좋습니다. , JSON 기반 API를 구축하기 위한 사양 표준입니다. 간단한 API 인터페이스는 대략 다음과 같습니다.

JSONAPI

간략한 설명: 루트 노드의 데이터는 기본 객체의 콘텐츠를 배치하는 데 사용됩니다. 여기서 유형과 ID는 이는 필수 필드이며 기본 개체의 유형과 ID를 나타내는 데 사용됩니다. 기타 모든 단순 속성은 속성에 배치됩니다. 기본 개체에 일대일, 일대다 및 기타 관련 개체가 있는 경우 관계에 배치되지만 유형 및 ID를 통해서만 가능합니다. 필드에 링크가 배치되고, 연관된 개체의 실제 콘텐츠가 루트 연락처의 included에 배치됩니다.

JSONAPI를 사용하면 데이터 구문 분석 프로세스가 표준화되어 불필요한 통신 비용이 절약됩니다. 그러나 JSONAPI 데이터를 수동으로 구성하는 것은 여전히 ​​매우 번거로운 작업입니다. 다행히 Fractal을 사용하면 구현 프로세스를 상대적으로 자동화할 수 있습니다. 위의 예를 Fractal로 구현하면 다음과 같을 것입니다. 내가 가장 좋아하는 PHP 툴킷을 선택해야 한다면 Fractal이 분명히 목록에 있을 것입니다. Fractal은 사용자가 JSONAPI를 전혀 알 필요가 없도록 구현 세부 정보를 숨깁니다. 계약을 시작할 준비가 되었습니다. 그러나 자신의 프로젝트에서 사용하고 싶다면 Fractal을 직접 사용하는 대신 Fractal에 더 적합한 Fractalistic을 사용해 볼 수 있습니다. 더 쉽게 사용할 수 있도록 캡슐화됨:

<?php
use League\Fractal\Manager;
use League\Fractal\Resource\Collection;
$articles = [
  [
    &#39;id&#39; => 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를 Naked로 작성하는 경우 기본적으로 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 = [
      &#39;type&#39; => 'articles',
      'id' => $this->id,
      'name' => $this->name,
      'author' => $this->whenLoaded('author'),
    ];
    return new JsonApiSerializer($this, $value);
  }
}
?>

전체 프로세스는 Laravel의 아키텍처에 너무 많이 개입하지 않습니다. Laravel은 현재 JSONAPI를 구현한다고 말할 수 있습니다. 가장 좋은 솔루션은 JsonApiSerializer를 연구하는 것입니다. 구현해야 할 코드가 백 줄이 넘지만 이를 달성하기 위해 많은 노력을 기울였습니다. 모든 단계가 힘든 작업이라고 할 수 있습니다.                                         나는 당신이 이 기사를 읽는 방법을 마스터했다고 믿습니다. 더 흥미진진한 내용을 알고 싶다면 PHP 중국어 웹사이트의 다른 관련 기사를 주목해 보세요!

추천 자료:

vue-cli 코드 속도를 높이고 최적화하는 방법

Vue.js 범용 애플리케이션 프레임워크 Nuxt.js 자세한 설명

JS로 라벨 스크롤 전환 구현

위 내용은 PHP에서 JSONAPI를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.