Menu
CoddyTech

استجابات JSON

جزء من قسم أساسيات Express في رحلة Node.js على Coddy. الدرس 6 من 23.

يحتاج البرنامج الذي يستدعي خادمك إلى بيانات يمكنه قراءتها، لا إلى جملة.

app.get('/api/weather', (req, res) => {
    res.json({ city: 'Oslo', temp: 4, rain: true });
});

JSON هو تنسيق نصي للكائنات والمصفوفات. يحوّل res.json(value) القيمة إلى JSON ويضبط ترويسة Content-Type على application/json؛ والترويسة سطر ذو اسم يُرسَل مع الاستجابة، وهذا السطر يوضّح نوع المحتوى الذي يليه. يتلقى العميل {"city":"Oslo","temp":4,"rain":true} ويقرأ temp على أنه عدد.

يرسل res.send مع سلسلة نصية محتوى من النوع text/html، ما يضطر البرنامج إلى تحليله. تبدأ المسارات المخصّصة للبرامج عادةً بـ /api، ولذلك لا تشترك الصفحات والبيانات في المسار نفسه أبدًا.

challenge icon

التحدي

سهل

تحتاج البرامج، مثل تطبيق الهاتف، إلى بيانات Recipe Box بصيغة يمكنها قراءتها. أضف واجهة JSON بجانب الصفحات.

  1. في server.js، أضف مسارًا لـ /api/recipes. يرسل مصفوفة recipes كاملة بصيغة JSON.
  2. أضف مسارًا لـ /api/recipes/:id. يعثر على الوصفة بالطريقة نفسها التي يتبعها /recipes/:id، ويرسل كائن الوصفة كاملًا بصيغة JSON، وليس عنوانها فقط. بالنسبة إلى الوصفة 2، هذا هو الكائن الذي يحتوي على "id": 2 و"title": "Pancakes" و"tags": ["breakfast", "sweet"] وعدد حصصها.
  3. عندما لا توجد وصفة بهذا المعرّف، أعد الحالة 404. يمكنك إرسال النص No such recipe، كما تفعل الصفحة.

جرّب ذلك: اضغط على «تشغيل» وأرسل /api/recipes. ينبغي أن ترى قائمة بأربع وصفات، تبدأ بـ Tomato Soup. أرسل /api/recipes/2: كائن Pancakes. أرسل /api/recipes/99: الحالة 404. في علامة تبويب الترويسات، تكون قيمة Content-Type للمسار /api/recipes هي application/json. ثم أرسل /about: تكون قيمة Content-Type له هي text/html، لأن res.send يرسل صفحةً عند تمرير سلسلة نصية إليه.

جرّب بنفسك

import express from 'express';
import { recipes } from './data.js';

const app = express();

app.get('/', (req, res) => {
    res.send('Welcome to Recipe Box');
});

// ترسل type('text') نصًا عاديًا، لذا يظهر كل عنوان في سطر مستقل.
app.get('/recipes', (req, res) => {
    const { tag } = req.query;
    const list = tag ? recipes.filter((recipe) => recipe.tags.includes(tag)) : recipes;
    res.type('text').send(list.map((recipe) => recipe.title).join('\n'));
});

app.get('/recipes/:id', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).send('No such recipe');
        return;
    }
    res.send(recipe.title);
});

app.get('/about', (req, res) => {
    res.send('Recipe Box collects family recipes.');
});

app.listen(3000, () => {
    console.log('Recipe Box is running on port 3000');
});
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس أساسيات Express

تدرّب بنفسك: Playground لـ Express