📜 ⬆️ ⬇️

Simple JSON-RPC-like API for PHP

Introduction


What is the JSON-RPC API? It's just one of the types of APIs, but also a clear standard, which may not be the case in this article (yes, it will be a samopis).

After I fiddled with the RESTful API for a while and became very angry with him, because of how simple it is on the outside and can be complicated inside, I went to google to find a replacement.

And I came across an article about the JSON-RPC API, and I was very interested in its concept, so much so that I decided to implement my very simple bike.

JSON-RPC API Concept
')
The main idea of ​​this standard is in a certain object-oriented approach.

Semantically, the query looks like this:

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

And this is only one request, the great beauty of such an API is that they can be beautifully combined, and this gives us the opportunity to use it for batch requests (download something in parts).

That is, a complete request may look like this.

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

Here api_v is the API version, and reqs is an array of queries. Importantly, each query has a method (class.method), parameters, and a name. The name here plays a big role. When you received a response from the server, you can refer to the result of the query by its name. Example: A request with a method of adding a user should be called “user_creating”, but this is up to you;)

Let's start writing


The first thing you need to do is an API class, in my case it does even less than it should. Some processes are separate from me, but this does not change the 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) ); } } 

There are comments in the code, but here is a brief excursion ... We call an unknown function on the API, use the __call magic function for this purpose. That is, by calling the function “Object.method” of the API ($ api -> {“Object.method”}), it automatically splits the string into a pair of object-method and calls it. After that, the results of all queries are added to one array and it is sent back in json format. It's simple.

Classes


It is very important - here the classes are stored in the source folder and this is how the class should look.

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

The class name must match the one requested in the query, the same as the method name. All the rest does not matter. A method can do anything and return anything.

But we also need a control script. This is the same script that will be called upon request.

 <?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(); 

What is going on here? We enable our API depending on the version specified in the request. We decode json requests and go through each of them. We call the API method of the type “object.method” and save its result under the name of this request (it was written above that each request has its own name). After the execution of all requests, we return a json-array of results ... And, in principle, everything.

Little js


Here is a small example of a function in js that will make API requests of this type. Written using jQuery, and I wildly apologize to you for it, but it's so simple to simply show the essence without too much.

 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); } }); } 

There is a simple POST request, and almost nothing is special, except that it is possible to specify only one request, and not an array, and I also save all the answers to the array loaded, this is just not necessary for convenience.

Well, I hope you understand the main idea. I wanted to make a simple and intuitive API - I did. I mostly wanted to show this simple approach to creating a multi-functional API.

See you soon…

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


All Articles