Содержание


JSON-RPC


Zend\Json\Server - JSON-RPC server, JSON, Server, ЗФ2, Zend Framework 2, ZF2, ру, ru




Zend\Json\Server это реализация сервера JSON-RPC.  Поддерживаются обе спецификации JSON-RPC версии 1 и 2.  Так же обеспечивается PHP реализация спецификаций Service Mapping Description (SMD) -  предоставление сервиса метаданных для обслуживание пользователей.

 

JSON-RPCэто легкая реализация RemoteProcedureCall, использующая JSON для обмена сообщениями.  Поддерживается PHP SoapServer API, что обеспечивает:

 

- Создание экземпляра объекта сервера

- Прикрепляет одну или более функций и/или классов/объектов к объекту сервера.

- Запрос «handle()»

 

Zend\Json\Server использует Zend\Server\Reflectionдля выполнения отражения любого прикрепленного класса или функции, а так же использует полученную информацию для построения SMD и усиленную подпись вызова метода (enforce method call signatures).

 

Важно: каждый прикрепленный метод класса и/или функция должны иметь полноценную PHP документирование. Тоесть как минимум должны быть:

 

- Все параметры и их предполагаемые типы переменных

- Тип возвращаемой переменной

 

Zend\Json\Server прослушивает POST запросы только один раз. Это позволяет легко использовать ту же конечную точку сервера и обрабатывать запросы, а также  предоставлять сервис SMD, как показано в следующем примере.

 

Использование Zend\Json\Server

 

Давайте определим класс, который будет работать с сервером JSON-RPC. Назовем класс «Calculator» и определим методы «add», «subtract», «multiply», «divide». 

/**
 * Calculator - sample class to expose via JSON-RPC
 */
class Calculator
{
    /**
     * Return sum of two variables
     *
     * @param  int $x
     * @param  int $y
     * @return int
     */
    public function add($x, $y)
    {
        return $x + $y;
    }
 
    /**
     * Return difference of two variables
     *
     * @param  int $x
     * @param  int $y
     * @return int
     */
    public function subtract($x, $y)
    {
        return $x - $y;
    }
 
    /**
     * Return product of two variables
     *
     * @param  int $x
     * @param  int $y
     * @return int
     */
    public function multiply($x, $y)
    {
        return $x * $y;
    }
 
    /**
     * Return the division of two variables
     *
     * @param  int $x
     * @param  int $y
     * @return float
     */
    public function divide($x, $y)
    {
        return $x / $y;
    }
}

Запомните, что каждый метод должен иметь DocBlock -  обязательно! В котором описан каждый из параметров и его тип, а так же тип возвращаемого значения. Это очень важно, если Вы используете Zend\Json\Server или другой серверный компонент в Zend Framework.

 

Теперь мы создадим скрипт для обработки запросов:

$server = new Zend\Json\Server\Server();
 
// Indicate what functionality is available:
$server->setClass('Calculator');
 
// Handle the request:
$server->handle();

Однако тут не указан адрес возврата SMD.  Клиент JSON-RPC может сам определить нужный метод. Это осуществляется путем определения метода HTTP запроса, а затем определением некоторых метаданных сервера:

$server = new Zend\Json\Server\Server();
$server->setClass('Calculator');
 
if ('GET' == $_SERVER['REQUEST_METHOD']) {
    // Indicate the URL endpoint, and the JSON-RPC version used:
    $server->setTarget('/json-rpc.php')
           ->setEnvelope(Zend\Json\Server\Smd::ENV_JSONRPC_2);
 
    // Grab the SMD
    $smd = $server->getServiceMap();
 
    // Return the SMD to the client
    header('Content-Type: application/json');
    echo $smd;
    return;
}
 
$server->handle();

Если использовать  сервер JSON-RPC  в Dojo, то Вы должны задать специальный флаг совместимости, что бы они взаимодействовали правильно:

$server = new Zend\Json\Server\Server();
$server->setClass('Calculator');
 
