Maison  >  Article  >  interface Web  >  Comment utiliser JSONAPI en PHP

Comment utiliser JSONAPI en PHP

php中世界最好的语言
php中世界最好的语言original
2018-04-13 16:03:091889parcourir

Cette fois, je vais vous expliquer comment utiliser JSONAPI en PHP. Quelles sont les précautions lors de l'utilisation de JSONAPI en PHP Voici des cas pratiques, jetons un coup d'œil.

Désormais, la tâche principale des programmeurs de serveur n'est plus de définir des modèles, mais d'écrire des API basées sur JSON. interface. Malheureusement, tout le monde a souvent des styles d'interface d'écriture très différents, ce qui entraîne de nombreux coûts de communication inutiles pour l'intégration du système. Si vous rencontrez des problèmes similaires, autant faire attention à JSONAPI. , il s'agit d'une norme de spécification pour la création d'API basées sur JSON. Une interface API simple ressemble à peu près à ceci :

. JSONAPI

Une brève explication : les données du nœud racine sont utilisées pour placer le contenu de l'objet principal, où type et id Il s'agit d'un champ obligatoire utilisé pour représenter le type et l'identité de l'objet principal. Tous les autres attributs simples sont placés dans les attributs. Dans, si l'objet principal a un à un, un à plusieurs et d'autres objets associés, alors il est placé dans des relations, mais uniquement via le type et l'identifiant. Un lien est placé dans le champ, et le contenu réel de l'objet associé est placé dans included dans le contact racine.

Avec JSONAPI, le processus d'analyse des données devient standardisé, ce qui permet d'économiser des coûts de communication inutiles. Cependant, il est toujours très difficile de construire manuellement des données JSONAPI. Heureusement, en utilisant Fractal, le processus d'implémentation peut être relativement automatisé. Si l'exemple ci-dessus est implémenté à l'aide de Fractal, il ressemblera probablement à ceci :

<?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();
?>
<.> Si je devais choisir ma boîte à outils PHP préférée, Fractal serait certainement sur la liste. Il masque les détails d'implémentation afin que les utilisateurs n'aient pas du tout besoin de connaître JSONAPI. L’accord est prêt à démarrer. Mais si vous souhaitez l'utiliser dans votre propre projet, au lieu d'utiliser Fractal directement, vous pouvez essayer Fractalistic, qui est meilleur pour Fractal. Encapsulé pour faciliter son utilisation :

<?php
Fractal::create()
  ->collection($articles)
  ->transformWith(new ArticleTransformer())
  ->includeAuthor()
  ->toArray();
?>
Si vous écrivez du PHP nu, alors Fractalistic est fondamentalement le meilleur choix, mais si vous utilisez un framework full-stack, alors Fractalistic n'est peut-être pas assez élégant car il ne peut pas être mieux intégré aux fonctions existantes du framework lui-même, en prenant Lavalal comme exemple, il dispose d'une API intégrée. Fonction ressources, sur cette base j'ai implémenté un JsonApiSerializer, qui s'intègre parfaitement au framework. Le code est le suivant :

<?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;
  }
}
?>
. La ressource correspondante est fondamentalement la même qu'avant, sauf que la valeur de retour a été modifiée :

<?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);
  }
}
?>
Le contrôleur correspondant est presque le même qu'avant, sauf qu'un attribut isRoot est ajouté pour identifier la racine :

<?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->isRoot = true;
    return $resource;
  }
}
?>
L'ensemble du processus n'empiète pas trop sur l'architecture de Laravel. On peut dire que Laravel actuellement. implémente JSONAPI La meilleure solution Si vous êtes intéressé, vous pouvez étudier JsonApiSerializer. Bien qu'il n'y ait que plus d'une centaine de lignes de code à implémenter, j'ai déployé beaucoup d'efforts pour y parvenir. On peut dire que chaque étape du processus est un travail difficile.                                        

Je pense que vous maîtrisez la méthode de lecture de cet article. Pour plus de passionnant, veuillez prêter attention aux autres articles connexes sur le site Web PHP chinois !

Lecture recommandée :

Comment accélérer et optimiser le code vue-cli


Cadre d'application universel Vue.js Nuxt .js Utiliser une explication détaillée


JS pour implémenter la commutation de défilement d'étiquettes


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn