صفحة تستدعي API
جزء من قسم واجهات REST API في رحلة Node.js على Coddy. الدرس 21 من 25.
تستدعي صفحةٌ واجهة API باستخدام fetch. يحتاج طلب POST إلى ثلاثة خيارات: الطريقة والترويسات والنص الأساسي. حوّل كائن JavaScript إلى نص JSON لاستخدامه نصًا أساسيًا، وحدّد نوع ذلك النص بأنه application/json.
const response = await fetch('/api/books', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({title: title}),
});
const data = await response.json();يستقبل await الأول استجابة HTTP. ويقرأ الثاني نص JSON الأساسي فيها. يخبرك response.ok ما إذا كانت حالتها ضمن النطاق الناجح. لا تؤدي حالة مثل 400 أو 409 إلى رفض وعد fetch؛ بل تعطيك استجابة تكون فيها قيمة ok هي false. تم توفير شيفرة النموذج والقائمة؛ ركّز على إرسال الطلب والتعامل مع نتيجته.
يشير المتغير message المتوفر إلى فقرة الرسالة في الصفحة. عيّن له textContent لعرض نص، أو سلسلة فارغة لمسحها:
message.textContent = data.error.message;
// امسحه بعد النجاح:
message.textContent = '';تستخدم الصفحة وواجهة API المصدر نفسه، لذا لا يحتاج هذا الاستدعاء إلى إذن CORS. يشفّر FormData النموذج بطريقة تختلف عن JSON؛ استخدم نص JSON لأن واجهة API هذه تستخدم express.json().
التحدي
سهللا تحتوي واجهة API لديك على صفحة بعد. أضف إليها صفحة صغيرة يقدّمها الخادم نفسه، ويضيف نموذجها المهام من خلال واجهة API.
- في
server.js، قدّم المجلدpublicباستخدامexpress.static، بحيث يعيدGET /الملفpublic/index.html. - في
public/index.html، يستخرج مستمع الإرسال العنوانَ بالفعل. اجعله يرسل المهمة الجديدة إلى واجهة API:- استخدم المتغير
titleالمزوّد، والذي يحتوي على نص الإدخال. - أرسلها باستخدام
fetch('/api/tasks', ...)على هيئة POST. - يكون المحتوى نص JSON مُنشأ باستخدام
JSON.stringify، مثل{"title":"Water the plants"}. - يحتاج الطلب إلى الترويسة
'Content-Type': 'application/json'ضمن الخيارheadersالخاص بـfetch، وإلا فلن تتمكنexpress.json()من قراءة المحتوى.
- استخدم المتغير
- إذا كان الرد ناجحًا (تكون خاصية
okفيه true لأي حالة من 200 إلى 299)، فأفرغ النموذج باستخدامform.reset()، وأفرغ#message، واستدعِload()كي تعرض القائمة المهمة الجديدة. - وإلا، فسيكون محتوى الرد بالشكل الذي استخدمناه سابقًا للأخطاء، مثل:اعرض قيمة
{ "error": { "code": "conflict", "message": "A task with this title already exists" } }messageفي الفقرة#message.
تنفّذ الاختبارات نص الصفحة البرمجي المزوّد باستخدام نموذج مُحاكى صغير وواجهة API الحقيقية للدرس. وهي ترسل مهمة ومهمة مكررة، ثم تفحص القائمة والنموذج والرسالة. جرّب أيضًا الصفحة الفعلية بجانب المحرر.
جرّب ذلك: أرسل GET /. ستُفتح الصفحة في عرض الصفحة، وفيها المهام الثلاث الأولية. اكتب "Water the plants" واضغط Add: سيُفرغ حقل الإدخال وستظهر المهمة في أسفل القائمة. اكتب "Water the plants" مرة أخرى واضغط Add: ستبقى القائمة كما هي، وستظهر الرسالة "A task with this title already exists" أسفل النموذج.
جرّب بنفسك
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tasks</title>
</head>
<body>
<h1>Tasks</h1>
<ul id="list"></ul>
<form id="add">
<input name="title" placeholder="New task" required>
<button>Add</button>
</form>
<p id="message"></p>
<script>
const list = document.querySelector('#list');
const form = document.querySelector('#add');
const message = document.querySelector('#message');
async function load() {
const response = await fetch('/api/tasks?limit=50');
const page = await response.json();
list.replaceChildren(...page.items.map((task) => {
const item = document.createElement('li');
item.textContent = (task.done ? '[x] ' : '[ ] ') + task.title;
return item;
}));
}
form.addEventListener('submit', async (event) => {
event.preventDefault();
const title = form.elements.title.value;
// Send the title to POST /api/tasks as JSON. On success clear
// the form and load() again; on an error show its message.
});
load();
</script>
</body>
</html>
جميع دروس واجهات REST API
1الموارد والأفعال
الموارد وعناوين URLالإنشاء باستخدام POST4المتصفحات والإصدارات والإعدادات
ما هو المصدرالسماح لمصدر آخرCORSصفحة تستدعي APIتدرّب بنفسك: Playground لـ Express