if ('GET' == $_SERVER['REQUEST_METHOD']) {
    $server->setTarget('/json-rpc.php')
           ->setEnvelope(Zend\Json\Server\Smd::ENV_JSONRPC_2);
    $smd = $server->getServiceMap();
 
    // Set Dojo compatibility:
    $smd->setDojoCompatible(true);
 
    header('Content-Type: application/json');
    echo $smd;
    return;
}
 
$server->handle();

Дополнительные детали

 

Про основные возможности мы уже рассказали. Теперь рассмотрим более подробно дополнительные возможности.

 


Zend\Json\Server\Server

 

Zend\Json\Server\Server является главным классом JSON-RPC. Он обрабатывает все запросы и возвращает ответы. В нем присутствуют такие методы:

 

addFunction($function)

Указывает пользовательскую функцию для подключения к серверу.

 

setClass($class)

Указывает класс или лбъект, прикрепляемый к серверу. Все публичные методы будут рассматриваться как методы JSON-RPC

 

fault($fault = null, $code = 404, $data = null)

Создает и возвращает объект Zend\Json\Server\Error

 

handle($request = false)

Принимает запрос JSON-RPC, и при необходимости (не обязательно), передает его на обработку в объект Zend\Json\Server\Request.

 

getFunctions()

Возвращает список всех прикрепленных методов

 

setRequest(Zend\Json\Server\Request $request)

Указывает объект запроса, который использует сервер

 

getRequest()

Возвращает объект запроса, используемый сервером.

 

setResponse(Zend\Json\Server\Response $response)

Установить объект ответа для использования сервером

 

getResponse()

Получить объект ответа, используемый сервером.

 

setAutoEmitResponse($flag)

Указывает, должен ли сервером автоматически выбрасывать ответ и все заголовки. По умолчанию «TRUE».

 

autoEmitResponse()

Определяет, включен ли автоматический выброс ответов.

 

getServiceMap()

Получает описание карты сервисов в виде объекта Zend\Json\Server\Smd  

 

 


Zend\Json\Server\Request

 

Окружениезапросов JSON-RPC  заключеновобъект Zend\Json\Server\Request.  Этот объект позволяет устанавливать необходимые части запроса, включая ID запроса, параметры, версия спецификаций JSON-RPC. Так же есть возможность самозагрузки через JSON или установки настроек, а так же саморендеринг как JSON , используя метод «toJson()».

 

В объекте запросов доступны следующие методы:

 

setOptions(array $options)

Задает настройки объекта. «$options» может содержать ключи, совпадающие с методами «set*»: setParams(), setMethod(), setId(), setVersion().

 

addParam($value, $key = null)

Добавляет параметр к использованию, когда вызывается метод. Параметры могут быть значениями или именами.

 

addParams(array $params)

Добавляет несколько параметров сразу. Прокси для «addParam()».

 

setParams(array $params)

Добавляет все параметры сразу. Перезаписывает существующие параметры.

 

getParam($index)

Получает параметры по имени или позиции.

 

getParams()

Получает сразу все параметры.

 

setMethod($name)

Назначает метод для вызова.

 

getMethod()

Определяет вызванный метод.

 

isMethodError()

Определяет, приведет ли запрос к ошибке.

 

setId($name)

Установливает идентификатор запроса (используется клиентом в соответствии с запросами и ответам).

 

getId()

Возвращает идентификатор запроса.

 

setVersion($version)

Задает версию спецификации JSON-RPC, которой соответствует запрос. Например: «1.0», «2.0»

 

getVersion()

Получает версию спецификации JSON-RPC, которая использовалась для запроса.

 

loadJson($json)

Загружает объект запроса из строки JSON

 

toJson()

Рендерит (показывает) запрос в виде JSON  строки

 

Версию HTTPможно узнать, используя Zend\Json\Server\Request\Http.  Этот класс получает запрос через «php://input», а также предоставляет доступ к необработанным данным JSON  через метод «getRawJson()»

 

Zend\Json\Server\Response

 

Ответ JSON-RPC  заключен в объекте Zend\Json\Server\Response. Этот объект позволяет устанавливать возвращаемое значение запроса, будет или нет ответ ошибкой, идентификатор ответа, версию спецификаций JSON-RPC, карту сервисов.

 

