Zend_Json_Server - servidor JSON-RPC
Zend_Json_Server es una implementación del
servidor JSON-RPC Soporta tanto la versión 1 de la especificación
JSON-RPC
así como la especificación de la versión 2 ; además, provee una implementación de
PHP de la especificación del Service Mapping Description (SMD) para prestar un servicio
de metadatos a consumidores del servicio.
JSON-RPC es un protocolo liviano de Remote Procedure Call que utiliza
JSON para envolver sus mensajes. Esta implementación JSON-RPC sigue la
API
PHP de SoapServer . Esto significa que, en una situación típica,
simplemente:
Instancia el objeto servidor
Agrega una o más funciones y/o clases/objetos al objeto
servidor para
handle() -- maneja -- el requerimiento
Zend_Json_Server utiliza para realizar reflexión sobre
cualquiera de las clases o funciones agregadas, y utiliza esa
información para construir tanto la SMD y hacer cumplir el método de
llamado de firmas. Como tal, es imperativo que cualquier de las
funciones agregadas y/o los métodos de clase tengan mínimamente una
plena documentación de PHP docblocks:
Todos los parámetros y sus tipos de variables esperados
El tipo de variable del valor de retorno
Zend_Json_Server escucha por solicitudes POST
únicamente en este momento; afortunadamente, la mayoría de las
implementaciones del cliente JSON-RPC en los medios en el momento de
escribir esto, sólo requieren a POST como es. Esto hace que sea fácil de
utilizar el mismo punto final del servidor para manejar a ambas
peticiones así como para entregar el servicio SMD, como se muestra en el
siguiente ejemplo.
Uso de Zend_Json_Server
Primero, definir una clase que queramos exponer vía servidor
JSON-RPC. Vamos a la clase 'Calculator', y definir los métodos para
'add', 'subtract', 'multiply', y 'divide':
Nótese que cada método tiene un docblock con entradas indicando
cada parámetro y su tipo, así como una entrada para el valor de
retorno. Esto es absolutamente crítico cuando
se usa Zend_Json_Server -- o cualquier otro
componente del servidor en Zend Framework, por esa cuestión.
Ahora, crearemos un script para manejar las peticiones:
setClass('Calculator');
// Manejar el requerimiento:
$server->handle();
]]>
Sin embargo, esto no soluciona el problema de devolución de un
SMD para que el cliente JSON-RPC pueda autodescubrir los métodos.
Esto puede lograrse determinando el método del requerimiento
HTTP , y luego especificando algún servidor
de metadatos:
setClass('Calculator');
if ('GET' == $_SERVER['REQUEST_METHOD']) {
// Indica el punto final de la URL, y la versión en uso de JSON-RPC:
$server->setTarget('/json-rpc.php')
->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2);
// Capturar el SMD
$smd = $server->getServiceMap();
// Devolver el SMD al cliente
header('Content-Type: application/json');
echo $smd;
return;
}
$server->handle();
]]>
Si utiliza el servidor JSON-RPC con Dojo toolkit, también
necesitará establecer un flag de compatibilidad especial para
garantizar que los dos interoperen correctamente:
setClass('Calculator');
if ('GET' == $_SERVER['REQUEST_METHOD']) {
$server->setTarget('/json-rpc.php')
->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2);
$smd = $server->getServiceMap();
// Establecer la compatibilidad con Dojo:
$smd->setDojoCompatible(true);
header('Content-Type: application/json');
echo $smd;
return;
}
$server->handle();
]]>
Detalles Avanzados
Aunque la mayor funcionalidad de
Zend_Json_Server se puntualiza en , hay más funcionalidad
avanzada disponible.
Zend_Json_Server
Zend_Json_Server es la clase núcleo en la
propuesta JSON-RPC; que maneja todas las peticiones y como
respuesta devuelve un conjunto de datos. Tiene los siguientes
métodos:
addFunction($function) :
Especifica la función de espacio del usuario para
agregar al servidor.
setClass($class) : Especifica
una clase u objeto para agregar al servidor; todos los
métodos públicos de ese item serán expuestos como
métodos JSON-RPC.
fault($fault = null, $code = 404, $data =
null) : Crea y devuelve un objeto
Zend_Json_Server_Error .
handle($request = false) :
Maneja una solicitud JSON-RPC; opcionalmente, pasa un
objeto Zend_Json_Server_Request a
utlizar (crea uno por defecto).
getFunctions() : Devuelve una
lista de todos los métodos agregados.
setRequest(Zend_Json_Server_Request
$request) : Especifica un objeto
solicitud para el servidor a utilizar.
getRequest() : Recupera el
objeto solicitud usado por el servidor.
setResponse(Zend_Json_Server_Response
$response) : Establece el objeto
respuesta para el servidor a utilizar.
getResponse() : Recupera el
objeto respuesta usado por el servidor.
setAutoEmitResponse($flag) :
Indica si el servidor debería emitir automáticamente la
respuesta y todas las cabeceras; por defecto, esto es
TRUE.
autoEmitResponse() : Determina
si la auto-emisión de la respuesta está habilitada.
getServiceMap() : Recupera la
descripción del mapa de servicio en el form de un objeto
Zend_Json_Server_Smd .
Zend_Json_Server_Request
El medio ambiente de una solicitud JSON-RPC está encapsulado
en el objeto Zend_Json_Server_Request .
Este objeto le permite establecer porciones necesarias de la
solicitud JSON-RPC, incluida el ID de la solicitud, parámetros y
especificaciones de la versión JSON-RPC. Tiene la capacidad de
cargarse a sí mismo via JSON o un conjunto de opciones, y puede
mostrase a si mismo como JSON vía el método
toJson() .
El objeto solicitud tiene los siguientes métodos
disponibles:
setOptions(array $options) :
Especifica la configuración del objeto.
$options puede contener claves
que concuerden con cualuier método 'set':
setParams() ,
setMethod() ,
setId() , y
setVersion() .
addParam($value, $key = null) :
Agrega un parámetro para usar con el método de llamada.
Los parámetros pueden ser sólo los valores, o pueden
incluir opcionalmente el nombre del parámetro.
addParams(array $params) :
Agrega múltiples parámetros a la vez; proxies a
addParam()
setParams(array $params) :
Establece todos los parámetros a la vez; sobrescribe
cualquiera de los parámetros existentes.
getParam($index) : Recupera un
parámetro por posición o por el nombre.
getParams() : Recupera todos
los parámetros a la vez.
setMethod($name) : Establece el
método para llamar.
getMethod() : Recupera el
método que será llamado.
isMethodError() : Determinar si
la solicitud está malformada o no y si daría como
resultado un error.
setId($name) : Establecer el
identificador de solicitud(utilizado por el cliente para
igualar las solicitudes de respuestas).
getId() : Recuperar el
identificador de solicitudes.
setVersion($version) :
Establecer la versión de la especificación JSON-RPC que
conforma la solicitud. Puede ser '1.0' o '2.0'.
getVersion() : Recuperar la
versión de la especificación JSON-RPC utilizados por la
solicitud.
loadJson($json) : Cargar el
objeto solicitud de una cadena JSON.
toJson() : Mostrar la solicitud
como un string JSON.
Una versión específica de HTTP está
disponible a través de
Zend_Json_Server_Request_Http . Esta
clase podrá recuperar la solicitud via
php://input , y permite el acceso
JSON sin procesar vía el método
getRawJson() .
Zend_Json_Server_Response
La respuesta del conjunto de datos JSON-RPC es encapsulada en
el objeto Zend_Json_Server_Response .
Este objeto le permite ajustar el valor de retorno de la
solicitud, siendo la respuesta un error o no, el identificador
de solicitud, con que versión de especificación esta conformada
la respuesta de JSON-RPC, y, opcionalmente el mapa de servicio.
El objeto respuesta tiene los siguientes métodos
disponibles:
setResult($value) : Establecer
el resultado de la respuesta.
getResult() : Recuperar el
resultado de la respuesta.
setError(Zend_Json_Server_Error
$error) : Establecer un objeto error.
Si ya está, este será utilizado como la respuesta cuando
se serialize a JSON.
getError() : Recuperar el
objeto error, si lo hubiera.
isError() : Si la respuesta es
una respuesta de error o no.
setId($name) : Establecer el
identificador de solicitud (de manera que la respuesta
del cliente pueda coincidir con la solicitud original).
getId() : Recuperar el
identificador de solicitud.
setVersion($version) :
Establecer la versión JSON-RPC con la que deba estar
conformada la respuesta.
getVersion() : Recuperar la
versión JSON-RPC con la cumple la respuesta.
toJson() : Serializar la
respuesta a JSON. Si la respuesta es una respuesta de
error, serializar el objeto error.
setServiceMap($serviceMap) :
Establecer el objeto mapa de servicio para la respuesta.
getServiceMap() : Recuperar el
objeto mapa de servicio, si hubiera alguno.
Una versión específica de HTTP está
disponible a través de
Zend_Json_Server_Response_Http . Esta
clase enviará las cabeceras HTTP apropiadas
así como serializará la respuesta como JSON .
Zend_Json_Server_Error
JSON-RPC tiene un formato especial para informar condiciones
de error. Todos los errores necesitan proporcionar, mínimamente,
un mensaje de error y un código de error; opcionalmente, pueden
proporcionar datos adicionales, tales como un backtrace.
Los códigos de error derivan de los recomendados por el proyecto XML-RPC EPI .
Zend_Json_Server apropiadamente
asigna el código sobre la base de la condición de error. Para
las excepciones de la aplicación, se utiliza el código '-32000'.
Zend_Json_Server_Error expone los
siguientes métodos:
setCode($code) : Establece el
código de error; si el código de error no está en el
rango de aceptación de XML-RPC, -32000 será asignado.
getCode() : Recuperar el actual
código de error.
setMessage($message) :
Establecer el mensaje de error.
getMessage() : Recuperar el
mensaje de error actual.
setData($data) : Establecer el
conjunto de datos auxiliares para calificar más adelante
el error, tal como un backtrace.
getData() : Recuperar cualquier
auxiliar actual de errores de datos.
toArray() : Mandar el error a
un array. El array contendrá las claves 'code',
'message', y 'data'.
toJson() : Mandar el error a
una representación de error JSON-RPC.
Zend_Json_Server_Smd
SMD quiere decir Service Mapping Description, un esquema JSON
que define cómo un cliente puede interactuar con un servicio web
en particular. En el momento de escribir esto, la especificación todavía no ha sido ratificada
oficialmente, pero ya está en uso en Dojo toolkit así como en
otros clientes consumidores de JSON-RPC.
En su aspecto más básico, un SMD indica el método de
transporte (POST, GET, TCP/IP, etc), el tipo de envoltura de la
solicitud (generalmente se basa en el protocolo del servidor),
el objetivo URL del proveedor del servicio, y
un mapa de los servicios disponibles. En el caso de JSON-RPC, el
servicio de mapa es una lista de los métodos disponibles, en el
que cada método documenta los parámetros disponibles y sus
tipos, así como los tipos de valores esperados a devolver.
Zend_Json_Server_Smd Proporciona un
objeto orientado para construir servicios de mapas. Básicamente,
pasa los metadatos describiendo el servicio usando mutators, y
especifica los servicios (métodos y funciones).
Las descripciones de los servicios son típicamente instancias
de Zend_Json_Server_Smd_Service ; también
puede pasar toda la información como un array a los diversos
mutators de servicios en
Zend_Json_Server_Smd , y que
instanciará on objeto de servicio por usted. Los objetos de
servicio contienen información como el nombre del servicio
(típicamente, la función o el nombre del método), los parámetros
(nombres, tipos y posición), y el tipo del valor de retorno.
Opcionalmente, cada servicio puede tener su propio objetivo y
envoltura, aunque esta funcionalidad rara vez es utilizada.
Zend_Json_Server Realmente todo esto
sucede entre bambalinas para usted, utilizando reflexión sobre
las clases y funciones agregadas; debe crear su propio servicio
de mapas sólo si necesita brindar funcionalidad personalizada
que la introspección de clase y función no puede ofrecer.
Los métodos disponibles en
Zend_Json_Server_Smd incluyen:
setOptions(array $options) :
Establecer un objeto SMD desde un array de opciones.
Todos los mutators (métodos comenzando con 'set') se
pueden usar como claves.
setTransport($transport) :
Establecer el transporte usado para acceder al servicio;
únicamente POST es actualmente soportado.
getTransport() : Obtener el
servicio de transporte actual.
setEnvelope($envelopeType) :
Establecer la envoltura de la solicitud que debería ser
utilizada para acceder al servicio. Actualmente las
constantes soportadas son
Zend_Json_Server_Smd::ENV_JSONRPC_1
y
Zend_Json_Server_Smd::ENV_JSONRPC_1
.
getEnvelope() : Obtener la
envoltura de la petición actual.
setContentType($type) :
Establecer el tipo de contenido que deben utilizar las
solicitudes (por defecto, es 'application/json»).
getContentType() : Conseguir el
tipo del contenido actual para las solicitudes al
servicio.
setTarget($target) : Establecer
el punto final de la URL para el
servicio.
getTarget() : Obtener el punto
final de la URL para el servicio.
setId($id) : Normalmente, este
es el punto final de la URL del
servicio (igual que el objetivo).
getId() : Recuperar el ID del
servicio (normalmente el punto final de la
URL del servicio).
setDescription($description) :
Establecer una descripción del servicio (típicamente
información narrativa que describe el propósito del
servicio).
getDescription() : Obtener la
descripción del servicio.
setDojoCompatible($flag) :
Establecer un flag que indique si el SMD es compatible o
no con el toolkit de Dojo. Cuando sea verdadero, el
JSON SMD será formateado para
cumplir con el formato que espera el cliente de Dojo
JSON-RPC.
isDojoCompatible() : Devuelve
el valor del flag de compatibilidad de Dojo (FALSE, por
defecto).
addService($service) : Añade un
servicio al mapa. Puede ser un array de información a
pasar al constructor de
Zend_Json_Server_Smd_Service
, o una instancia de esa clase.
addServices(array $services) :
Agrega múltiples servicios a la vez.
setServices(array $services) :
Agrega múltiples servicios a la vez, sobreescribiendo
cualquiera de los servicios previamente establecidos.
getService($name) : Ontiene el
servicio por su nombre.
getServices() : Obtener todos
los servicios agregados.
removeService($name) : Elimina
un servicio del mapa.
toArray() : Mandar el mapa de
servicio a un array.
toDojoArray() : Mandar el mapa
de servicio a un array compatible con Dojo Toolkit.
toJson() : Mandar el mapa de
servicio a una representación JSON.
Zend_Json_Server_Smd_Service tiene los
siguientes métodos:
setOptions(array $options) :
Establecer el estado del objeto dede un array. Cualquier
mutator (métodos comenzando con 'set') puede ser
utilizado como una clave y establecerlo mediante este
método.
setName($name) : Establecer el
nombre del servicio (típicamente, la función o el nombre
del método).
getName() : Recuperar el nombre
del servicio.
setTransport($transport) :
Establecer el servicio de transporte (actualmente, sólo
transportes apoyados por
Zend_Json_Server_Smd son
permitidos).
getTransport() : Recuperar el
transporte actual.
setTarget($target) : Establecer
el punto final de la URL del servicio
(típicamente, este será el mismo que el SMD en general,
al cual el servicio está agregado).
getTarget() : Obtener el punto
final de la URL del servicio.
setEnvelope($envelopeType) :
Establecer la envoltura del servicio (actualmente, sólo
se permiten las envolturas soportadas por
Zend_Json_Server_Smd .
getEnvelope() : Recuperar el
tipo de envoltura del servicio.
addParam($type, array $options = array(),
$order = null) : Añadir un parámetro
para el servicio. Por defecto, sólo el tipo de parámetro
es necesario. Sin embargo, también puede especificar el
orden, así como opciones tales como:
name : el nombre del
parámetro
optional : cuándo el
parámetro es opcional o no
default : un valor por
defecto para el parámetro
description : texto
describiendo el parámetro
addParams(array $params) :
Agregar varios parámetros a la vez; cada param debería
ser un array asociativo conteniendo mínimamente la clave
'type' describiendo el tipo de parámetro y,
opcionalmente la clave 'order'; cualquiera de las otras
claves serán pasados como $options a
addOption() .
setParams(array $params) :
Establecer muchos parámetros a la vez, sobrescribiendo
cualquiera de los parámetros existentes.
getParams() : Recuperar todos
los parámetros actualmente establecidos.
setReturn($type) : Establecer
el tipo del valor de retorno del servicio.
getReturn() : Obtener el tipo
del valor de retorno del servicio.
toArray() : Mandar el servicio
a un array.
toJson() : Mandar el servicio a
una representación JSON .