使用 Guzzle 将 APIRespose 中的错误传递给 Laravel 视图

Pass errors from API Respose to Laravel view using Guzzle

这是我的代码:

public function store(Request $request)
{
    try {

        $request->merge(['subject' => 'Subject']);

        $client = new Client(['base_uri' => 'http://crm.vulcan/api/v1/']);

        $res = $client->request('POST','contactForm',[
            'headers' => [
                'Accept' => 'application/json'
            ]
        ]);

    } catch (RequestException $e) {
        return Redirect::route('contact.form')->withErrors($e->getResponse());
    }
}

它不起作用,因为我不知道 $e->getResponse() 应该如何工作。

如果我这样做 dd($e->getResponse()) 那么我会得到这个:

Response {#330 ▼
  -reasonPhrase: "Unprocessable Entity"
  -statusCode: 422
  -headers: array:7 [▶]
  -headerLines: array:7 [▶]
  -protocol: "1.1"
  -stream: Stream {#328 ▶}
}

reasonPhrasestatusCode 正是我所期待的,所以没有问题。

但是,我真正想要的只是 API 中的 JSON 对象,它说明了哪些字段未验证。我知道该对象在那里,因为当我通过 Postman 发送 POST 时我可以看到它。而且,奇怪的是,如果我在完全相同的 $e->getResponse 上执行 return,那么我也可以看到该对象:

{
"name": [
    "The name field is required."
],
"nickname": [
    "The nickname field is required."
],
"email": [
    "The email field is required."
],
"subject": [
    "A subject must be provided"
],
"body-text": [
    "The body-text field is required."
]
}

这正是我需要传递给 withErrors() 的内容,然后我就完成了,但我不知道该怎么做。

我觉得我对流有误解,但我已经阅读了有关 PSR7 和流的内容,恐怕我不明白它的任何含义或它与这个特定问题的相关性。

编辑

经过一番摆弄,我将 catch 更新为以下内容:

        $errors = json_decode($e->getResponse()->getBody()->getContents());

        return Redirect::route('contact.form')->withErrors($errors);

这似乎有效,因为我得到 JSON 格式错误的对象 Laravel 可以用于表单。

这应该可以处理 HTTP 代码而不抛出异常:

public function store(Request $request)
{
    $request->merge(['subject' => 'Subject']);

    $client = new Guzzle([
        'base_uri' => 'http://crm.vulcan/api/v1/'
    ]);

    $res = $client->request('POST','contactForm',[
        'http_errors'=>false,
        'headers' => [
            'Accept' => 'application/json'
        ]
    ]);

    if ($res->getStatusCode() == 422) {
        //then there should be some validation JSON here;
        $errors = json_decode($res->getBody()->getContents());
    } 

    return Redirect::route('contact.form')->withErrors($errors);
}

我想,您需要从响应中获取正文内容。正如 documentation 所说,您可以使用 $response->getBody() 方法获取响应主体,并将其转换为 string.

如果你想稍后解析json对php数组的响应,你可以直接使用$response->json()方法。

对于您的情况,代码应如下所示:

$body = (string) $e->getResponse()->getBody();
// or
$body = $e->getResponse()->json();

编辑:我不确定 $e->getResponse() return 是否与文档中描述的相同 class 实例。如果以上代码不起作用,您应该能够从 $res 对象获取响应正文。