Объект ответа содержит следующие методы:

 

setResult($value)

Устанавливает результат ответа.

 

getResult()

Получает результат ответа.

 

setError(Zend\Json\Server\Error $error)

Устанавливает объект ошибок. Если установлено, то будет использоваться как ответ при сериализации в JSON.

 

getError()

Возвращает объект ошибки, если таковые имеются.

 

isError()

Будет или нет ответ ответом ошибки.

 

setId($name)

Установить идентификатор запроса.

 

getId()

Возвращает идентификатор запроса.

 

setVersion($version)

Устанавливает версию JSON-RPC.

 

getVersion()

Получает версию JSON-RPC.

 

toJson()

Сериализирует ответ в JSON. Если ответ является ошибкой, то сериализирует в объект ошибок.

 

setServiceMap($serviceMap)

Задает карту объектов сервисов ответа.

 

getServiceMap()

Получает карту объектов сервисов .

 

Версия HTTP доступна через Zend\Json\Server\Response\Http . Этот класс будет посылать соответствующие заголовки HTTP, а также сериализировать ответ в JSON .

 

Zend\Json\Server\Error

 

У JSON-RPC имеется специальный формат для представления ошибок. Все ошибки должны, как минимум выводить сообщение и код ошибки. Так же, возможен вывод дополнительной информации, например трассировка.

 

Коды ошибок выводятся по рекомендациям XML-RPC EPI. Zend\Json\Server присваивает код, в зависимости от состояния ошибки. Для исключений приложения используется код «-32000».

 

Zend\Json\Server\Error оперирует следующими методами:

 

setCode($code)

Устанавливает код ошибки. Если код не находится в диапазоне XML-RPC кодов ошибок, используется код «-32000».

 

getCode()

Получить текущий код ошибки.

 

setMessage($message)

Установить сообщение ошибки.

 

getMessage()

Получить текущее сообщение об ошибке.

 

setData($data)

Задать дополнительные данные к ошибке. Например трассировку.

 

getData()

Получить дополнительные данные к ошибке.

 

toArray()

Переместить ошибку в массив. Массив в свою очередь содержит ключи «code», «message», «data».

toJson()

Вывести JSON-RPC  ошибку.

 

Zend\Json\Server\Smd

 

SMD  это ServiceMappingDescription, схема JSON, определяющая как клиент может взаимодействовать с веб - сервисом.  На момент написания этой статьи, спецификации еще не были официально ратифицированы,  однако они уже используются в Dojo Toolkit на равне с другими клиентами JSON-RPC .

 

По своей сути ServiceMappingDescription указывает на метод транспортировки (POST, GET, TCP/IP и т.д.), тип конверта запроса (request envelope type -  если знаете как перевести правильнее отправьте пожалуйста на почту, указанную в низу страницы), обычно основанного на протоколе сервера, URL , карту доступных сервисов.  В случае JSON-RPC  карта сервисов – это список доступных продокументированых методов.

 

Zend\Json\Server\Smd  предоставляет объект, ориентированный на построение карты сервисов. В самом простом случае необходимо передать метаданные с помощью коммутаторов, описывающие сервис  и  указать сервисы (методы и функции).

 

Сервисы, описывающие сами себя как правило экземпляры Zend\Json\Server\Smd\Service. Вы так же можете передать всю необходимую информацию в виде массива в различные коммутаторы сервисов в Zend\Json\Server\Smd , и он инициализирует сервис для Вас. Объекты сервисов содержат такую информацию, как имя сервиса (обычно имя функции или метода), параметры (названия, типы, ..), тип возвращаемого значения. Опционально (не обязательно) каждому сервису можно задать цели (target) и конверты (envelope), однако эти возможности используются исключительно редко.

 

Zend\Json\Server\Server делает все вышеописанное для Вас,используя отражения прикрепленных классов и функций. Вам всего навсего необходимо создать карту сервисов, если хотите добавить пользовательские (дополнительные) возможности  в класс или функцию, если они не реализуют того, что необходимо.

 

