[英]How to test a zend expressive rest api controller using PHPUnit?
[英]How to call another internal endpoint from within zend expressive REST api application?
我正在嘗試從 zend 表達(PSR-7)應用程序中的另一個方法中調用 REST api 端點(內部)。 目前我正在做的是,我發送另一個這樣的 http 請求( docs ):
$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);
但我想知道既然我正在嘗試調用內部端點,我是否能夠以某種方式轉發請求? 我聽說過控制器插件forwards ,但我不確定它是如何工作的。
端點 url 和請求類型是從數據庫中檢索的。 我可以直接調用該方法,但轉發端點會減少有條件地檢查每個模塊所需的工作。
感謝您能指出我正確的方向。
更新:
讓我解釋一下用例。 我們有一個調度程序數據庫,其中包含要發送的端點和參數。 每 5 分鍾 (CRON) 向調度程序 API 發送一個 cURL 請求。 調度程序檢查數據庫中提供的時間間隔並在此時間間隔觸發相應的端點。
因此,如果我理解正確,您的 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/
我想到的第一種方法是將當前類(可能是 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(“handle”方法)。 我首先更新了數據庫實體,然后簡單地調用 return parent::handle($request) 返回新的數據庫實體。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.