alberto-leon-crespo / rest-entity-manager
基于symfony实体和fosrestbundle的Web服务的库。
Requires
- php: >=5.4
- doctrine/doctrine-bundle: ^1.6
- doctrine/orm: ^2.5
- friendsofsymfony/rest-bundle: ^2.3
- guzzlehttp/guzzle: ~5.3
- jms/serializer-bundle: ^2.3
- voku/arrayy: 3.8
This package is not auto-updated.
Last update: 2024-09-20 09:32:20 UTC
README
一个面向数据映射的REST实体管理器。当你使用面向创建Web服务的库时,遇到的主要问题是它们都旨在处理标准的连接到数据库的流。许多现代基于Web的API,充当其他企业和非企业API的中间代理。因此出现了“Rest Entity Manager”。
库的基本工作原理
该库包含两个标准序列化器。第一个序列化器负责在实体和不同的REST服务之间转换数据。第二个序列化器用于编码和解码客户端发送和接收的内容,从而填充API中的实体。
内部,实体管理器读取不同连接的配置并执行对各个Web服务的请求。
服务
- alc_rest_entity_manager.handler:是REST实体管理器。负责读取不同连接的配置并将其加载到REST客户端。
- alc_rest_entity_manager.jms_event_subscriber:负责读取实体配置并配置到不同的REST WS映射。
- alc_rest_entity_manager.serializer:是负责映射客户端发送和接收的信息到API中不同实体的序列化器。
- alc_rest_entity_manager.logger:负责监控和记录管理器的REST请求日志。
- alc_rest_entity_manager.metadata_class_reader:负责读取用于执行映射所需的类元信息。
- alc_rest_entity_manager.parameters_procesor:负责根据在REST连接中定义的配置处理过滤参数。
- alc_rest_request_parameters_name_override:在“request”服务中覆盖URL参数,遵循点表示法。例如:“poliza.id”
预备知识
这是一个旨在与“FOSRestBundle”一起工作的bundle,但也无需它即可使用。
安装
步骤 1:下载bundle
打开命令行界面,进入项目目录,并执行以下命令以下载此bundle的最新稳定版本。
$ composer require alberto-leon-crespo/rest-entity-manager
步骤 2:激活bundle
通过向app/AppKernel.php
文件中添加以下行来激活bundle:
<?php // app/AppKernel.php // ... class AppKernel extends Kernel { public function registerBundles() { $bundles = array( // ... new ALC\RestEntityManager\ALCRestEntityManagerBundle(), ); // ... } }
配置
要使用面向REST的实体,必须先配置REST连接。
# app/config/config.yml alc_rest_entity_manager: default_manager: default # El nombre de la conexion que usara el manager por defecto. managers: default: name: 'default' # El nombre de la conexion host: 'https://jsonplaceholder.typicode.com/' # URL base del servicio rest que se va a consultar session_timeout: 7200 # Tiempo de expiración de la sesion que hay entre el cliente rest y el webservice de destino avanced: filtering: ignored_parameters: [_fields,_sort,_page,_limit] #Parametros ignorados del filtrado, no se consideran parametros de filtrado parameters_map: maps: - { origin: _fields, destination: selection } # El campo de origen se mapea al WS como el campo destino indicado - { origin: _page, destination: _page } # El campo de origen se mapea al WS como el campo destino indicado - { origin: _limit, destination: _limit } # El campo de origen se mapea al WS como el campo destino indicado - { origin: _sort, interceptor: ALC\WebServiceBundle\Interceptors\SortParametersInterceptor::parseSortFields } # El campo de origen se transforma por medio de un ParameterInterceptor custom_params: # Bloque de parametros de configuración personalizables secret_api_key: example1234 events_handlers: # Bloque de eventos sobre peticiones. tokens_inject_handler: # Nombre del manejador del evento event: before # Evento a interceptar interceptor: 'ALC\WebServiceBundle\Interceptors\TokenInjector::injectToken' # Interceptor de las peticiones
如果您想与FOSRestBundle一起使用序列化器,则需要用以下配置覆盖标准序列化器。
# app/config/config.yml fos_rest: service: serializer: alc_rest_entity_manager.serializer
实体配置注解
-
ALC\RestEntityManager\Annotations\Resource:
指示实体将访问的REST资源。在这种情况下,“users”
-
ALC\RestEntityManager\Annotations\Repository:
指示与实体关联的存储库。
-
ALC\RestEntityManager\Annotations\Id:
指示注释前的属性是资源的唯一标识符。
-
ALC\RestEntityManager\Annotations\Field:
-
target:REST服务的目标字段。
-
type:字段的数据类型。
-
支持的数据类型
支持的类型与JMSSerializer接受的类型相同。JMSSerializer。
-
-
-
ALC\RestEntityManager\Annotations\Headers:
允许指定一个HTTP头数组及其应用于实体REST请求的值。
<?php namespace ALC\WebServiceBundle\Entity\Users; use ALC\RestEntityManager\Annotations as Rest; use Symfony\Component\Validator\Constraints as Assert; /** * @Rest\Resource("users") * @Rest\Headers({"content-type": "application/json","cache-control": "no-cache"}) * @Rest\Repository("ALC\WebServiceBundle\Entity\Users\UsersRepository") */ class Users { /** * @Rest\Id() * @Rest\Field(target="id",type="integer") */ private $idUsuario; /** * @Rest\Field(target="name",type="string") * @Assert\NotNull() * @Assert\NotBlank() */ private $nombre; \\ Some class properties and methods \\ .... }
REST管理器的一般操作
按id搜索
等同于GET /users/:id
- id:要查询的资源标识符。
- format:信息的输出格式。
- json
- xml
- object
- type:如果指定了format
object
,则输出数据类型。
<?php $objUsersRepository = $this ->get('alc_rest_entity_manager.handler') ->getManager('default') ->getRepository('AppBundle:Users\Users'); $arrResponse = $objUsersRespository->find( $userId, 'object', 'ALC\\WebServiceBundle\\Entity\\Users\\Users' );
检索列表中的所有记录
等同于GET /users
- format:信息的输出格式。
- json
- xml
- object
- type:如果指定了format
object
,则输出数据类型。
<?php $objUsersRepository = $this ->get('alc_rest_entity_manager.handler') ->getManager('default') ->getRepository('AppBundle:Users\Users'); $arrResponse = $objUsersRespository->findAll( 'object', 'ALC\\WebServiceBundle\\Entity\\Users\\Users' );
检索过滤后的列表
等同于GET /users?nombre=Alberto
- filters:应用于列表的过滤器。
- format:信息的输出格式。
- json
- xml
- object
- type:如果指定了format
object
,则输出数据类型。
<?php $arrFilters = array( 'nombre' => 'Jhon' ); $objUsersRepository = $this ->get('alc_rest_entity_manager.handler') ->getManager('default') ->getRepository('AppBundle:Users\Users'); $arrResponse = $objUsersRespository->findBy( $arrFilters, 'object', 'ALC\\WebServiceBundle\\Entity\\Users\\Users' );
检索过滤后列表的第一条记录
等同于GET /users?nombre=Alberto
- filters:应用于列表的过滤器。
- format:信息的输出格式。
- json
- xml
- object
- type:如果指定了format
object
,则输出数据类型。
<?php $arrFilters = array( 'nombre' => 'Jhon' ); $objUsersRepository = $this ->get('alc_rest_entity_manager.handler') ->getManager('default') ->getRepository('AppBundle:Users\Users'); $arrResponse = $objUsersRespository->findOneBy( $arrFilters, 'object', 'ALC\\WebServiceBundle\\Entity\\Users\\Users' );
保存更改
等同于POST /users或PUT /users
如果实体对象在标记为id的字段中有值,则执行PUT操作;否则执行POST操作。
- object:要持久化的实体实例。
- format:信息的输出格式。
- json
- xml
- object
- type:如果指定了format
object
,则输出数据类型。
<?php $objUser = new \AppBundle\Users(); $objUser->setNombre("Jhon"); $objUser->setApellido("Doe"); $em = $this ->get('alc_rest_entity_manager.handler') ->getManager('default'); $arrResponse = $em->persist( $objUser, 'object', 'ALC\\WebServiceBundle\\Entity\\Users\\Users' );
检查是否存在记录,如果存在则更新,如果不存在则创建。
等同于POST /users或PUT /users
如果实体对象在标记为id的字段中有值且该id存在,则执行PUT操作;否则执行POST操作。
- object:要持久化的实体实例。
- format:信息的输出格式。
- json
- xml
- object
- type:如果指定了format
object
,则输出数据类型。
<?php $objUser = new \AppBundle\Users(); $objUser->setNombre("Jhon"); $objUser->setApellido("Doe"); $em = $this ->get('alc_rest_entity_manager.handler') ->getManager('default'); $arrResponse = $em->merge( $objUser, 'object', 'ALC\\WebServiceBundle\\Entity\\Users\\Users' );
使用webservice的更新值获取实体信息
- object:要刷新的实体实例。
- format:信息的输出格式。
- json
- xml
- object
- type:如果指定了format
object
,则输出数据类型。
<?php $objUser = new \AppBundle\Users(); $objUser->setIdUsuario(2); $em = $this ->get('alc_rest_entity_manager.handler') ->getManager('default'); $arrResponse = $em->refresh( $objUser, 'object', 'ALC\\WebServiceBundle\\Entity\\Users\\Users' );
REST管理器的自定义操作
当由于各种原因,这些标准操作不能适用于您的用例时,您可以通过仓库或直接在控制器中执行操作(就像处理REST客户端一样)来完全自定义调用。
使用仓库
在实体REST中定义"Repository"注解非常重要。
<?php // Repository namespace AppBundle\Entity\Users; use ALC\RestEntityManager\RestRepository; class UsersRepository extends RestRepository { public function listadoUsuariosWithVocalA(){ $response = $this->get( 'users', array() ); $arrUsers = $this->serializer->deserialize( $response->getBody()->getContents(), 'array<ALC\WebServiceBundle\Entity\Users\Users>', 'json' ); foreach( $arrUsers as $key => $objUser ){ if( mb_strpos( $objUser->getNombre(), 'a', null, 'utf8' ) === false ){ unset( $arrUsers[$key] ); } } return array_values( $arrUsers ); } } // Controller <?php namespace ALC\WebServiceBundle\Controller; use FOS\RestBundle\Controller\FOSRestController; use Symfony\Component\HttpFoundation\Request; class UsersController extends FOSRestController { public function getUsersAction(Request $objRequest){ $objEntityManager = $this->get('alc_rest_entity_manager.handler')->getManager(); /** * @var $objUsersRespository \ALC\RestEntityManager\Services\RestEntityHandler\RestEntityHandler|\ALC\WebServiceBundle\Entity\Users\UsersRepository */ $objUsersRespository = $objEntityManager->getRepository('ALCWebServiceBundle:Users\Users'); $arrUsersWithAVocal = $objEntityManager->listadoUsuariosWithVocalA(); // If use FOSRestBundle return $arrUsersWithAVocal; // If dont use FOSRestBundle $strUsersSerialized = $this->get('alc_rest_entity_manager.serializer')->serialize( $arrUsersWithAVocal, 'json' ); $objResponse = new Response( $strUsersSerialized, 200, ['Content-Type'=>'application/json'] ); return $objResponse;
高级过滤选项
有时,我们传递给URL的参数不是过滤参数(排序、分页等)。
为此,只需指定哪些参数将忽略过滤以及它们在目标WS中的等效项。
直接等效
在这种情况下,与目标WS的等效是直接的,即源字段与目标字段之间的等效。
# app/config/config.yml ... name: 'default' host: 'https://jsonplaceholder.typicode.com/' session_timeout: 7200 avanced: filtering: ignored_parameters: [_fields,_sort,_page,_limit] # Parametros especiales que deben de ser ignorados en los filtrados. parameters_map: # Mapeo de parametros especiales origen - destino maps: - { origin: page, destination: _page } # Campor de origen page, campo de destino _page - { origin: limit, destination: _limit } # Campor de origen limit, campo de destino _limit
因此,如果您的WS中输入的URL是{{URL_BASE}}/usuarios?page=1&limit=5,则将按照以下方式向目标WS发出请求{{URL_BASE}}/users?_page=1&_limit=5
间接等效
您可能会遇到一些情况,其中与目标参数的特殊等效不是直接的,即一个参数可能对应两个,如下例所示。
在这种情况下,您可以创建以下方式的参数拦截器
<?php namespace ALC\WebServiceBundle\Interceptors; use ALC\RestEntityManager\ParameterInterceptor; class SortParametersInterceptor extends ParameterInterceptor { public function parseSortFields($value) { $firstCharacter = $value[0]; $fieldName = substr($value, 1); $order = null; if ($firstCharacter === '-') { $order = 'desc'; } elseif ($firstCharacter === '+' || $firstCharacter === ' ') { $order = 'asc'; } // Busca las equivalencias entre los parametros de entrada de tu WS y el WS de destino $arrFinalParams = $this->getMetadataClassReader()->matchEntityFieldsWithResourcesFieldsRecursive( [ $fieldName => $order ] ); $arrayMatch = array(); foreach( $arrFinalParams as $campoOrdenar => $metodoOrdenacion ){ $arrayMatch['_sort'] = $campoOrdenar; $arrayMatch['_order'] = $metodoOrdenacion; }; return $arrayMatch; } }
为了注册,只需在"parameters_map"部分注册以下配置即可
# app/config/config.yml ... name: 'default' host: 'https://jsonplaceholder.typicode.com/' session_timeout: 7200 avanced: filtering: ignored_parameters: [_fields,_sort,_page,_limit] # Parametros especiales que deben de ser ignorados en los filtrados. parameters_map: # Mapeo de parametros especiales origen - destino maps: - { origin: _sort, interceptor: ALC\WebServiceBundle\Interceptors\SortParametersInterceptor::parseSortFields }
事件拦截器
如果需要拦截请求事件以注入API令牌到头或执行类似操作,只需创建以下方式的需求拦截器
<?php namespace ALC\WebServiceBundle\Interceptors; use ALC\RestEntityManager\Interceptors\RequestInterceptor; use GuzzleHttp\Event\BeforeEvent; // La clase debe de extender al objecto ALC\RestEntityManager\Interceptors\RequestInterceptor class TokenInjector extends RequestInterceptor { public function injectToken(BeforeEvent $event, array $arrManagerConfig){ $apiKey = $arrManagerConfig['custom_params']['secret_api_key']; $event->getRequest()->setHeader('X-Api-Key', $apiKey); return $event; } }
创建拦截器后,您必须按照以下配置进行注册
# app/config/config.yml ... name: 'default' host: 'https://jsonplaceholder.typicode.com/' session_timeout: 7200 avanced: ... events_handlers: tokens_inject_handler: event: before interceptor: 'ALC\WebServiceBundle\Interceptors\TokenInjector::injectToken'
您必须指定要拦截的事件以及拦截请求的类和方法。
可以拦截的事件与Guzzle Http Client接受的事件相同。Guzzle Http Client。
示例
要查看更多示例,请参阅示例捆绑包ALC\WebServiceBundle