Trong tình huống này, tôi luôn nghĩ đến giao diện trước, sau đó viết mã PHP để hỗ trợ nó.
- Đó là API REST, vì vậy các mã trạng thái HTTP có ý nghĩa là bắt buộc.
- Bạn muốn cấu trúc dữ liệu nhất quán, linh hoạt được gửi đến và từ máy khách.
Hãy nghĩ về tất cả những điều có thể sai và mã trạng thái HTTP của họ:
- Máy chủ đưa ra lỗi (500)
- Lỗi xác thực (401)
- Không tìm thấy tài nguyên yêu cầu (404)
- Dữ liệu bạn đang sửa đổi đã được thay đổi kể từ khi bạn tải nó (409)
- Lỗi xác thực khi lưu dữ liệu (422)
- Khách hàng đã vượt quá tỷ lệ yêu cầu của họ (429)
- Loại tệp không được hỗ trợ (415)
Lưu ý, có những cái khác mà bạn có thể nghiên cứu sau này.
Đối với hầu hết các điều kiện thất bại, chỉ có một thông báo lỗi được trả về. Các 422 Unprocessable Entity
phản ứng, mà tôi đã sử dụng cho "lỗi xác nhận" có thể trở lại nhiều hơn một lỗi --- Một hoặc nhiều lỗi mỗi lĩnh vực hình thức.
Chúng tôi cần một cấu trúc dữ liệu linh hoạt để phản hồi lỗi.
Hãy làm ví dụ, các 500 Internal Server Error
:
HTTP/1.1 500 Internal Server Error
Content-Type: text/json
Date: Fri, 16 Jan 2015 17:44:25 GMT
... other headers omitted ...
{
"errors": {
"general": [
"Something went catastrophically wrong on the server! BWOOP! BWOOP! BWOOP!"
]
}
}
Ngược lại với các lỗi xác nhận đơn giản khi cố gắng gửi một cái gì đó lên máy chủ:
HTTP/1.1 422 Unprocessable Entity
Content-Type: text/json
Date: Fri, 16 Jan 2015 17:44:25 GMT
... other headers omitted ...
{
"errors": {
"first_name": [
"is required"
],
"telephone": [
"should not exceed 12 characters",
"is not in the correct format"
]
}
}
Họ quan trọng ở đây là loại nội dung text/json
. Điều này cho các ứng dụng khách biết rằng họ có thể giải mã phần thân phản hồi bằng bộ giải mã JSON. Nếu, giả sử, lỗi máy chủ nội bộ không bị phát hiện và trang web "Đã xảy ra lỗi" chung chung của bạn được phân phối thay thế, loại nội dung phải text/html; charset=utf-8
để ứng dụng khách không cố giải mã nội dung phản hồi dưới dạng JSON.
Điều này có vẻ như tất cả đều được tìm thấy và cho đến khi bạn cần hỗ trợ các phản hồi JSONP . Bạn phải trả lại một 200 OK
phản hồi, ngay cả đối với những thất bại. Trong trường hợp này, bạn sẽ phải phát hiện ra rằng máy khách đang yêu cầu phản hồi JSONP (thường bằng cách phát hiện tham số yêu cầu URL được gọi callback
) và thay đổi cấu trúc dữ liệu một chút:
(NHẬN / bài viết / 123? Gọi lại = displayBlogPost)
<script type="text/javascript" src="/posts/123?callback=displayBlogPost"></script>
HTTP/1.1 200 OK
Content-Type: text/javascript
Date: Fri, 16 Jan 2015 17:44:25 GMT
... other headers omitted ...
displayBlogPost({
"status": 500,
"data": {
"errors": {
"general": [
"Something went catastrophically wrong on the server! BWOOP! BWOOP! BWOOP!"
]
}
}
});
Sau đó, trình xử lý phản hồi trên máy khách (trong trình duyệt web) phải có hàm JavaScript toàn cầu được gọi là displayBlogPost
chấp nhận một đối số duy nhất. Hàm này sẽ phải xác định xem phản hồi có thành công hay không:
function displayBlogPost(response) {
if (response.status == 500) {
alert(response.data.errors.general[0]);
}
}
Vì vậy, chúng tôi đã chăm sóc khách hàng. Bây giờ, hãy chăm sóc máy chủ.
<?php
class ResponseError
{
const STATUS_INTERNAL_SERVER_ERROR = 500;
const STATUS_UNPROCESSABLE_ENTITY = 422;
private $status;
private $messages;
public function ResponseError($status, $message = null)
{
$this->status = $status;
if (isset($message)) {
$this->messages = array(
'general' => array($message)
);
} else {
$this->messages = array();
}
}
public function addMessage($key, $message)
{
if (!isset($message)) {
$message = $key;
$key = 'general';
}
if (!isset($this->messages[$key])) {
$this->messages[$key] = array();
}
$this->messages[$key][] = $message;
}
public function getMessages()
{
return $this->messages;
}
public function getStatus()
{
return $this->status;
}
}
Và để sử dụng điều này trong trường hợp lỗi máy chủ:
try {
// some code that throws an exception
}
catch (Exception $ex) {
return new ResponseError(ResponseError::STATUS_INTERNAL_SERVER_ERROR, $ex->message);
}
Hoặc khi xác thực đầu vào của người dùng:
// Validate some input from the user, and it is invalid:
$response = new ResponseError(ResponseError::STATUS_UNPROCESSABLE_ENTITY);
$response->addMessage('first_name', 'is required');
$response->addMessage('telephone', 'should not exceed 12 characters');
$response->addMessage('telephone', 'is not in the correct format');
return $response;
Sau đó, bạn chỉ cần một cái gì đó lấy đối tượng phản hồi được trả về và chuyển đổi nó thành JSON và gửi phản hồi theo cách vui vẻ của nó.