ในสถานการณ์นี้ฉันมักจะนึกถึงอินเทอร์เฟซก่อนแล้วจึงเขียนโค้ด PHP เพื่อรองรับ
- เป็น REST API ดังนั้นจึงต้องมีรหัสสถานะ HTTP ที่มีความหมาย
- คุณต้องการให้โครงสร้างข้อมูลที่สอดคล้องและยืดหยุ่นถูกส่งไปและกลับจากไคลเอนต์
ลองนึกถึงทุกสิ่งที่อาจผิดและรหัสสถานะ HTTP:
- เซิร์ฟเวอร์ส่งข้อผิดพลาด (500)
- การตรวจสอบล้มเหลว (401)
- ไม่พบทรัพยากรที่ร้องขอ (404)
- ข้อมูลที่คุณกำลังแก้ไขมีการเปลี่ยนแปลงนับตั้งแต่คุณโหลด (409)
- ข้อผิดพลาดในการตรวจสอบความถูกต้องเมื่อบันทึกข้อมูล (422)
- ลูกค้าได้เกินอัตราการร้องขอของพวกเขา (429)
- ประเภทไฟล์ที่ไม่รองรับ (415)
หมายเหตุมีคนอื่นที่คุณสามารถค้นคว้าได้ในภายหลัง
สำหรับเงื่อนไขความล้มเหลวส่วนใหญ่จะมีข้อความข้อผิดพลาดเดียวที่จะส่งคืน การ422 Unprocessable Entity
ตอบสนองซึ่งฉันใช้สำหรับ "ข้อผิดพลาดในการตรวจสอบความถูกต้อง" อาจส่งคืนข้อผิดพลาดมากกว่าหนึ่งข้อ --- ข้อผิดพลาดอย่างน้อยหนึ่งข้อต่อแบบฟอร์มฟิลด์
เราต้องการโครงสร้างข้อมูลที่ยืดหยุ่นสำหรับการตอบสนองข้อผิดพลาด
ยกตัวอย่างเช่น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!"
]
}
}
ตรงกันข้ามที่มีข้อผิดพลาดการตรวจสอบง่ายเมื่อพยายาม POST บางสิ่งไปยังเซิร์ฟเวอร์:
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"
]
}
}
text/json
ที่สำคัญที่นี่พวกเขาเป็นชนิดที่เป็นเนื้อหา สิ่งนี้บอกแอปพลิเคชันไคลเอนต์ว่าสามารถถอดรหัสเนื้อความการตอบสนองด้วยตัวถอดรหัส JSON หากกล่าวว่าข้อผิดพลาดเซิร์ฟเวอร์ภายในไม่ถูกตรวจจับและมีการส่งมอบหน้าเว็บ "บางอย่างผิดปกติ" ของคุณแทนประเภทเนื้อหาควรเป็นtext/html; charset=utf-8
เช่นนั้นแอปพลิเคชันไคลเอนต์จะไม่พยายามถอดรหัสเนื้อหาการตอบสนองเป็น JSON
สิ่งนี้จะค้นหาและน่าสนใจทั้งหมดจนกว่าคุณจะต้องการสนับสนุนการตอบกลับJSONP คุณต้องส่งคืนการ200 OK
ตอบกลับแม้จะล้มเหลว ในกรณีนี้คุณจะต้องตรวจสอบว่าลูกค้าร้องขอการตอบสนอง JSONP (โดยปกติจะตรวจพบพารามิเตอร์คำขอ URL ที่เรียกว่าcallback
) และเปลี่ยนโครงสร้างข้อมูลเล็กน้อย:
(GET / posts / 123? callback = 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!"
]
}
}
});
จากนั้นตัวจัดการการตอบสนองบนไคลเอนต์ (ในเว็บเบราว์เซอร์) ควรมีฟังก์ชั่น JavaScript ทั่วโลกที่เรียกว่าdisplayBlogPost
ซึ่งยอมรับอาร์กิวเมนต์เดียว ฟังก์ชั่นนี้จะต้องพิจารณาว่าการตอบสนองนั้นประสบความสำเร็จหรือไม่:
function displayBlogPost(response) {
if (response.status == 500) {
alert(response.data.errors.general[0]);
}
}
ดังนั้นเราจึงดูแลลูกค้า ทีนี้มาดูแลเซิร์ฟเวอร์กันดีกว่า
<?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;
}
}
และเพื่อใช้สิ่งนี้ในกรณีที่เซิร์ฟเวอร์เกิดข้อผิดพลาด:
try {
// some code that throws an exception
}
catch (Exception $ex) {
return new ResponseError(ResponseError::STATUS_INTERNAL_SERVER_ERROR, $ex->message);
}
หรือเมื่อตรวจสอบการป้อนข้อมูลของผู้ใช้:
// 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;
หลังจากนั้นคุณเพียงต้องการบางสิ่งที่ใช้วัตถุตอบกลับที่ส่งคืนและแปลงเป็น JSON และส่งการตอบสนองด้วยวิธีที่สนุกสนาน