Методы, доступные в Zend\Json\Server\Smd:

 

setOptions(array $options)

Создает объект SMD из полученного массива настроек. Все коммутаторы могут быть использованы как ключи массива (методы начинающиеся с «set»).

 

setTransport($transport)

Установить транспортный протокол для сервиса. На данный момент поддерживается только «POST»

 

getTransport()

Получить транспортный протокол сервиса.

 

setEnvelope($envelopeType)

Установить конверт запроса, который используется для доступа к сервису. Поддерживаются такие константы: Zend\Json\Server\Smd::ENV_JSONRPC_1 и Zend\Json\Server\Smd::ENV_JSONRPC_2.

 

getEnvelope()

Получить текущий конверт запроса.

 

setContentType($type)

Установить тип контента запроса. По умолчанию «application/json»

 

getContentType()

Получить текущий тип контента запроса

 

setTarget($target)

Установить URL конечной точки для сервиса.

 

getTarget()

Получить URL конечной точки для сервиса.

 

setId($id)

Как правило, это URL-адрес конечной точки сервиса. То же, что и «target»

 

getId()

Получить ID сервиса

 

setDescription($description)

Установить описание сервиса.

 

getDescription()

Получить описание сервиса.

 

setDojoCompatible($flag)

Флаг, указывающий на совместимость с Dojo Toolkit. Если установить «TRUE», то созданный JSON будет совместим с Dojo JSON-RPC.

 

isDojoCompatible()

Узнать значение флага совместимости с Dojo

 

addService($service)

Добавить сервис в карту. Может быть массивом с необходимой информацией, который передается в конструктор Zend\Json\Server\Smd\Service, или экземпляром этого класса.

 

addServices(array $services)

Добавляет несколько сервисов сразу.

 

setServices(array $services)

Добавляет несколько сервисов сразу. Перезаписывает ранее существующие.

 

getService($name)

Получить сервис по имени.

 

getServices()

Получить все сервисы.

 

removeService($name)

Удалить сервис из карты.

 

toArray()

Передать сервисы в массив.

 

toDojoArray()

Передать сервисы в массив, совместимый с Dojo Toolkit.

 

toJson()

Вывести карту сервисов в представлении JSON

 

 

Методы, доступные в Zend\Json\Server\Smd\Service:

 

 

setOptions(array $options)

Задать состояние объекта.  Любой коммутатор (метод начинающийся с «set») может быть использован как ключ массива.

 

setName($name)

Установить имя сервиса (обычно имя функции или метода)

 

getName()

Получить имя сервиса.

 

setTransport($transport)

Установить транспортный протокол, используемый для сервиса. Допускается только тот, который поддерживается в Zend\Json\Server\Smd. На данный момент это только «POST».

 

getTransport()

Получить транспортный протокол, используемый для сервиса.

 

setTarget($target)

Установить URL конечной точки службы. Обычно совпадает с SMD, к которой прикреплен сервис.

 

getTarget()

Получить URL конечной точки службы.

 

setEnvelope($envelopeType)

Установить конверт сервиса. Допускаются только совместимые с Zend\Json\Server\Smd.

 

getEnvelope()

Получить конверт сервиса.

 

addParam($type, array $options = array(), $order = null)

Добавить параметр к сервису. По умолчанию, необходим только тип параметра. Однако при необходимости у Вас имеется возможность указать порядок и такие параметры:

- name – имя параметра

- optional – является ли параметр обязательным

- default – значение по умолчанию

- description - описание

 

addParams(array $params)

Добавляет несколько параметров сразу. Каждый параметр должен быть ассоциативным массивом, содержащий как минимум ключ «type». При необходимости можно указать тоже, что и для «addParam».

 

setParams(array $params)

Добавляет сразу несколько параметров. Перезаписывает существующие.

 

getParams()

Получить все доступные параметры.

 

setReturn($type)

Задать тип возвращаемого значения сервисом

 

getReturn()

Узнать тип возвращаемого значения сервисом

 

toArray()

Сохранить сервис в виде массива

 

toJson()

Отобразить сервис как JSON представление
Автор статьи: DuB