COE 558Lecture 03المحاضرة 03Part 05الجزء 05
Designing REST APIs: the lamp system and the calculatorتصميم واجهات REST API: نظام المصباح والآلة الحاسبة
The five design elements applied end to end: the full smart-home lamp API with headers and JSON bodies, then the calculator addition API with status codes, and how to design the other operations yourself.عناصر التصميم الخمسة مطبقةً من البداية إلى النهاية: واجهة API الكاملة لمصباح المنزل الذكي مع الترويسات (headers) وأجسام JSON، ثم واجهة API للجمع في الآلة الحاسبة مع رموز الحالة (status codes)، وكيف تصمم بقية العمليات بنفسك.
- Conceptsالمفاهيم
- 5
- Slidesالشرائح
- 22-27
- Readingمدة القراءة
- 30 min30 دقيقة
Why this part mattersلماذا يهمّ هذا الجزء
The previous parts gave you the vocabulary: endpoints, methods, status codes, headers, JSON and the REST constraints. This part spends all of it on two complete designs. The first is a home lamp you control from a browser. The second is a calculator whose arithmetic runs on a server. Both end in a table, and that table is exactly what the midterm on 26 Oct 2026 is likely to ask you to fill in.
The order follows how you would design a real API. First, picture the system and the one resource it controls. Second, write the route table for that resource. Third, abstract the table into five design elements you can apply to anything. Fourth, apply them to the calculator, including every status code it can return. Fifth, design the remaining operations yourself. Along the way, every mistake or weak spot on the slides is flagged, so you can answer the exam in the slide's format and still know what a production API would do differently.
أعطتك الأجزاء السابقة المفردات: نقاط النهاية (endpoints)، والطرق (methods)، ورموز الحالة، والترويسات (headers)، وJSON، وقيود REST. هذا الجزء يستعمل كل ذلك في تصميمين كاملين. الأول مصباح منزلي تتحكم فيه من المتصفح. والثاني آلة حاسبة تُنفَّذ عملياتها الحسابية على خادم. كلاهما ينتهي بجدول، وهذا الجدول هو بالضبط ما يُرجَّح أن يطلب منك اختبار منتصف الفصل في 26 Oct 2026 تعبئته.
الترتيب يتبع الطريقة التي تصمم بها API حقيقيًا. أولًا، تخيّل النظام والمورد الوحيد الذي يتحكم فيه. ثانيًا، اكتب جدول المسارات (route table) لهذا المورد. ثالثًا، جرّد الجدول إلى خمسة عناصر تصميم يمكنك تطبيقها على أي شيء. رابعًا، طبّقها على الآلة الحاسبة، بما في ذلك كل رمز حالة يمكن أن تعيده. خامسًا، صمّم بقية العمليات بنفسك. وعلى طول الطريق، ننبّه إلى كل خطأ أو نقطة ضعف في الشرائح، حتى تجيب في الامتحان بصيغة الشريحة وتعرف مع ذلك ما الذي سيفعله API حقيقي في بيئة الإنتاج بشكل مختلف.
By the end you canفي نهاية هذا الجزء ستستطيع
- Trace one click in the lamp UI to an HTTP request, a server and a signal to device 123.تتبّع نقرة واحدة في واجهة المصباح حتى تصبح طلب HTTP يصل إلى الخادم ثم إشارة إلى الجهاز 123.
- Complete the lamp API table: what GET, DELETE, PUT and POST mean on /lamps and on /lamps/123, with the right JSON.أكمل جدول API المصباح: ماذا تعني GET وDELETE وPUT وPOST على /lamps وعلى /lamps/123، مع الـ JSON الصحيح.
- State the five REST design elements and what each one holds.اذكر عناصر تصميم REST الخمسة وما يحمله كل عنصر.
- Design a calculator operation in the slide's table format and pick the right status code for each failure.صمّم عملية في الآلة الحاسبة بصيغة جدول الشريحة، واختر رمز الحالة الصحيح لكل حالة فشل.
- Explain why the slide's GET with a JSON body is shaky, and give two correct alternatives.اشرح لماذا يُعد طلب GET مع جسم JSON في الشريحة تصميمًا مهزوزًا، واذكر بديلين صحيحين.
You are on the sofa with your phone. The browser shows a page at .../lamps/123 with an ON button, an OFF button and an intensity slider. You tap ON. A second later the lamp in the hallway lights up. What happened in between is the whole subject of this lecture in miniature.
أنت جالس على الأريكة وفي يدك هاتفك. يعرض المتصفح صفحة على .../lamps/123 فيها زر ON وزر OFF ومنزلق لشدة الإضاءة. تضغط ON. وبعد ثانية يضيء المصباح في الممر. ما حدث بين الضغطة والإضاءة هو موضوع هذه المحاضرة كله في صورة مصغّرة.
ON, OFF and an intensity slider on a page for lamp 123.
زر ON وزر OFF ومنزلق لشدة الإضاءة في صفحة المصباح 123.
Hosts the lamp API, checks the request, decides what to do.
يستضيف API المصباح، ويتحقق من الطلب، ويقرر ما يفعل.
Turns on, off, or changes brightness.
يشتغل أو ينطفئ أو يغيّر سطوعه.
Three components, two very different links. Between the browser and the Raspberry Pi the link is HTTP: the browser is an HTTP client, the Pi runs an HTTP server, and the tap becomes a request to an Endpoint. Between the Pi and the lamp the link is a device signal, a GPIO pin, a relay or a radio protocol, that the web never sees. The API is the HTTP side only. That is why the design problem is phrased in terms of URLs and methods and never mentions wires or voltages.
ثلاثة مكونات، ورابطان مختلفان تمامًا. بين المتصفح وRaspberry Pi الرابط هو HTTP: المتصفح هو HTTP client، والـ Pi يشغّل HTTP server، والضغطة تصبح طلبًا إلى endpoint. أما بين الـ Pi والمصباح فالرابط إشارة جهاز: منفذ GPIO، أو مُرحِّل (relay)، أو بروتوكول لاسلكي، ولا يراه الويب أبدًا. الـ API هو جانب HTTP فقط. ولهذا تُصاغ مسألة التصميم بلغة عناوين URL والطرق، ولا تذكر الأسلاك أو الجهد الكهربائي أبدًا.
The lamp is the Resource: the thing the server manages and exposes. The number 123 is its identity, and the URL that names it, /lamps/123, is its URI. Every operation the UI offers is a change to the lamp's state: whether it is on, how bright it is, whether it is enabled at all. So the design question becomes: which method on which URL changes which part of that state, and what does the data look like?
المصباح هو resource (المورد): الشيء الذي يديره الخادم ويعرضه. الرقم 123 هو هويته، والعنوان الذي يسمّيه، /lamps/123، هو URI الخاص به. كل عملية تقدمها الواجهة هي تغيير في حالة المصباح: هل هو مضاء، وما درجة سطوعه، وهل هو مفعَّل أصلًا. فيصبح سؤال التصميم: أي طريقة على أي URL تغيّر أي جزء من هذه الحالة، وكيف تبدو البيانات؟
Recall
Which link in the lamp system is the API, and which is not?أي رابط في نظام المصباح هو الـ API، وأيها ليس كذلك؟
The browser to server link is the API: HTTP requests to URLs such as /lamps/123. The server to lamp link is a device signal that the client never sees, so it is not part of the API design.
الرابط من المتصفح إلى الخادم هو الـ API: طلبات HTTP إلى عناوين مثل /lamps/123. أما الرابط من الخادم إلى المصباح فهو إشارة جهاز لا يراها العميل أبدًا، لذلك فهو ليس جزءًا من تصميم الـ API.
Start with one row. A GET request to http://myHome.com/lamps/123 returns {"id": 123, "Enabled": true, "ON": true, "brightness": 35}. Read the JSON as a sentence: lamp 123 is enabled, switched on, and at 35 percent brightness. That JSON is a Representation of the lamp's state, not the lamp itself.
ابدأ بصف واحد. طلب GET إلى http://myHome.com/lamps/123 يعيد {"id": 123, "Enabled": true, "ON": true, "brightness": 35}. اقرأ الـ JSON كجملة: المصباح 123 مفعَّل، ومضاء، وسطوعه 35 بالمئة. هذا الـ JSON هو representation (تمثيل) لحالة المصباح، وليس المصباح نفسه.
Now fill in the whole grid. The rows are the four methods. The columns are two URLs: the Collection endpoint /lamps, meaning all lamps, and the Item endpoint /lamps/123, meaning one lamp. Each cell says what that method does to that URL.
الآن املأ الشبكة كلها. الصفوف هي الطرق الأربع. والأعمدة عنوانان: collection endpoint /lamps ومعناها كل المصابيح، وitem endpoint /lamps/123 ومعناها مصباح واحد. كل خلية تقول ماذا تفعل تلك الطريقة بذلك العنوان.
| Methodالطريقة | /lamps/lamps | /lamps/123/lamps/123 | JSON objectكائن JSON |
|---|---|---|---|
| GETGET | List all lamps in the houseعرض قائمة بكل المصابيح في المنزل | Get information about lamp 123الحصول على معلومات المصباح 123 | Returned in the response: {"id": 123, "Enabled": true, "ON": true, "brightness": 35}يعود في الاستجابة: {"id": 123, "Enabled": true, "ON": true, "brightness": 35} |
| DELETEDELETE | Disable all lampsتعطيل كل المصابيح | Disable lamp 123تعطيل المصباح 123 | Sent in the response: {"id": 123, "Enabled": false}يُرسَل في الاستجابة: {"id": 123, "Enabled": false} |
| PUTPUT | Change brightness, turn on or off, or enable all lampsتغيير السطوع، أو التشغيل أو الإطفاء، أو تفعيل كل المصابيح | Change brightness, turn on or off, or enable lamp 123تغيير السطوع، أو التشغيل أو الإطفاء، أو تفعيل المصباح 123 | Sent in the request: {"id": 123, "Enabled": true, "ON": true, "brightness": 60}يُرسَل في الطلب: {"id": 123, "Enabled": true, "ON": true, "brightness": 60} |
| POSTPOST | Search for a newly installed lamp, assign it a unique ID, create its virtual resourceالبحث عن مصباح رُكِّب حديثًا، وإعطاؤه معرّفًا فريدًا (ID)، وإنشاء مورده الافتراضي | Not applicableغير قابل للتطبيق | Returned in the response: {"id": 123, "Enabled": true, "ON": false, "brightness": 0}يعود في الاستجابة: {"id": 123, "Enabled": true, "ON": false, "brightness": 0} |
Reading the table row by rowقراءة الجدول صفًا صفًا
- GET reads and never changes anything. On /lamps it lists every lamp; on /lamps/123 it returns one lamp's state.GET يقرأ ولا يغيّر أي شيء أبدًا. على /lamps يعرض قائمة بكل المصابيح، وعلى /lamps/123 يعيد حالة مصباح واحد.
- DELETE here means disable. The response {"id": 123, "Enabled": false} shows the lamp still exists, with its Enabled flag cleared. This is a soft delete: the record stays, so a PUT can enable the lamp again later. A physical lamp still screwed into the ceiling should not vanish from the system.DELETE هنا تعني التعطيل. الاستجابة {"id": 123, "Enabled": false} تُظهر أن المصباح ما زال موجودًا، مع إلغاء علامة Enabled. هذا حذف ناعم (soft delete): يبقى السجل، فيمكن لطلب PUT أن يعيد تفعيل المصباح لاحقًا. فالمصباح الحقيقي الذي ما زال مثبتًا في السقف لا ينبغي أن يختفي من النظام.
- PUT sends the full new state in the request: {"id": 123, "Enabled": true, "ON": true, "brightness": 60}. Compared with the GET above, only brightness changed, from 35 to 60. Sending every field is what makes PUT a replacement, and why it is Idempotent method: sending the same body twice leaves the lamp at 60 both times.PUT يرسل الحالة الجديدة كاملة في الطلب: {"id": 123, "Enabled": true, "ON": true, "brightness": 60}. مقارنةً بـ GET أعلاه، لم يتغير إلا السطوع، من 35 إلى 60. إرسال كل الحقول هو ما يجعل PUT عملية استبدال، ولهذا هو idempotent: إرسال الجسم نفسه مرتين يترك المصباح على 60 في المرتين.
- POST on /lamps asks the server to discover a newly installed lamp, assign it an ID and create its virtual resource. The response {"id": 123, "Enabled": true, "ON": false, "brightness": 0} carries the ID the server chose, and the new lamp starts off at zero brightness.POST على /lamps يطلب من الخادم أن يكتشف مصباحًا رُكِّب حديثًا، ويعطيه معرّفًا (ID)، وينشئ مورده الافتراضي. الاستجابة {"id": 123, "Enabled": true, "ON": false, "brightness": 0} تحمل المعرّف الذي اختاره الخادم، ويبدأ المصباح الجديد مطفأً بسطوع صفر.
- POST on /lamps/123 is not applicable. Creating something at an ID that already names an existing lamp is contradictory: the client cannot pick the ID, and lamp 123 already exists.POST على /lamps/123 غير قابل للتطبيق. إنشاء شيء عند معرّف يسمّي أصلًا مصباحًا موجودًا أمر متناقض: العميل لا يستطيع اختيار المعرّف، والمصباح 123 موجود بالفعل.
The Header fields column is the same for every row: a Cookie, an Authentication token and an Authorization token. They do not change the operation; they tell the server who is asking and whether they may. You would not want a neighbour on the same Wi-Fi to switch off your lamps.
عمود header fields هو نفسه في كل صف: Cookie، وauthentication token، وauthorization token. هذه لا تغيّر العملية، بل تخبر الخادم من الذي يطلب وهل يُسمح له. فأنت لا تريد أن يطفئ جارك المتصل بشبكة Wi-Fi نفسها مصابيحك.
Quick checkاختبار سريع
A homeowner installs a new lamp and wants the system to register it. Which route matches the slide's table?ركّب صاحب المنزل مصباحًا جديدًا ويريد أن يسجّله النظام. أي مسار يطابق جدول الشريحة؟
Recall
Which lamp JSON is sent in a request, and which come back in responses?أي JSON للمصباح يُرسَل في الطلب، وأيها يعود في الاستجابات؟
Only the PUT JSON is sent in the request (the new state, brightness 60). GET, DELETE and POST JSON come back in responses: the current state, the disabled state, and the newly created lamp with its assigned ID.
فقط JSON الخاص بـ PUT يُرسَل في الطلب (الحالة الجديدة، السطوع 60). أما JSON الخاص بـ GET وDELETE وPOST فيعود في الاستجابات: الحالة الحالية، والحالة المعطَّلة، والمصباح المنشأ حديثًا مع المعرّف الذي أُعطي له.
Take one cell of the lamp table, "change the brightness of lamp 123", and ask what a developer needs to implement it. Which URL? Which method? What comes back if it works or fails? What metadata travels with it? What does the data look like? Those five questions are the REST design elements.
خذ خلية واحدة من جدول المصباح، "تغيير سطوع المصباح 123"، واسأل ماذا يحتاج المطوّر لتنفيذها. أي URL؟ أي طريقة؟ ماذا يعود إذا نجحت أو فشلت؟ ما البيانات الوصفية التي ترافقها؟ كيف تبدو البيانات؟ هذه الأسئلة الخمسة هي REST design elements (عناصر تصميم REST).
| Elementالعنصر | What it holdsما يحمله | Lamp exampleمثال المصباح | Question it answersالسؤال الذي يجيب عنه |
|---|---|---|---|
| 1. URL1. URL | Domain name + pathاسم النطاق (domain) + المسار (path) | http://myHome.com/lamps/123http://myHome.com/lamps/123 | Which resource?أي مورد؟ |
| 2. HTTP request method2. طريقة طلب HTTP (request method) | GET, POST, PUT, DELETEGET, POST, PUT, DELETE | PUTPUT | What to do with it?ماذا نفعل به؟ |
| 3. HTTP response status code3. رمز حالة استجابة HTTP (status code) | 100 to 599من 100 إلى 599 | 200 OK200 OK | Did it work, and if not, whose fault?هل نجح الطلب، وإن لم ينجح فخطأ من؟ |
| 4. Header fields4. حقول الترويسة (header fields) | Metadata: cookies, tokens, Content-Typeبيانات وصفية: ملفات تعريف الارتباط (cookies)، والرموز (tokens)، وContent-Type | Content-Type: application/jsonContent-Type: application/json | What surrounds the message?ما الذي يحيط بالرسالة؟ |
| 5. JSON message5. رسالة JSON | Representation of a resource's state or requested changeتمثيل حالة المورد أو التغيير المطلوب فيه | {"id": 123, "Enabled": true, "ON": true, "brightness": 60}{"id": 123, "Enabled": true, "ON": true, "brightness": 60} | What is the data?ما البيانات؟ |
The URL names the resource: a domain name, which locates the server, plus a path, which locates the resource on it. The HTTP method names the operation. The Status code reports the outcome with a three-digit number. The header fields carry metadata about the message rather than the resource, such as cookies, tokens and Content-Type. The JSON message carries the resource representation itself: either its current state, in a response, or the change you want, in a request.
الـ URL يسمّي المورد: اسم نطاق (domain) يحدد مكان الخادم، ومسار (path) يحدد مكان المورد عليه. وHTTP method تسمّي العملية. وstatus code يبلّغ عن النتيجة برقم من ثلاث خانات. وحقول الترويسة تحمل بيانات وصفية عن الرسالة وليس عن المورد، مثل ملفات تعريف الارتباط (cookies) والرموز (tokens) وContent-Type. ورسالة JSON تحمل تمثيل المورد نفسه: إما حالته الحالية في الاستجابة، أو التغيير الذي تريده في الطلب.
Status codes: the first digit is the classرموز الحالة: الخانة الأولى هي الفئة
RFC 9110 states that all valid status codes lie between 100 and 599 inclusive, and that only the first digit carries a category. The last two digits pick a specific meaning inside the class. When you design an API, you are mostly choosing which 2xx, 4xx and 5xx codes it can return.
ينص RFC 9110 على أن كل رموز الحالة الصالحة تقع بين 100 و599 شاملةً، وأن الخانة الأولى وحدها تحمل الفئة. أما الخانتان الأخيرتان فتختاران معنى محددًا داخل الفئة. عندما تصمم API، فأنت في الغالب تختار أي رموز 2xx و4xx و5xx يمكن أن يعيدها.
| Classالفئة | Nameالاسم | Meaningالمعنى |
|---|---|---|
| 1xx1xx | Informationalمعلوماتية (Informational) | Request received, processing continuesاستُلم الطلب، والمعالجة مستمرة |
| 2xx2xx | Successfulناجحة (Successful) | Received, understood and acceptedاستُلم الطلب وفُهم وقُبل |
| 3xx3xx | Redirectionإعادة توجيه (Redirection) | The client must take further actionعلى العميل أن يتخذ إجراءً إضافيًا |
| 4xx4xx | Client errorخطأ العميل (Client error) | Bad syntax or cannot be fulfilled; the client should change the requestصياغة خاطئة أو لا يمكن تلبيته، وعلى العميل أن يغيّر الطلب |
| 5xx5xx | Server errorخطأ الخادم (Server error) | A valid request the server failed to fulfilطلب صالح فشل الخادم في تلبيته |
Recall
Name the five design elements and give a one-word role for each.اذكر عناصر التصميم الخمسة وأعطِ لكل منها دورًا بكلمة واحدة.
URL (where), HTTP request method (what action), HTTP response status code (outcome), header fields (metadata), JSON message (data, the resource representation).
URL (أين)، وHTTP request method (أي فعل)، وHTTP response status code (النتيجة)، وheader fields (بيانات وصفية)، وJSON message (البيانات، أي تمثيل المورد).
The second example is a web page titled "My Awesome Calculator!". It has a box for X, a box for Y, four radio buttons (addition, subtraction, multiplication, division) and a Submit button. The task: design a REST API for the addition operation, so that the sum is computed on the server, not in the browser.
المثال الثاني صفحة ويب عنوانها "My Awesome Calculator!". فيها خانة لـ X، وخانة لـ Y، وأربعة أزرار اختيار (جمع، طرح، ضرب، قسمة)، وزر Submit. المهمة: صمّم REST API لعملية الجمع، بحيث يُحسب المجموع على الخادم وليس في المتصفح.
Work through the five elements in order. The URL needs a domain and a path, so the slide picks http://calculator.com/add. Adding two numbers reads data and changes nothing, so the method is GET. The inputs travel as JSON, {"X": 1, "Y": 2}. The caller must be allowed to use the service, so the request carries an Authorization header. Finally, list the status codes that the server can return.
مرّ على العناصر الخمسة بالترتيب. الـ URL يحتاج نطاقًا ومسارًا، فتختار الشريحة http://calculator.com/add. جمع عددين يقرأ بيانات ولا يغيّر شيئًا، فالطريقة هي GET. المدخلات تنتقل بصيغة JSON، {"X": 1, "Y": 2}. يجب أن يكون المستدعي مسموحًا له باستخدام الخدمة، لذلك يحمل الطلب ترويسة Authorization. وأخيرًا، اذكر رموز الحالة التي يمكن أن يعيدها الخادم.
The calculator addition API, exactly as on slide 26API الجمع في الآلة الحاسبة، تمامًا كما في الشريحة 26
- URL
- http://calculator.com/addhttp://calculator.com/add
- HTTP request methodطريقة طلب HTTP
- GETGET
- HTTP response status codeرمز حالة استجابة HTTP
- 200 (successful), 400 (bad request), 406 (not acceptable), 500 (internal server error), 503 (service unavailable)200 (نجاح، successful)، و400 (طلب خاطئ، bad request)، و406 (غير مقبول، not acceptable)، و500 (خطأ داخلي في الخادم، internal server error)، و503 (الخدمة غير متاحة، service unavailable)
- Header fieldsحقول الترويسة
- AuthorizationAuthorization
- JSON messageرسالة JSON
- {"X": 1, "Y": 2}{"X": 1, "Y": 2}
On the server, the request is unpacked into a small environment: X = 1, Y = 2, op = Addition. The handler then runs Resp.send(X op Y) and the client receives 3. The browser never adds anything; it only sends inputs and displays an answer. This is the client-server split from Lecture 1: the computation lives behind the API.
على الخادم، يُفكّ الطلب إلى بيئة صغيرة: X = 1، Y = 2، op = Addition. ثم يشغّل المعالج Resp.send(X op Y) ويستقبل العميل 3. المتصفح لا يجمع أي شيء، بل يرسل المدخلات ويعرض الإجابة فقط. هذا هو الفصل بين العميل والخادم (client-server) من المحاضرة 1: الحساب يعيش خلف الـ API.
Each status code, with the request that triggers itكل رمز حالة مع الطلب الذي يسببه
A list of codes is easy to memorise and easy to confuse. Tie each to a concrete calculator request instead. The question to ask every time is: whose fault is it? A 4xx says the client must change the request. A 5xx says the request was fine and the server failed.
قائمة الرموز سهلة الحفظ وسهلة الخلط. لذلك اربط كل رمز بطلب محدد للآلة الحاسبة. والسؤال الذي تطرحه كل مرة: خطأ من هذا؟ الرمز 4xx يقول إن على العميل أن يغيّر الطلب. والرمز 5xx يقول إن الطلب كان سليمًا والخادم هو الذي فشل.
| Codeالرمز | RFC 9110 meaningالمعنى في RFC 9110 | Calculator triggerما يسببه في الآلة الحاسبة | Whose faultخطأ من |
|---|---|---|---|
| 200 OK200 OK | The request succeededنجح الطلب | X = 1, Y = 2, server healthy, result 3X = 1، Y = 2، الخادم سليم، والنتيجة 3 | Nobodyلا أحد |
| 400 Bad Request400 Bad Request | The server will not process it because of a client errorلن يعالجه الخادم بسبب خطأ من العميل | X is missing, or X is "abc"X مفقود، أو قيمة X هي "abc" | Clientالعميل |
| 406 Not Acceptable406 Not Acceptable | No representation matches the client's Accept headers, and the server will not send a defaultلا يوجد تمثيل يطابق ترويسات Accept لدى العميل، والخادم لن يرسل صيغة افتراضية | Accept: application/xml to a JSON-only calculatorAccept: application/xml إلى آلة حاسبة لا تعيد إلا JSON | Clientالعميل |
| 500 Internal Server Error500 Internal Server Error | An unexpected condition on the serverحالة غير متوقعة على الخادم | An exception in the addition code, a null reference, a failed database callاستثناء (exception) في كود الجمع، أو مرجع فارغ (null reference)، أو فشل استدعاء قاعدة البيانات | Serverالخادم |
| 503 Service Unavailable503 Service Unavailable | Temporary overload or maintenance; may carry Retry-Afterحمل زائد مؤقت أو صيانة، وقد يحمل ترويسة Retry-After | Too many requests at once, or the server is being upgradedطلبات كثيرة جدًا في وقت واحد، أو الخادم قيد الترقية | Serverالخادم |
406 is the subtle one. It is about the response format. The client's Accept header lists the media types it can read. If the client says it will only take application/xml and the calculator only speaks JSON, the server cannot produce an acceptable answer. MDN notes that sending a default format with 200 may be preferable to a 406, so using it is a design choice: strict servers use it, lenient ones ignore the mismatch.
الرمز 406 هو الأدق. إنه يتعلق بصيغة الاستجابة. ترويسة Accept لدى العميل تسرد أنواع الوسائط (media types) التي يستطيع قراءتها. إذا قال العميل إنه لن يقبل إلا application/xml والآلة الحاسبة لا تتكلم إلا JSON، فلا يستطيع الخادم إنتاج إجابة مقبولة. وتشير MDN إلى أن إرسال صيغة افتراضية مع 200 قد يكون أفضل من 406، فاستخدامه قرار تصميمي: الخوادم الصارمة تستخدمه، والمتساهلة تتجاهل عدم التطابق.
Why the slide's GET with a body is shakyلماذا يُعد GET مع جسم في الشريحة تصميمًا مهزوزًا
The slide pairs GET with a JSON body. RFC 9110 is explicit that content received in a GET request has no generally defined semantics, cannot change the meaning of the request, and may cause some implementations to reject the request. A client should not send one unless the origin server has said it will support it. In practice, the browser's fetch throws an error if you give a GET request a body, and caches key stored responses on the method and URL, never the body, so two different sums sent to the same URL could collide in a cache.
تجمع الشريحة بين GET وجسم JSON. يصرّح RFC 9110 بأن المحتوى المستلَم في طلب GET ليس له دلالة معرّفة بشكل عام، ولا يمكنه تغيير معنى الطلب، وقد يجعل بعض التطبيقات ترفض الطلب. ولا ينبغي للعميل أن يرسله ما لم يعلن الخادم الأصلي أنه يدعمه. وعمليًا، دالة fetch في المتصفح ترمي خطأ إذا أعطيت طلب GET جسمًا، والذاكرات المؤقتة (caches) تفهرس الاستجابات المخزنة حسب الطريقة والـ URL وليس حسب الجسم أبدًا، لذلك قد يتصادم مجموعان مختلفان أُرسلا إلى الـ URL نفسه داخل الذاكرة المؤقتة.
| Designالتصميم | Requestالطلب | Strengthنقطة القوة | Weaknessنقطة الضعف |
|---|---|---|---|
| Slide designتصميم الشريحة | GET /add with body {"X": 1, "Y": 2}GET /add مع الجسم {"X": 1, "Y": 2} | Matches the exam tableيطابق جدول الامتحان | Body has no defined meaning for GET; proxies and libraries may drop or reject itالجسم ليس له معنى محدد مع GET، وقد تُسقطه الوسائط (proxies) والمكتبات أو ترفضه |
| GET with a query stringGET مع سلسلة استعلام (query string) | GET /add?x=1&y=2GET /add?x=1&y=2 | Safe, cacheable, bookmarkable; inputs are part of the URLآمن، وقابل للتخزين المؤقت، ويمكن حفظه كإشارة مرجعية (bookmark)، والمدخلات جزء من الـ URL | Inputs visible in logs and history; URL length limits for large inputsالمدخلات ظاهرة في السجلات (logs) وسجل التصفح، وحدود طول الـ URL تقيّد المدخلات الكبيرة |
| POST with a JSON bodyPOST مع جسم JSON | POST /add with body {"X": 1, "Y": 2}POST /add مع الجسم {"X": 1, "Y": 2} | Body has a defined meaning; handles large or structured inputsللجسم معنى محدد، ويتعامل مع المدخلات الكبيرة أو المنظَّمة | Not cached by default; POST signals possible side effects that addition does not haveلا يُخزَّن مؤقتًا افتراضيًا، وPOST يوحي بآثار جانبية محتملة ليست موجودة في عملية الجمع |
Try every case in the builder. Start with the slide's design and the answer 3. Switch Accept to XML and watch the 406. Clear X, or type abc, for a 400. Mark the server as buggy or overloaded for 500 and 503. Then switch to GET with a query string and to POST and see how the request line and headers change while the five elements stay the same.
جرّب كل حالة في أداة البناء. ابدأ بتصميم الشريحة والإجابة 3. غيّر Accept إلى XML وشاهد 406. امسح X، أو اكتب abc، لتحصل على 400. اجعل الخادم معطوبًا أو محمّلًا فوق طاقته لتحصل على 500 و503. ثم انتقل إلى GET مع سلسلة استعلام وإلى POST، وشاهد كيف يتغير سطر الطلب والترويسات بينما تبقى العناصر الخمسة كما هي.
GET /add HTTP/1.1
Host: calculator.com
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.demo
Content-Type: application/json
Content-Length: 13
{"X":1,"Y":2}HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 12
{"result":3}The server builds the environment X = 1, Y = 2, op = Addition, computes 1 + 2 = 3, and returns it as JSON with 200.يبني الخادم البيئة X = 1, Y = 2, op = Addition، ويحسب 1 + 2 = 3، ثم يعيد الناتج بصيغة JSON مع الرمز 200.
This is the slide's design. RFC 9110 says content in a GET request has no generally defined semantics, and some proxies or client libraries drop or reject it, so the server may never see X and Y.هذا هو تصميم الشريحة. يقول RFC 9110 إن المحتوى في طلب GET ليس له معنى معرّف بشكل عام، وبعض الخوادم الوسيطة (proxies) أو مكتبات العميل تحذفه أو ترفضه، فقد لا يرى الخادم X وY أبدًا.
Quick checkاختبار سريع
A client sends Accept: application/xml to the calculator, which only produces JSON. Which response fits?يرسل عميل Accept: application/xml إلى الآلة الحاسبة التي لا تنتج إلا JSON. أي استجابة تناسب؟
Quick checkاختبار سريع
Why is the slide's GET request with a JSON body a shaky design?لماذا يُعد طلب GET مع جسم JSON في الشريحة تصميمًا مهزوزًا؟
Recall
Give a calculator request that triggers each of 400, 406, 500 and 503.أعطِ طلبًا للآلة الحاسبة يسبب كلًا من 400 و406 و500 و503.
400: X missing or "abc". 406: Accept: application/xml to a JSON-only server. 500: a bug in the server's addition code. 503: the server is overloaded or in maintenance, possibly with a Retry-After header.
400: X مفقود أو قيمته "abc". 406: Accept: application/xml إلى خادم لا يعيد إلا JSON. 500: خلل في كود الجمع على الخادم. 503: الخادم محمّل فوق طاقته أو في صيانة، وربما مع ترويسة Retry-After.
The slide designs addition and stops. The natural exam follow-up is: design the same API for subtraction, multiplication or division. The good news is that four of the five elements barely change. The path names the new operation, and the JSON carries new numbers. Division adds one new failure case.
تصمم الشريحة عملية الجمع وتتوقف. والسؤال الطبيعي التالي في الامتحان: صمّم الـ API نفسه للطرح أو الضرب أو القسمة. والخبر الجيد أن أربعة من العناصر الخمسة بالكاد تتغير. المسار يسمّي العملية الجديدة، والـ JSON يحمل أعدادًا جديدة. والقسمة تضيف حالة فشل جديدة واحدة.
Worked exampleمثال محلول
Designing the division APIتصميم API القسمة
URLالـ URL
Same domain, new path: http://calculator.com/divide. With a query string the full request target is /divide?x=6&y=3.
النطاق نفسه ومسار جديد: http://calculator.com/divide. ومع سلسلة استعلام يصبح هدف الطلب الكامل /divide?x=6&y=3.
Methodالطريقة
Division reads inputs and changes no server state, so GET, exactly as for addition. With inputs in the query string, GET is also safe and cacheable.
القسمة تقرأ مدخلات ولا تغيّر أي حالة على الخادم، لذلك GET، تمامًا كما في الجمع. ومع وضع المدخلات في سلسلة الاستعلام، يصبح GET أيضًا آمنًا وقابلًا للتخزين المؤقت.
Compute the success caseاحسب حالة النجاح
X = 6, Y = 3, op = Division, so 6 ÷ 3 = 2. The server replies 200 OK with {"result": 2}.
X = 6، Y = 3، op = Division، إذن 6 ÷ 3 = 2. يرد الخادم بـ 200 OK مع {"result": 2}.
Find the new failureجد حالة الفشل الجديدة
GET /divide?x=6&y=0 is well formed, but 6 ÷ 0 has no value. The fault lies in the client's input, so the server returns 400 Bad Request with {"error": "Division by zero is undefined"}, never 500.
GET /divide?x=6&y=0 طلب سليم البنية، لكن 6 ÷ 0 ليس له قيمة. الخطأ في مدخلات العميل، لذلك يعيد الخادم 400 Bad Request مع {"error": "Division by zero is undefined"}، وليس 500 أبدًا.
Headers and the rest of the codesالترويسات وبقية الرموز
Authorization for access, Accept: application/json for the response format. The codes 406, 500 and 503 keep the same triggers as for addition.
Authorization للوصول، وAccept: application/json لصيغة الاستجابة. والرموز 406 و500 و503 تبقى بأسبابها نفسها كما في الجمع.
Resultالنتيجة
Division is addition's design with path /divide, plus one extra 400 trigger: Y = 0.القسمة هي تصميم الجمع مع المسار /divide، بالإضافة إلى سبب إضافي واحد لـ 400: Y = 0.
Division API in the slide's table format, query string versionAPI القسمة بصيغة جدول الشريحة، نسخة سلسلة الاستعلام (query string)
- URL
- http://calculator.com/divide?x=6&y=3http://calculator.com/divide?x=6&y=3
- HTTP request methodطريقة طلب HTTP
- GETGET
- HTTP response status codeرمز حالة استجابة HTTP
- 200, 400 (missing or non-numeric input, or y = 0), 406, 500, 503200، و400 (مدخلات مفقودة أو غير رقمية، أو y = 0)، و406، و500، و503
- Header fieldsحقول الترويسة
- Authorization, Accept: application/jsonAuthorization, Accept: application/json
- JSON messageرسالة JSON
- Response {"result": 2}, or {"error": "Division by zero is undefined"}الاستجابة {"result": 2}، أو {"error": "Division by zero is undefined"}
| Operationالعملية | URLURL | Methodالطريقة | Status codesرموز الحالة | Header fieldsحقول الترويسة | JSON messageرسالة JSON | Resultالنتيجة |
|---|---|---|---|---|---|---|
| Addition (slide)الجمع (الشريحة) | http://calculator.com/addhttp://calculator.com/add | GETGET | 200, 400, 406, 500, 503200, 400, 406, 500, 503 | AuthorizationAuthorization | {"X": 1, "Y": 2}{"X": 1, "Y": 2} | 1 + 2 = 31 + 2 = 3 |
| Subtractionالطرح | http://calculator.com/subtracthttp://calculator.com/subtract | GETGET | 200, 400, 406, 500, 503200, 400, 406, 500, 503 | AuthorizationAuthorization | {"X": 5, "Y": 2}{"X": 5, "Y": 2} | 5 - 2 = 35 - 2 = 3 |
| Multiplicationالضرب | http://calculator.com/multiplyhttp://calculator.com/multiply | GETGET | 200, 400, 406, 500, 503200, 400, 406, 500, 503 | AuthorizationAuthorization | {"X": 4, "Y": 3}{"X": 4, "Y": 3} | 4 × 3 = 124 × 3 = 12 |
| Divisionالقسمة | http://calculator.com/dividehttp://calculator.com/divide | GETGET | 200, 400 (also Y = 0), 406, 500, 503200، 400 (وأيضًا Y = 0)، 406، 500، 503 | AuthorizationAuthorization | {"X": 6, "Y": 3}{"X": 6, "Y": 3} | 6 ÷ 3 = 26 ÷ 3 = 2 |
The slide closes with references. The deck cites Henry Cocos's Cloud Computing lecture series (summer term 2025), four cloud textbooks and uptime.is, an availability calculator from Lecture 2 that this lecture does not use. They appear under Sources below, next to the standards that back the status code and GET claims in this part.
تُختَم الشريحة بالمراجع. يستشهد العرض بسلسلة محاضرات Cloud Computing لـ Henry Cocos (الفصل الصيفي 2025)، وأربعة كتب في الحوسبة السحابية، وuptime.is، وهي حاسبة توافر (availability) من المحاضرة 2 لا تستخدمها هذه المحاضرة. تظهر كلها تحت المصادر أدناه، بجانب المعايير التي تدعم ادعاءات رموز الحالة وGET في هذا الجزء.
Recall
Design the multiplication API in the slide's format for X = 4, Y = 3.صمّم API الضرب بصيغة الشريحة لـ X = 4 وY = 3.
URL http://calculator.com/multiply; method GET; status codes 200, 400, 406, 500, 503; header Authorization; JSON {"X": 4, "Y": 3}. The server computes 4 × 3 = 12 and returns it with 200.
URL هو http://calculator.com/multiply، والطريقة GET، ورموز الحالة 200 و400 و406 و500 و503، والترويسة Authorization، والـ JSON هو {"X": 4, "Y": 3}. يحسب الخادم 4 × 3 = 12 ويعيده مع 200.
Recapالخلاصة
If you remember nothing elseإن لم تتذكر شيئاً آخر فتذكّر هذا
- The lamp system: browser UI, HTTP request, server (a Raspberry Pi), signal to the lamp with ID 123.نظام المصباح: واجهة المتصفح، ثم طلب HTTP، ثم الخادم (Raspberry Pi)، ثم إشارة إلى المصباح ذي المعرّف 123.
- /lamps is the collection, /lamps/123 one item. POST creates on the collection only; POST on /lamps/123 is not applicable./lamps هي المجموعة و/lamps/123 عنصر واحد. POST ينشئ على المجموعة فقط، أما POST على /lamps/123 فغير قابل للتطبيق.
- DELETE disables the lamp (Enabled: false) instead of erasing it: a soft delete. PUT sends the full new state.DELETE يعطّل المصباح (Enabled: false) بدل محوه: حذف ناعم (soft delete). أما PUT فيرسل الحالة الجديدة كاملة.
- Five design elements: URL (domain + path), method, status code (100 to 599), header fields (metadata), JSON message (representation).عناصر التصميم الخمسة: URL (النطاق + المسار)، والطريقة (method)، ورمز الحالة (من 100 إلى 599)، وحقول الترويسة (بيانات وصفية)، ورسالة JSON (التمثيل).
- Calculator: http://calculator.com/add, GET, codes 200, 400, 406, 500, 503, Authorization header, JSON {"X": 1, "Y": 2}, result 3.الآلة الحاسبة: http://calculator.com/add، وGET، والرموز 200 و400 و406 و500 و503، وترويسة Authorization، وJSON {"X": 1, "Y": 2}، والنتيجة 3.
- 4xx means the client is at fault (400 bad input, 406 unproducible format). 5xx means the server is (500 bug, 503 overloaded).4xx تعني أن الخطأ من العميل (400 مدخلات خاطئة، 406 صيغة لا يمكن إنتاجها). 5xx تعني أن الخطأ من الخادم (500 خلل برمجي، 503 حمل زائد).
- GET with a body has no defined meaning (RFC 9110). Use GET /add?x=1&y=2 or POST /add with the JSON body.GET مع جسم ليس له معنى محدد (RFC 9110). استخدم GET /add?x=1&y=2 أو POST /add مع جسم JSON.
Sourcesالمصادر
- RFC 9110: HTTP SemanticsRFCIETFSection 9.3.1 (content in a GET request has no generally defined semantics), section 15 (status codes 100 to 599 and their classes), 15.5.1 (400), 15.5.7 (406), 15.6.1 (500), 15.6.4 (503 and Retry-After), 15.5.2 and 15.5.4 (401 and 403), 11.6.2 (Authorization header).القسم 9.3.1 (المحتوى في طلب GET ليس له دلالة معرّفة بشكل عام)، والقسم 15 (رموز الحالة من 100 إلى 599 وفئاتها)، و15.5.1 (400)، و15.5.7 (406)، و15.6.1 (500)، و15.6.4 (503 وRetry-After)، و15.5.2 و15.5.4 (401 و403)، و11.6.2 (ترويسة Authorization).(opens in a new tab)(يفتح في تبويب جديد)
- RFC 8259: The JavaScript Object Notation (JSON) Data Interchange FormatRFCIETFObject names are strings, should be unique, and are compared code unit by code unit.أسماء الكائنات سلاسل نصية، وينبغي أن تكون فريدة، وتُقارَن وحدةً ترميزيةً بوحدة.(opens in a new tab)(يفتح في تبويب جديد)
- 406 Not AcceptableDocsMDN Web DocsAccept, Accept-Encoding and Accept-Language as triggers; a default response with 200 may be preferable to 406.Accept وAccept-Encoding وAccept-Language بوصفها مسببات، وقد يكون إرسال استجابة افتراضية مع 200 أفضل من 406.(opens in a new tab)(يفتح في تبويب جديد)
- RFC 9111: HTTP CachingRFCIETFSection 2: the cache key is built from the request method and target URI (refined by Vary), not from the request body.القسم 2: مفتاح الذاكرة المؤقتة (cache key) يُبنى من طريقة الطلب وURI الهدف (ويُنقَّح بـ Vary)، وليس من جسم الطلب.(opens in a new tab)(يفتح في تبويب جديد)
- Fetch Standard: the Request constructorDocsWHATWGThrows a TypeError when a GET or HEAD request is given a non-null body.يرمي TypeError عندما يُعطى طلب GET أو HEAD جسمًا غير فارغ (non-null).(opens in a new tab)(يفتح في تبويب جديد)
- Web API design best practicesDocsMicrosoft Azure Architecture CenterNouns rather than verbs in URIs, plural collections such as /orders and /orders/1, POST to the collection, 406 when no Accept type matches.أسماء بدل الأفعال في عناوين URI، ومجموعات بصيغة الجمع مثل /orders و/orders/1، وPOST إلى المجموعة، و406 عندما لا يطابق أي نوع في Accept.(opens in a new tab)(يفتح في تبويب جديد)
- AIP-136: Custom methodsDocsGoogle API Improvement ProposalsHow resource-oriented APIs express actions such as calculations: a colon verb, GET for read-only methods, POST otherwise.كيف تعبّر الواجهات الموجّهة نحو الموارد عن أفعال مثل العمليات الحسابية: فعل بعد نقطتين (colon verb)، وGET للطرق التي تقرأ فقط، وPOST لغيرها.(opens in a new tab)(يفتح في تبويب جديد)
- Cloud Computing, summer term 2025 (Henry Cocos)Articlehenrycocos.deCourse page of the lecture series cited on slide 27.صفحة المقرر لسلسلة المحاضرات المستشهد بها في الشريحة 27.(opens in a new tab)(يفتح في تبويب جديد)
- Cloud Computing: Theory and Practice, 3rd edition (Marinescu)BookMorgan Kaufmann, 2022Slide 27 reference.مرجع من الشريحة 27.(opens in a new tab)(يفتح في تبويب جديد)
- Cloud Computing, revised and updated edition (Ruparelia)BookMIT Press, 2023Slide 27 reference, MIT Press Essential Knowledge series.مرجع من الشريحة 27، ضمن سلسلة MIT Press Essential Knowledge.(opens in a new tab)(يفتح في تبويب جديد)
- Cloud Computing: Principles, Systems and Applications (Antonopoulos and Gillam, eds.)BookSpringer, 2010Slide 27 reference.مرجع من الشريحة 27.(opens in a new tab)(يفتح في تبويب جديد)
- The Cloud Computing Book: The Future of Computing Explained (Comer)BookChapman and Hall/CRC, 2021Slide 27 reference.مرجع من الشريحة 27.(opens in a new tab)(يفتح في تبويب جديد)
- uptime.is: SLA and uptime calculatorDocsuptime.isListed on slide 27; an availability calculator used in Lecture 2, not in this lecture.مذكور في الشريحة 27، وهو حاسبة توافر (availability) استُخدمت في المحاضرة 2، وليس في هذه المحاضرة.(opens in a new tab)(يفتح في تبويب جديد)