Laravel 通通給我回應 Json


建立時間: 2024年2月22日 15:49
更新時間: 2024年2月22日 16:01

說明

如果你跟我一樣打算使用 Laravel 設定 API,並且希望總是回應 Json,就可以參考本篇文章,我在很多情境之下都讓 Laravel 回應 Json。

例外回應 Json

讓 Laravel 自動將例外回應 Json。

Handler 是例外預設會到達的地方,在 register() 中實作 renderable() 回應例外處理。

app\Exceptions\Handler.php

<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Request;
use Throwable;

class Handler extends ExceptionHandler
{
    /**
     * The list of the inputs that are never flashed to the session on validation exceptions.
     *
     * @var array<int, string>
     */
    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];

    /**
     * Register the exception handling callbacks for the application.
     */
    public function register(): void
    {
        $this->renderable(function (Throwable $throwable, Request $request) {
            // 處理 api 路由
            if ($request->is('api/*')) {
                // debug 模式顯示預設的錯誤頁面
                if (app()->hasDebugModeEnabled()) {
                    return false;
                }

                // local 回應 json 錯誤訊息
                if (app()->environment('local')) {
                    return response()->json(
                        [
                            'Message' => $throwable->getMessage(),
                            'Status' => 'fail',
                        ],
                        500
                    );
                }

                // 其餘回應通用格式
                return response()->json(
                    [
                        'Message' => 'Internal server error.',
                        'Status' => 'fail',
                    ],
                    500
                );
            }
        });
    }
}

這是我自己寫的例外,可以方便地 throw new FailException(); 拋出例外。

app\Exceptions\FailException.php

<?php

declare(strict_types=1);

namespace App\Exceptions;

use Exception;
use Illuminate\Http\JsonResponse;
use Throwable;

/**
 * To response fail json
 */
class FailException extends Exception
{
    /**
     * Construct
     *
     * @param string $message 錯誤訊息
     * @param int $statusCode HTTP status code
     * @param string $status Internal status code
     * @param int $code The Exception code
     * @param Throwable|null $previous The previous throwable used for the exception chaining.
     * @return void
     */
    public function __construct(
        string $message = 'Internal server error.',
        private int $statusCode = 500,
        private string $status = 'fail',
        int $code = 0,
        ?Throwable $previous = null
    ) {
        parent::__construct($message, $code, $previous);
    }

    public function render(): JsonResponse
    {
        return response()->json(
            [
                'message' => $this->getMessage(),
                'status' => $this->status,
            ],
            $this->statusCode
        );
    }
}

404 Not Found 回應 Json

在路由檔案中,實作最後找不到路由時回應 Json。

routes\api.php

// 404 not found.
Route::fallback(function () {
    return response()->json(
        [
            'Message' => '404 not found.',
            'Status' => 'fail'
        ],
        JsonResponse::HTTP_NOT_FOUND
    );
});

routes\web.php

// 404 not found.
Route::fallback(function () {
    return response()->json(
        [
            'Message' => '404 not found.',
            'Status' => 'fail'
        ],
        JsonResponse::HTTP_NOT_FOUND
    );
});

表單驗證失敗回應 Json

主要是實作 failedValidation(),你可以像我一樣,所有的表單都繼承 ApiFormRequest,確保每個表單都是回應 Json。

例如: class MyForm extends FormRequest

app\Http\Requests\ApiFormRequest.php

<?php

declare(strict_types=1);

namespace App\Common;

use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\JsonResponse;
use Illuminate\Validation\ValidationException;

/**
 * 處理 Api Form 表單
 */
class ApiFormRequest extends FormRequest
{
    /**
     * 自定驗證失敗處理
     *
     * @return void
     *
     * @throws BindingResolutionException
     * @throws ValidationException
     */
    protected function failedValidation(Validator $validator)
    {
        throw new ValidationException(
            $validator,
            response()->json(
                [
                    'Errors' => $validator->errors(),
                    'Status' => 'fail',
                ],
                JsonResponse::HTTP_UNPROCESSABLE_ENTITY
            )
        );
    }
}

Controller 回應 Json

這個部分就比較常見了,在方法的最後回傳 return response()->json(); 就行了。

觀看次數: 636
apijsonlaravelresponse
按讚追蹤 Enjoy 軟體 Facebook 粉絲專頁
每週分享資訊技術

一杯咖啡的力量,勝過千言萬語的感謝。

支持我一杯咖啡,讓我繼續創作優質內容,與您分享更多知識與樂趣!