API simple de type JSON-RPC en PHP

Entrée


Qu'est-ce que l'API JSON-RPC? Ce n'est qu'un des types d'API, mais aussi un standard clair, qui peut ne pas être dans cet article (oui, il y aura des samopis).

Après avoir manipulé l'API RESTful pendant un certain temps et me suis énervé contre elle, pour sa simplicité à l'extérieur et son pliage à l'intérieur, je suis allé sur Google à la recherche d'un remplaçant.

Et je suis tombé sur un article sur l'API JSON-RPC, et j'étais très intéressé par son concept, à tel point que j'ai décidé d'implémenter mon vélo le plus simplement possible.

Concept d'API JSON-RPC

L'idée principale de cette norme réside dans une certaine approche orientée objet.

Sémantiquement, la requête ressemble à ceci:

{ "api version": 0.1, "method": "object.method", "params": { "user id": 1234 } } 

Et ce n'est qu'une demande, le grand charme d'une telle API est qu'elles peuvent être magnifiquement combinées, ce qui nous donne la possibilité de l'utiliser pour des demandes par lots (charger quelque chose en plusieurs parties).

Autrement dit, une demande complète peut ressembler à ceci.

 { "api_v": "0.1", "reqs": [ { "name": "my_important_request", "method": "user.kick_out", "params": { "id": "1234", "when": "now", ... } }, ... ] } 

Ici, api_v est la version de l'API et reqs est un tableau de requêtes. Ce qui est important, chaque requête a une méthode (class.method), des paramètres et un nom. Le nom joue ici un grand rôle. Lorsque vous recevez une réponse du serveur, vous pouvez faire référence au résultat de la requête par son nom. Exemple: Une demande avec une méthode d'ajout d'un utilisateur doit être appelée "user_creating", mais cela dépend de vous;)

Commençons à écrire


La première chose à faire est la classe API, dans mon cas, elle fait encore moins que ce qu'elle devrait. Certains processus sont séparés de moi, mais cela ne change pas l'essence.

 <?php // @package 'api_0.1.php' // API  0.1 class API { private $last_resp; //    private $resp = []; //   public function __call( $method, $params ) { //  ,     $object = substr($method, 0, strpos($method, '.')); $method_name = substr($method, strpos($method, '.')+1); //   include_once __DIR__.'/source/'.$object.'.methods.php'; //      $resp = $object::$method_name($params); if(!empty($resp)) $this->last_resp = $resp; else $this->last_resp = null; } //          - pulbic function add_resp($req_name){ if($this->last_resp === null) return false; $req = $this->last_resp; $this->resp[$req_name] = $req; } //  ,    public function response(){ exit ( json_encode($this->resp) ); } } 

Il y a des commentaires dans le code, mais voici une brève digression ... Nous appelons l'API une fonction inconnue, utilisez la fonction magique __call à ces fins. Autrement dit, en appelant la fonction "Object.method" de l'API ($ api -> {"Object.method"}), il divise automatiquement la chaîne en une paire de méthode objet et l'appelle. Après cela, les résultats de toutes les requêtes sont ajoutés à un tableau et ils sont renvoyés au format json. Tout est simple.

Cours


C'est très important - ici, les classes sont stockées dans le dossier source et voici à quoi devrait ressembler la classe

 <?php class object{ function method($params){ /* ... */ } } 

Le nom de la classe doit correspondre à ce qui est demandé dans la demande, de même avec le nom de la méthode. Tout le reste n'a pas d'importance. Une méthode peut tout faire et retourner n'importe quoi.

Mais nous avons également besoin d'un script de contrôle. Il s'agit du même script qui sera appelé sur demande.

 <?php // @package api.php header('Content-Type: application/json'); //     json $api_v = $_POST['api_v']; // $path = __DIR__.'/APIs/api_'.$api_v.'.php'; //       ,    if(!file_exists($path)) exit; //       include_once __DIR__.'/APIs/api_'.$api_v.'.php'; //  API $api = new API(); $reqs = $_POST['reqs']; $reqs = @json_decode($reqs, true); //  json  php  () //    ,          API foreach ($reqs as $req) { $method = $req['method']; $params = $req['params']; $req_name = $req['name']; $api->$method($params); $api->add_resp($req_name); } //    $api->response(); 

Que se passe-t-il ici? Nous activons notre API en fonction de la version spécifiée dans la demande. Nous décodons les requêtes json et passons en revue chacune d'elles. Nous appelons la méthode API de type "object.method" et enregistrons son résultat sous le nom de cette requête (il a été écrit ci-dessus que chaque requête a son propre nom). Après avoir exécuté toutes les requêtes, nous renvoyons un tableau json de résultats ... Et, en gros, c'est tout.

Little js


Voici un petit exemple d'une fonction en js qui fera des requêtes API de ce type. Il est écrit en utilisant jQuery, et je m'en excuse énormément pour cela, mais c'est tellement plus simple de montrer l'essence sans trop.

 function api_call(reqs, callback){ //  (  ,    ,     )   json var json = JSON.stringify( (Array.isArray(reqs) ? reqs : [reqs]) ); //  POST  $.post({ url: '/api/api.php', //    api.php dataType: 'json', //   json,     data: ({ api_v: '0.1', reqs: json }), //   API   ( json ) success: function(res){ //         window,      .     for(var key in res){ window.loaded[key] = res[key]; } //      callback(res); } }); } 

Voici une simple demande POST, et il n'y a presque rien de spécial, sauf qu'il est possible de spécifier une seule demande, pas un tableau, et j'enregistre également toutes les réponses dans un tableau de téléchargements, c'est juste que, pour plus de commodité, ce n'est pas du tout nécessaire.

Eh bien, j'espère que l'idée principale est claire pour vous. Je voulais créer une API simple et intuitive - je l'ai fait. Pour la plupart, je voulais montrer cette approche simple pour créer une API multifonctionnelle.

A bientôt ...

Source: https://habr.com/ru/post/fr446348/


All Articles