Laravel 5.5 ApiResource 简单封装 (类似于 dingo-API 的响应)

一 封装 ApiHelper Trait

app/Http/Controllers/Traits/ApiHelper.php

<?php
/**
 * Api 接口封装
 */

namespace App\Http\Controllers\Traits;

use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Http\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;

trait ApiHelper
{
    /**
     * 响应创建的响应并关联位置(如果提供)。
     * Respond with a created response and associate a location if provided.
     *
     * @param null|string $location
     * @param null        $content
     * @return Response
     */
    public function created($location = null, $content = null)
    {
        $response = new Response($content);
        // 201
        $response->setStatusCode(Response::HTTP_CREATED);
        if (! is_null($location)) {
            $response->header('Location', $location);
        }

        return $response;
    }

    /**
     * 回应已接受的回复并关联位置和/或内容(如果提供)。
     * Respond with an accepted response and associate a location and/or content if provided.
     *
     * @param null|string $location
     * @param mixed       $content
     *
     * @return Response
     */
    public function accepted($location = null, $content = null)
    {
        $response = new Response($content);
        // 202
        $response->setStatusCode(Response::HTTP_ACCEPTED);

        if (! is_null($location)) {
            $response->header('Location', $location);
        }

        return $response;
    }

    /**
     * 回复无内容回复。
     * Respond with a no content response.
     *
     * @return Response
     */
    public function noContent()
    {
        $response = new Response(null);
        // 204
        return $response->setStatusCode(Response::HTTP_NO_CONTENT);
    }

    /**
     * 返回json响应。
     * Return a json response.
     * @param array $data
     * @param array $headers
     * @return Response
     */
    public function json($data = [], array $headers = [])
    {
        return new Response(compact('data'),Response::HTTP_OK,$headers);
    }

    /**
     * 将项目绑定到apiResource并开始构建响应。
     *  Bind an item to a apiResource and start building a response.
     * @param       $data
     * @param       $resourceClass
     * @param array $meta
     * @return mixed
     */
    public function item($data, $resourceClass, $meta = [])
    {
        if(is_null($data)){
            return compact('data');
        }
        if (count($meta)) {
            return (new $resourceClass($data))->additional($meta);
        }
        return new $resourceClass($data);
    }

    /**
     * 将集合绑定到apiResource并开始构建响应。
     * Bind a collection to a apiResource and start building a response.
     *
     * @param       $data
     * @param       $resourceClass
     * @param array $meta
     * @return Response
     */
    public function collection($data, $resourceClass, $meta = [])
    {
        if (count($meta)) {
            return $resourceClass::collection($data)->additional($meta);
        }
        return $resourceClass::collection($data);
    }

    /**
     * 将 paginator 绑定到 apiResource 并开始构建响应。
     * Bind a paginator to a apiResource and start building a response.
     *
     * @param Paginator $paginator
     * @param           $resourceClass
     * @param array     $meta
     * @return Response
     */
    public function paginator(Paginator $paginator, $resourceClass, array $meta = [])
    {
        return $this->collection($paginator,$resourceClass,$meta);
    }

    /**
     * 返回错误响应。
     * Return an error response.
     *
     * @param string $message
     * @param        $statusCode
     * @return void
     */
    public function error($message, $statusCode=400)
    {
        // return new Response(compact('message','status_code'),$status_code,$header);
        throw new HttpException($statusCode, $message);
    }

    /**
     * 返回404未找到错误。
     * Return a 404 not found error.
     *
     * @param string $message
     *
     * @throws \Symfony\Component\HttpKernel\Exception\HttpException
     *
     * @return void
     */
    public function errorNotFound($message = 'Not Found')
    {
        // 404
        $this->error($message, Response::HTTP_NOT_FOUND);
    }

    /**
     * 返回400错误请求错误。
     * Return a 400 bad request error.
     *
     * @param string $message
     *
     * @throws \Symfony\Component\HttpKernel\Exception\HttpException
     *
     * @return void
     */
    public function errorBadRequest($message = 'Bad Request')
    {
        // 400
        $this->error($message, Response::HTTP_BAD_REQUEST);
    }

    /**
     * 返回403禁止的错误。
     * Return a 403 forbidden error.
     *
     * @param string $message
     *
     * @throws \Symfony\Component\HttpKernel\Exception\HttpException
     *
     * @return void
     */
    public function errorForbidden($message = 'Forbidden')
    {
        // 403
        $this->error($message, Response::HTTP_FORBIDDEN);
    }

    /**
     * 返回500内部服务器错误。
     * Return a 500 internal server error.
     *
     * @param string $message
     *
     * @throws \Symfony\Component\HttpKernel\Exception\HttpException
     *
     * @return void
     */
    public function errorInternal($message = 'Internal Error')
    {
        // 500
        $this->error($message, Response::HTTP_INTERNAL_SERVER_ERROR);
    }

    /**
     * 返回401未经授权的错误。
     * Return a 401 unauthorized error.
     *
     * @param string $message
     *
     * @throws \Symfony\Component\HttpKernel\Exception\HttpException
     *
     * @return void
     */
    public function errorUnauthorized($message = 'Unauthorized')
    {
        // 401
        $this->error($message, Response::HTTP_UNAUTHORIZED);
    }

    /**
     * 返回405方法不允许错误。
     * Return a 405 method not allowed error.
     *
     * @param string $message
     *
     * @throws \Symfony\Component\HttpKernel\Exception\HttpException
     *
     * @return void
     */
    public function errorMethodNotAllowed($message = 'Method Not Allowed')
    {
        // 405
        $this->error($message, Response::HTTP_METHOD_NOT_ALLOWED);
    }
}

二 异常处理文件中 Handler.php render()方法添加 HttpException处理

app/Exceptions/Handler.php

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;

class Handler extends ExceptionHandler{
    .
    .
    .
    public function render($request, Exception $exception)
    {
        // 处理 api 异常
        if ($request->ajax() && $exception instanceof HttpException) {
            $message = $exception->getMessage();
            $status_code = $exception->getStatusCode();
            return new Response(compact('message','status_code'),$status_code);
        }

        return parent::render($request, $exception);
    }
}

三 控制器调用

1 引入 ApiHelper

app/Http/Controllers/Api/Controller.php

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Traits\ApiHelper;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as BaseController;

class Controller extends BaseController
{
    use ApiHelper;
}

2 ajax 响应

app/Http/Controllers/Api/AuthorizationsController.php

<?php

namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
# 一定要注意这个地方
use App\Http\Controllers\Api\Controller;
use Illuminate\Support\Facades\Auth;

class AuthorizationsController extends Controller
{
    // api 登录
    public function store(AuthorizationRequest $request)
    {
        ...

        return $this->errorUnauthorized('用户名或密码错误');
    }
}

四 如果你使用 PostMan 测试 Api 接口

增加 Headers

KEY VALUE DESCRIPTION
X-Requested-With XMLHttpRequest
讨论数量: 0

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!