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
verdadero.
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 (falso, 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.