Custom response cho api laravel/lumen
TIL
720
Laravel
37
Lumen
4
White

Reishou viết ngày 22/04/2019

Tạo file trait App\Http\Response.php

<?php
namespace App\Http;

use Exception;

trait Response
{
    protected $data = [];

    protected $headers = [];

    protected $statusCode = 200;

    protected $errors;

    protected $message;

    protected $exception;

    public function addData(array $data)
    {
        foreach ($data as $key => $value) {
            $this->data[$key] = $value;
        }
    }

    public function setHeaders(array $headers)
    {
        foreach ($headers as $key => $value) {
            $this->headers[$key] = $value;
        }

        return $this;
    }

    public function setStatusCode(int $code)
    {
        $this->statusCode = $code;

        return $this;
    }

    public function addErrors(array $errors)
    {
        foreach ($errors as $key => $value) {
            $this->errors[$key] = $value;
        }

        return $this;
    }

    public function setMessage(string $message)
    {
        $this->message = $message;

        return $this;
    }

    public function setException(Exception $e)
    {
        $this->exception = $e;

        return $this;
    }
}

Tạo file App\Exceptions\CustomException.php

<?php
namespace App\Exceptions;

use Exception;

class CustomException extends Exception
{
    protected $code = 123;

    protected $message = 'INTERNAL_SERVER_CUSTOM_ERROR';

    protected $statusCode = 500;

    protected $privateMessage;

    public function __construct()
    {
        parent::__construct($this->message, $this->code);
    }

    public function getStatusCode()
    {
        return $this->statusCode;
    }

    public function setStatusCode(int $code)
    {
        $this->statusCode = $code;
    }

    public function getPrivateMessage()
    {
        return $this->privateMessage;
    }

    public function setPrivateMessage(string $message)
    {
        $this->privateMessage = $message;
    }
}

Thêm hàm getResponse() vào file App\Http\Response.php

public function getResponse()
{
    $data = [];

    if ($this->data) {
        $data['data'] = $this->data;
    }

    if ($this->errors || $this->exception) {
        $errorCode     = $this->exception->getCode() ?? $this->statusCode;
        $data['error'] = [
            'code'    => $errorCode ?: $this->statusCode,
            'message' => $this->message,
        ];
        if ($this->errors) {
            $data['error']['errors'] = $this->errors;
        }
    }

    if (env('APP_DEBUG') === true && $this->exception) {
        $data['debug'] = [
            'message' => $this->exception->getMessage(),
            'code'    => $this->exception->getCode(),
            'file'    => $this->exception->getFile(),
            'line'    => $this->exception->getLine(),
        ];
        if ($this->exception instanceof CustomException) {
            $data['debug']['message'] = $this->exception->getPrivateMessage();
        }
    }

    return response()->json($data, $this->statusCode, $this->headers);
}

Trường hợp trả về data

use App\Http\Response;
public function index(Request $request)
{
    $data = User::all();

    $this->addData($data);

    return $this->getResponse();
}

Để handle error, thêm vào function render() trong file App\Exceptions\Handle.php

public function render($request, Exception $exception)
{
    $this->setStatusCode(500)
        ->setMessage('INTERNAL_SERVER_ERROR')
        ->setException($exception);

    if ($exception instanceof CustomException) {
        $this->setStatusCode($exception->getStatusCode())
            ->setMessage($exception->getMessage());
    }

    return $this->getResponse();
}

Bây giờ ta hoàn toàn có thể throw exception bất kỳ chỗ nào muốn

$user = User::where('email', $email])->first();
if (!$user) {
    throw new UserNotFound($email);
}
<?php
namespace App\Exceptions;

class UserNotFound extends CustomException
{
    protected $code = 12345;

    protected $message = 'USER_NOT_FOUND';

    protected $statusCode = 404;

    public function __construct($email)
    {
        $this->setPrivateMessage("User with email $email has not found!");
        parent::__construct();
    }
}

Thay đổi $statusCode, $message tùy ý. $privateMessage chỉ hiển thị khi app đang bật debug.

{
    "error": {
        "code": 12345,
        "message": "USER_NOT_FOUND"
    },
    "debug": {
        "message": "User with email reishou@gmail.com has not found!",
        "code": 12345,
        "file": "/var/www/app/Http/Controllers/Controller.php",
        "line": 28
    }
}
Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Reishou

6 bài viết.
4 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
13 3
(Ảnh) Query filter là một vấn đề khá quen thuộc cho dù bạn code ngôn ngữ hay nền tảng nào. Các form search dữ liệu nâng cao với field, column cần f...
Reishou viết 3 tháng trước
13 3
White
1 2
Cài đặt môi trường lập trình web trên macOS khá thú vị. Có rất nhiều cách, nhiều hướng, nhiều stack cài đặt để lựa chọn. Nếu bạn muốn nhanh gọn thì...
Reishou viết 3 tháng trước
1 2
White
1 0
Với phần 1 và phần 2 thì các bạn có thể cài đặt hầu hết các dự án php thông thường. Tuy nhiên với các dự án hơi đặc thù lại cần một số php extensio...
Reishou viết 3 tháng trước
1 0
Bài viết liên quan
White
4 2
Bash script to fast serve Laravel project Lười gõ dòng lệnh quá nên tạo ra cái script để gõ nhanh :D laravelstart.sh /bin/bash if z "$1" ] ...
Vũ Hoàng Chung viết hơn 2 năm trước
4 2
White
0 0
1 Đặt vấn đề Chẳng hạn bây giờ bạn có 1 chuỗi các action diễn ra lần lượt và phụ thuộc vào nhau tạo accountgửi mail cho user, bạn sẽ viết code như...
Kaopiz Software Co., Ltd. viết 7 tháng trước
0 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
6 bài viết.
4 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!