[英]Laravel: cannot access resource collection in middleware
我正在嘗試創建一個中間件,它將返回的響應包裝為我的 API 的統一 JSON 響應。 這將確保所有 API 響應具有相同的基本結構,如下所示:
{
"success": true,
"data": {...}
}
現在這是我目前使用的中間件:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class ApiResponseWrapper
{
/**
* Handle an incoming request.
*
* @param Request $request
*
* @return mixed
*/
public function handle($request, Closure $next)
{
/** @var Response $response */
$response = $next($request);
$original = $response->getOriginalContent();
$content = [
'success' => $response->isSuccessful(),
'data' => $original,
];
$jsonContent = json_encode($content, JsonResponse::DEFAULT_ENCODING_OPTIONS);
$response->setContent($jsonContent);
return $response;
}
}
這個中間件的兩個關鍵點是:
$original = $response->getOriginalContent();
line 獲取要換行的響應內容。$content
進行json_encode
。 當我想將分頁的ResourceCollection
傳遞到中間件時,就會出現問題。 控制器方法如下所示:
public function index(): AnonymousResourceCollection
{
/** @var User $user */
$user = auth()->user();
return PostResource::collection($user->posts->paginate(20));
}
通常,Laravel 集合中不存在->paginate(...)
方法。 這是從這里獲取的宏: gist.github.com/simonhamp/549e8821946e2c40a617c85d2cf5af5e 。
如果我現在點擊調用index()
方法的端點,預期的輸出是這樣的:
{
"success": true,
"data": {
"data": [
<PostResource as JSON object>
],
"meta": {...},
"links": {...},
}
}
但我實際得到的是:
{
"success": true,
"data": [
<Post Model as array>
]
}
我想我可能需要調用一種方法來將$original
(類型為Illuminate\\Support\\Collection
)編碼為分頁資源集合,但我沒有找到。
其他回復都正常。 例如,在另一個控制器方法上,我只返回一個數組或字符串,它們按預期包裝。
有誰知道這里有什么問題?
編輯:
我還嘗試在設置$content
變量之前添加它:
if (method_exists($original, 'toArray')) {
$original = $original->toArray();
}
它導致ResourceCollections
輸出相同。
在調查變量類型並查看 Laravel API 后,我發現最簡單的解決方案是檢查響應是否為JsonResponse
並從中獲取呈現的分頁數據:
public function handle($request, Closure $next)
{
/** @var Response $response */
$response = $next($request);
$content = [
'success' => $response->isSuccessful(),
];
if ($response instanceof JsonResponse) {
/** @var JsonResponse $response */
$data = $response->getData(true);
$content = array_merge($content, $data);
} else {
$content['data'] = $response->getOriginalContent();
}
$jsonContent = json_encode($content, JsonResponse::DEFAULT_ENCODING_OPTIONS);
$response->setContent($jsonContent);
return $response;
}
這導致了我的用例的預期響應:
{
"success": true,
"data": [
<PostResource as JSON object>
],
"meta": {...},
"links": {...},
}
另請注意,我最初在包裝data
鍵中指定了data
、 meta
和links
鍵。 我發現上面的結果有點漂亮,因為我繞過了雙包裝data
。
我希望這會幫助任何遇到這個問題的人!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.