Un componente base para integrar Sencha Ext JS Ext.direct en una aplicación PHP
Esta biblioteca proporciona una implementación del lado del servidor para Sencha Ext.direct, un componente de comunicación estilo RPC que forma parte de Sencha's Ext JS y Sencha Touch .
ext direct es un protocolo de llamada a procedimiento remoto (RPC) independiente de la plataforma y el idioma. ext direct permite una comunicación fluida entre el lado del cliente de una aplicación Ext JS y cualquier plataforma de servidor que cumpla con la especificación. ext direct no tiene estado y es liviano, y admite funciones como descubrimiento de API, procesamiento por lotes de llamadas y eventos de servidor a cliente.
Actualmente, esta biblioteca sólo se utiliza como base de teqneers/ext-direct-bundle, un paquete de Symfony que integra *Ext.direct* en una aplicación basada en Symfony. No hemos intentado utilizar la biblioteca como un componente independiente ni en ningún otro contexto que no sea un entorno Symfony, por lo que a continuación se explica cómo debería funcionar teóricamente sin el paquete. Agradeceríamos cualquier ayuda y contribución para que la biblioteca sea más útil fuera del paquete.
Puedes instalar esta biblioteca usando el compositor.
composer require teqneers/ext-direct
o agregue el paquete a su archivo compositor.json directamente.
La estrategia de nomenclatura determina cómo los nombres de clases y espacios de nombres de PHP se traducen en nombres de acciones Ext.direct compatibles con Javascript. La estrategia de nomenclatura predeterminada traduce el separador namspapce en un archivo
.
. Entonces MyNamespaceService
se traduce a My.namespace.Service
. Tenga en cuenta que la transformación debe ser reversible ( My.namespace.Service
=> MyNamespaceService
).
$ namingStrategy = new TQ ExtDirect Service DefaultNamingStrategy ();
El registro de servicios utiliza una fábrica de metadatos de la biblioteca jms/metadata
y un controlador de anotaciones asociado (que a su vez utiliza un lector de anotaciones doctrine/annotations
) para leer metainformación sobre posibles clases de servicios anotados.
$ serviceRegistry = new TQ ExtDirect Service DefaultServiceRegistry (
new Metadata MetadataFactory (
new TQ ExtDirect Metadata Driver AnnotationDriver (
new Doctrine Common Annotations AnnotationReader ()
)
),
$ namingStrategy
);
El registro de servicios se puede completar manualmente llamando addServices()
o addService()
o importando servicios usando TQExtDirectServiceServiceLoader
. La implementación predeterminada TQExtDirectServicePathServiceLoader
puede leer clases de un conjunto de rutas determinadas.
El despachador de eventos es opcional, pero es necesario para utilizar funciones como conversión y validación de argumentos y conversión de resultados del oyente de perfiles.
$ eventDispatcher = new Symfony Component EventDispatcher EventDispatcher ();
El enrutador se utiliza para traducir las solicitudes Ext.direct entrantes en llamadas a métodos PHP para la clase de servicio correcta. ContainerServiceFactory
admite la recuperación de servicios desde un contenedor de inyección de dependencia de Symfony o la creación de instancias de servicios simples que no requieren ningún argumento de constructor. Las llamadas de servicio estáticas pasan por alto la fábrica de servicios.
$ router = new TQ ExtDirect Router Router (
new TQ ExtDirect Router ServiceResolver (
$ serviceRegistry ,
new TQ ExtDirect Service ContainerServiceFactory (
/* a SymfonyComponentDependencyInjectionContainerInterface */
)
),
$ eventDispatcher
);
El objeto de punto final es una fachada frente a todos los componentes del lado del servidor Ext.direct . Con su método createServiceDescription()
se puede obtener una descripción API compatible con el estándar, mientras que handleRequest()
toma un SymfonyComponentHttpFoundationRequest
y devuelve un SymfonyComponentHttpFoundationResponse
que contiene la respuesta Ext.direct para las llamadas de servicio. recibió.
$ endpoint = TQ ExtDirect Service Endpoint (
' default ' , // endpoint id
new TQ ExtDirect Description ServiceDescriptionFactory (
$ serviceRegistry ,
' My.api ' ,
$ router ,
new TQ ExtDirect Router RequestFactory (),
' My.api.REMOTING_API '
)
);
El administrador de puntos finales es solo una colección simple de puntos finales que permiten la recuperación utilizando la identificación del punto final. Esto permite una fácil exposición de múltiples API independientes.
$ manager = new TQ ExtDirect Service EndpointManager ();
$ manager -> addEndpoint ( $ endpoint );
$ defaultEndpoint = $ manager -> getEndpoint ( ' default ' );
$ apiResponse = $ defaultEndpoint -> createServiceDescription ( ' /path/to/router ' );
$ apiResponse -> send ();
$ request = Symfony Component HttpFoundation Request:: createFromGlobals ();
$ response = $ defaultEndpoint -> handleRequest ( $ request );
$ response -> send ();
El proceso de enrutamiento se puede manipular y aumentar mediante el uso de detectores de eventos en el despachador de eventos pasado al enrutador. La biblioteca proporciona cuatro suscriptores de eventos que permiten
Los convertidores de argumentos y resultados incluidos utilizan la biblioteca jms/serializer
para proporcionar capacidades extendidas de (des)serialización, mientras que el validador de argumentos predeterminado utiliza la biblioteca symfony/validator
.
$ eventDispatcher -> addSubscriber (
new TQ ExtDirect Router EventListener ArgumentConversionListener (
new TQ ExtDirect Router ArgumentConverter ( /* a JMSSerializerSerializer */ )
)
);
$ eventDispatcher -> addSubscriber (
new TQ ExtDirect Router EventListener ArgumentValidationListener (
new TQ ExtDirect Router ArgumentValidator ( /* a SymfonyComponentValidatorValidatorValidatorInterface */ )
)
);
$ eventDispatcher -> addSubscriber (
new TQ ExtDirect Router EventListener ResultConversionListener (
new TQ ExtDirect Router ResultConverter ( /* a JMSSerializerSerializer */ )
)
);
$ eventDispatcher -> addSubscriber (
new TQ ExtDirect Router EventListener StopwatchListener (
/* a SymfonyComponentStopwatchStopwatch */
)
);
Los servicios que se expondrán a través de la API Ext.direct deben estar decorados con metainformación adecuada. Actualmente esto sólo es posible usando anotaciones (como las conocidas en Doctrine, Symfony u otras bibliotecas PHP modernas).
Cada clase de servicio que se expondrá como una acción Ext.direct debe anotarse con TQExtDirectAnnotationAction
. La anotación Action
toma opcionalmente un parámetro de identificación de servicio para servicios que no son estáticos ni pueden crearse instancias con un constructor sin parámetros.
use TQ ExtDirect Annotation as Direct ;
/**
* @DirectAction()
*/
class Service1
{
// service will be instantiated using the parameter-less constructor if called method is not static
}
/**
* @DirectAction("app.direct.service2")
*/
class Service2
{
// service will be retrieved from the dependency injection container using id "app.direct.service2" if called method is not static
}
Además, cada método que se expondrá en una acción Ext.direct debe estar anotado con TQExtDirectAnnotationMethod
. La anotación Method
opcionalmente toma true
para designar el método como un controlador de formulario (que acepta publicaciones de formulario regulares) o false
para designar el método como un método Ext.direct normal (este es el valor predeterminado).
/**
* @DirectAction("app.direct.service3")
*/
class Service3
{
/**
* @DirectMethod()
*/
public function methodA ()
{
// regular method
}
/**
* @DirectMethod(true)
*/
public function methodB ()
{
// form handler method
}
}
Las funciones extendidas, como los parámetros con nombre y los parámetros con nombre estrictos descritos en la especificación Ext.direct, actualmente no están expuestos a través del sistema de anotaciones.
Los parámetros que entran en un método que se llama a través de una solicitud Ext.direct también se pueden anotar para aplicar la validación de parámetros. Esto requiere que TQExtDirectRouterEventListenerArgumentValidationListener
esté registrado con el despachador de eventos apropiado.
use Symfony Component Validator Constraints as Assert ;
/**
* @DirectAction("app.direct.service4")
*/
class Service4
{
/**
* @DirectMethod()
* @DirectParameter("a", { @AssertNotNull(), @AssertType("int") })
*
* @param int $a
*/
public function methodA ( $ a )
{
}
}
Si la firma del método que se llama expone parámetros con una sugerencia de tipo para SymfonyComponentHttpFoundationRequest
y/o TQExtDirectRouterRequest
, la solicitud HTTP entrante de Symfony y/o el Ext.direct sin formato La solicitud se inyecta en la llamada al método automáticamente. Este es un método de manejo de formularios especialmente importante porque no hay otra forma de acceder a los parámetros de solicitud HTTP entrantes (publicación de formulario).
Tan pronto como TQExtDirectRouterEventListenerArgumentConversionListener
esté habilitado, se pueden usar parámetros de objeto estrictamente tipificados en los métodos de servicio. Estos argumentos se deserializarán automáticamente a partir de la solicitud JSON entrante y se inyectarán en la llamada al método.
Lo mismo ocurre con la devolución de objetos de una llamada a un método de servicio. Si TQExtDirectRouterEventListenerResultConversionListener
está habilitado, los valores devueltos se serializan automáticamente en JSON incluso si no son objetos triviales.
Tanto el argumento como la conversión del valor de retorno se basan en la excelente biblioteca jms/serializer
de Johannes Schmitt. Consulte la documentación para obtener más información.
La especificación ext direct se puede encontrar en el sitio web de documentación de Sencha.
La licencia MIT (MIT)
Copyright (c) 2015 TEQneers GmbH & Co. KG
Por el presente se otorga permiso, sin cargo, a cualquier persona que obtenga una copia de este software y los archivos de documentación asociados (el "Software"), para operar con el Software sin restricciones, incluidos, entre otros, los derechos de uso, copia, modificación, fusión. , publicar, distribuir, sublicenciar y/o vender copias del Software, y permitir que las personas a quienes se les proporciona el Software lo hagan, sujeto a las siguientes condiciones:
El aviso de derechos de autor anterior y este aviso de permiso se incluirán en todas las copias o partes sustanciales del Software.
EL SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O IMPLÍCITA, INCLUYENDO PERO NO LIMITADO A LAS GARANTÍAS DE COMERCIABILIDAD, IDONEIDAD PARA UN PROPÓSITO PARTICULAR Y NO INFRACCIÓN. EN NINGÚN CASO LOS AUTORES O TITULARES DE DERECHOS DE AUTOR SERÁN RESPONSABLES DE NINGÚN RECLAMO, DAÑO U OTRA RESPONSABILIDAD, YA SEA EN UNA ACCIÓN CONTRACTUAL, AGRAVIO O DE OTRA MANERA, QUE SURJA DE, FUERA DE O EN RELACIÓN CON EL SOFTWARE O EL USO U OTRAS NEGOCIOS EN EL SOFTWARE.