1

我正在尝试从 zend expressive (PSR-7) 应用程序的另一个方法中调用 REST api 端点(内部)。目前我正在做的是,我发送另一个这样的http请求(文档):

$request = (new Zend\Diactoros\Request())
    ->withUri(new Zend\Diactoros\Uri('http://example.com'))
    ->withMethod('PATCH')
    ->withAddedHeader('Authorization', 'Bearer ' . $token)
    ->withAddedHeader('Content-Type', 'application/json');

$request->getBody()->write(json_encode($data));
$response = $client->send($request);

但我想知道,由于我正在尝试调用内部端点,我能否以某种方式转发请求?我听说过控制器插件转发,但我不确定它是如何工作的。

从数据库中检索端点 url 和请求类型。我可以直接调用该方法,但转发端点会减少有条件地检查每个模块所需的工作。

感谢您能指出我正确的方向。

更新:

让我解释一下用例。我们有一个调度程序数据库,其中包含要发送的端点和参数。每 5 分钟 (CRON) 向调度程序 API 发送一个 cURL 请求。调度程序检查数据库中提供的时间间隔,并在此时间间隔触发相应的端点。

4

2 回答 2

1

因此,如果我理解正确,您的 API 会收到一组命令和每个命令的一组参数。我将为每个命令创建一个单独的类,以及一个包含映射的类,您可能会将其视为一个工厂。

接口:

public function handle(ServerRequestInterface $request): ResponseInterface
{
    $parameters = $request->getAttribute('parameters');
    foreach($request->getAttribute('commands') as $commandName){
        $commandClass = CommandsMappingClass::getClassForCommand($commandName);

        //you can save the response if you need to
        (new $commandClass())->__invoke($parameters[$commandName]);
    }


}

命令映射类:

    private const MAPPING = [
        'command1' => Command1::class,
    ];

    public static function getClassForCommand(string $commandName): ?string
    {
       //you can return a default command if you need to 
        return self::MAPPING[$commandName] ?? null;
    }

这是一个基本的解决方案。映射可以看作是一个动态注册表,应用程序的每个模块都可以添加一个 cron 作业命令(当然,这些命令不会存储在常量中)。请参阅https://docs.zendframework.com/zend-servicemanager/delegators/

于 2020-01-03T14:54:17.113 回答
0

我想到的第一个方法是将当前类(可能是 RequestHandleInterface 的实现)转换为中间件(MiddlewareInterface)并更改路由定义。而不是 RequestHandler::class 您将拥有 [Middleware::class, RequestHandler::class](例如 [EditEntityMiddleware::class, GetEntityHandler::class])。如果您需要将信息从中间件传递给处理程序,您只需将其添加到请求中:

return $handler->handle($request->withAttribute('newInfo' => $newInfo));

为了访问请求处理程序中的信息:

$newInfo = $request->getAttribute('newInfo');

这个 API 应该响应更快,但是如果你有很多端点,可能很难添加/编辑很多路由。

如果你给我们一个更有说服力的例子,我们可能会得到更好的答案。我在编辑实体时遇到了同样的情况,因为我必须对数据库进行更改并返回新实体。对于 EditHandler,我只是扩展了 GetEntityHandler(“句柄”方法)。我首先更新了数据库实体,然后简单地调用 return parent::handle($request) 来返回新的数据库实体。

于 2019-12-31T12:08:22.220 回答