Module 11: APIs
Course: Programming with Free AI Tools — Build Real Websites and Apps | Module: 11 of 17 | Audience: Ages 15–25, beginners | Focus: REST basics, HTTP verbs, consuming APIs with JavaScript fetch, and building a simple API with PHP.
Core principle: Always verify AI-generated code. Run it, read the output, and understand what each line does before trusting it.
Lesson 11.1: What is an API and REST Basics
Duration: 45 minutes
Learning Objectives
- Define what an API is and why applications use them.
- Explain the REST architectural style in simple terms.
- Identify the four main HTTP verbs: GET, POST, PUT, DELETE.
- Read a basic JSON response and understand its structure.
- Describe status codes (200, 201, 404, 500) and what they mean.
Instructor Notes
Use a real-world analogy: an API is like a restaurant waiter — you (client) give an order, the kitchen (server) prepares it, and the waiter returns the food (response). Open a public API like https://jsonplaceholder.typicode.com/posts in the browser to show raw JSON.
Emphasize that REST is a convention, not a strict rule. Many APIs follow it loosely. Warn students: never hard-code secret API keys in client-side JavaScript that goes to the browser.
Presentation Outline
- What is an API? (5 min)
- Client–server model and request/response (10 min)
- REST concepts: resources, URLs, statelessness (10 min)
- HTTP verbs table: GET / POST / PUT / DELETE (10 min)
- JSON and HTTP status codes (10 min)
Demonstration
- Open
https://jsonplaceholder.typicode.com/posts/1 in the browser.
- Show the JSON object and point out the keys (
userId, id, title, body).
- Open DevTools → Network tab and reload to show the request method (GET) and status (200).
- Demonstrate a 404 by visiting
/posts/99999 style broken endpoint.
- Summarize: the browser sent GET, the server replied 200 with JSON.
AI Prompts
"Explain REST API to a 16-year-old using a simple real-world analogy. Include GET, POST, PUT, DELETE with one example each."
"Give me a table of common HTTP status codes (200, 201, 400, 401, 403, 404, 500) with what they mean for an API beginner."
Starter Code
{
"message": "This is what a JSON API response looks like.",
"lesson": 11.1,
"items": ["GET", "POST", "PUT", "DELETE"]
}
Final Code
GET https://jsonplaceholder.typicode.com/posts/1
HTTP/1.1 200 OK
Content-Type: application/json
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati",
"body": "quia et suscipit suscipit recusandae"
}
Exercises
- Visit three different REST API endpoints and write down their status codes.
- Draw a diagram showing a client, an API, and a database, with arrows for request and response.
- List which HTTP verb you would use for: reading a user, creating a user, updating a user, deleting a user.
Homework
- Find one free public API (e.g., weather, cat facts, countries) and write a one-paragraph explanation of what it returns.
- Create a table of 5 endpoints from that API with their HTTP method and a sample response field.
Quiz
- What does API stand for?
- a) Application Programming Interface ✅
- b) Automated Process Integration
- c) Applied Program Instruction
- d) Array Pointer Index
- Which HTTP verb is used to request data from a server?
- a) POST
- b) PUT
- c) GET ✅
- d) DELETE
- Which HTTP verb is typically used to create a new resource?
- a) GET
- b) POST ✅
- c) DELETE
- d) PATCH-less PUT
- What does an HTTP status code of 404 mean?
- a) Server error
- b) Resource not found ✅
- c) Success
- d) Unauthorized
- What format do most modern web APIs use to send data?
- a) XML only
- b) CSV
- c) JSON ✅
- d) Plain text
Lesson 11.2: Consuming APIs with JavaScript fetch
Duration: 60 minutes
Learning Objectives
- Use the
fetch() function to call a remote API.
- Handle promises with
.then() and with async/await.
- Parse JSON responses with
.json().
- Display API data in the DOM.
- Handle errors gracefully with
try/catch and .catch().
Instructor Notes
Start with the older .then() syntax, then show the cleaner async/await version. Stress that fetch does NOT throw on HTTP errors (like 404) — you must check response.ok. Show how to render a list of items using map() and innerHTML or createElement.
Remind students to verify the response shape before accessing properties (avoid undefined crashes).
Presentation Outline
- Recap JSON and endpoints (5 min)
- Introducing
fetch() (10 min)
.then() promise chain (15 min)
async/await + try/catch (15 min)
- Rendering data into HTML (15 min)
Demonstration
- Create
index.html with a <ul id="posts">.
- Write a
fetch('https://jsonplaceholder.typicode.com/posts?_limit=5') call.
- Parse with
.json(), then loop and append <li> elements.
- Convert the code to
async/await and add a try/catch that shows an error message in the page.
- Break the URL on purpose to demonstrate error handling.
AI Prompts
"Write a JavaScript function using fetch and async/await that gets 5 posts from jsonplaceholder and displays their titles in a ul element. Include error handling."
"Why doesn't fetch throw an error on HTTP 404? Show how to check response.ok and throw a custom error."
Starter Code
<!DOCTYPE html>
<html>
<head><title>API Demo</title></head>
<body>
<h1>Posts</h1>
<ul id="posts"></ul>
<script src="app.js"></script>
</body>
</html>
// TODO: fetch posts and display them
Final Code
async function loadPosts() {
const list = document.getElementById('posts');
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=5');
if (!response.ok) {
throw new Error('HTTP ' + response.status);
}
const posts = await response.json();
list.innerHTML = '';
posts.forEach(post => {
const li = document.createElement('li');
li.textContent = post.title;
list.appendChild(li);
});
} catch (error) {
list.innerHTML = '<li>Error loading posts: ' + error.message + '</li>';
}
}
loadPosts();
Exercises
- Modify the code to show each post's
body text under its title.
- Add a button that reloads the posts when clicked.
- Fetch users instead of posts and display names and emails.
Homework
- Build a small page that fetches and displays weather or country data from a free API of your choice.
- Add error handling and a "Loading..." message that appears before data arrives.
Quiz
- What does
await do inside an async function?
- a) Stops the whole browser
- b) Pauses execution until the promise resolves ✅
- c) Loops forever
- d) Throws an error
- How do you convert a fetch response to a JavaScript object?
- a)
response.text()
- b)
response.json() ✅
- c)
JSON.parse(response)
- d)
response.object()
- Does
fetch() reject on an HTTP 404 by default?
- a) Yes, always
- b) No, you must check
response.ok ✅
- c) Only in Firefox
- d) Only with POST
- Where should API error messages be shown to the user?
- a) Nowhere
- b) In the browser console only
- c) In the page UI with try/catch handling ✅
- d) In an alert that never closes
- Which method is used to send a request that may fail without crashing the app?
- a)
try/catch with async/await ✅
- b)
goto
- c)
while(true)
- d)
system.exit
Lesson 11.3: Building a Simple API with PHP
Duration: 60 minutes
Learning Objectives
- Create a PHP script that returns JSON instead of HTML.
- Read request data and return appropriate HTTP status codes.
- Implement GET and POST handlers in a single PHP file.
- Set the
Content-Type: application/json header.
- Store data in a simple in-memory or file-based array (no DB yet).
Instructor Notes
Use XAMPP so students can run PHP locally at http://localhost/. Show header('Content-Type: application/json') before any output. Use json_encode() / json_decode() for data conversion. Demonstrate reading the request body with file_get_contents('php://input'). Reinforce: validate input even in a tiny API — security awareness starts here.
Presentation Outline
- What a server-side API looks like (5 min)
- PHP
header() and json_encode() (10 min)
- Handling GET requests (15 min)
- Handling POST with request body (15 min)
- Testing with browser + fetch (15 min)
Demonstration
- Create
api.php that returns a list of products as JSON on GET.
- Add a POST handler that appends a new product to an array.
- Test GET via browser:
http://localhost/api.php.
- Test POST via a small HTML form or
fetch call from another page.
- Return
201 Created on successful POST and 400 on missing fields.
AI Prompts
"Write a PHP file api.php that returns a JSON list of products on GET and accepts a new product via POST using php://input. Set the JSON content-type header."
"Show how to return HTTP status codes in PHP (like 201 and 400) and explain why json_encode needs the header set first."
Starter Code
<?php
header('Content-Type: application/json');
$products = [
['id' => 1, 'name' => 'Book', 'price' => 10],
];
// TODO: handle GET and POST
echo json_encode($products);
Final Code
<?php
header('Content-Type: application/json');
$products = [
['id' => 1, 'name' => 'Book', 'price' => 10],
];
$method = $_SERVER['REQUEST_METHOD'];
if ($method === 'GET') {
echo json_encode($products);
exit;
}
if ($method === 'POST') {
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['name']) || !isset($input['price'])) {
http_response_code(400);
echo json_encode(['error' => 'name and price required']);
exit;
}
$input['id'] = count($products) + 1;
$products[] = $input;
http_response_code(201);
echo json_encode($input);
exit;
}
http_response_code(405);
echo json_encode(['error' => 'Method not allowed']);
Exercises
- Add a DELETE handler that removes a product by
id and returns 204.
- Add a PUT handler that updates a product's price by
id.
- Return a
404 when a requested product id does not exist.
Homework
- Extend the PHP API to store products in a JSON file (
products.json) instead of a variable, so data survives restarts.
- Write a JavaScript page that uses
fetch to GET and POST products to your API.
Quiz
- Which PHP function converts an array to a JSON string?
- a)
to_json()
- b)
json_encode() ✅
- c)
serialize()
- d)
echo_json()
- How do you set the response content type to JSON in PHP?
- a)
set_header(...)
- b)
header('Content-Type: application/json') ✅
- c)
content_type('json')
- d)
<?json ?>
- How do you read the raw POST body in PHP?
- a)
$_POST['body']
- b)
file_get_contents('php://input') ✅
- c)
request()->body
- d)
$_GET['body']
- What status code should a successful POST that created a resource return?
- a) 200
- b) 201 ✅
- c) 404
- d) 500
- Why must you validate input in an API?
- a) It makes the code longer
- b) To prevent bad or unsafe data from breaking the app ✅
- c) PHP requires it
- d) It is optional decoration
Lesson 11.4: Securing and Testing Your API
Duration: 45 minutes
Learning Objectives
- Explain why API keys and secrets must stay server-side.
- Validate and sanitize input in PHP.
- Test an API using the browser and a simple fetch client.
- Use HTTP status codes consistently for success and failure.
- Recognize common API mistakes (no error handling, exposed keys).
Instructor Notes
Demonstrate the danger of putting a key in client JS by showing "View Source". Teach htmlspecialchars() / filter_var() for sanitization basics. Introduce a lightweight testing habit: call the endpoint and confirm the JSON shape. Tie back to the grading rubric: security awareness is 10% of the grade.
Presentation Outline
- Why secrets must stay on the server (10 min)
- Input validation with
filter_var (10 min)
- Consistent status codes (10 min)
- Manual API testing workflow (10 min)
- Common mistakes review (5 min)
Demonstration
- Show a
.env-style config holding a fake API key, required by PHP only.
- Add validation: price must be numeric using
filter_var($price, FILTER_VALIDATE_FLOAT).
- Reject invalid data with
400 and a clear JSON error.
- Test GET and POST from the browser and from a fetch page.
- Review one buggy student-style API and fix it live.
AI Prompts
"Show me how to keep an API key secret in a PHP project and why I should never put it in JavaScript that runs in the browser."
"Write PHP code that validates a product price is a positive number using filter_var and returns a 400 error if invalid."
Starter Code
<?php
header('Content-Type: application/json');
// TODO: load config, validate input, return proper status codes
Final Code
<?php
header('Content-Type: application/json');
$apiKey = getenv('API_KEY') ?: 'demo-secret-key';
$data = json_decode(file_get_contents('php://input'), true) ?? [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($data['name'] ?? '');
$price = $data['price'] ?? null;
if ($name === '' || !filter_var($price, FILTER_VALIDATE_FLOAT) || $price < 0) {
http_response_code(400);
echo json_encode(['error' => 'Invalid name or price']);
exit;
}
http_response_code(201);
echo json_encode([
'api' => 'secure-demo',
'received' => ['name' => htmlspecialchars($name), 'price' => (float)$price]
]);
exit;
}
echo json_encode(['status' => 'ok', 'key_present' => !empty($apiKey)]);
Exercises
- Add a GET endpoint that requires a token header and returns
401 if missing.
- Sanitize a
description field with htmlspecialchars before echoing it back.
- Write three test cases (valid, missing field, negative price) and record the status codes.
Homework
- Refactor your Module 11.3 API to validate all inputs and return meaningful status codes.
- Write a short checklist (5 items) of how you will keep API keys safe in your final project.
Quiz
- Where should an API secret key live?
- a) In the browser JavaScript
- b) In a server-side config, never sent to the client ✅
- c) In a public GitHub repo
- d) In the HTML
- What does
filter_var($price, FILTER_VALIDATE_FLOAT) return if invalid?
- a)
0
- b)
false ✅
- c)
"invalid"
- d) Throws an error
- What status code means "Unauthorized"?
- a) 400
- b) 401 ✅
- c) 403
- d) 500
- Why sanitize user input with
htmlspecialchars?
- a) To make it shorter
- b) To prevent XSS by escaping HTML special chars ✅
- c) To encrypt it
- d) It is required by JSON
- Which is a good API testing habit?
- a) Assume it works
- b) Call it and check the JSON shape and status code ✅
- c) Never test POST
- d) Only test in production
End of Module 11. Remember: verify every AI-generated snippet by running it and reading the output.
الوحدة 11: APIs
الدورة: البرمجة بأدوات الذكاء الاصطناعي المجانية — بناء مواقع وتطبيقات حقيقية | الوحدة: 11 من 17 | الجمهور: أعمار 15–25، مبتدئون | الموضوع: أساسيات REST، أفعال HTTP، استهلاك APIs بـ JavaScript fetch، وبناء API بسيط بـ PHP.
المبدأ الأساسي: تحقق دائماً من الأكواد التي يولّدها الذكاء الاصطناعي. شغّلها، اقرأ المخرجات، وتأكد من فهم كل سطر قبل الثقة به.
الدرس 11.1 — ما هو API وأساسيات REST
المدة: 45 دقيقة
أهداف التعلم
- تعرّف على API ولماذا تستخدمه التطبيقات.
- اشرح نمط REST ببساطة.
- تعرّف على الأفعال الأربعة للـ HTTP: GET, POST, PUT, DELETE.
- اقرأ استجابة JSON بسيطة وتفهم بنيتها.
- وصف أكواد الحالة (200, 201, 404, 500) ومعناها.
ملخّص: API مثل نادل المطعم: العميل يطلب، المطبخ (السيرفر) يجهز، والنادل يعيد الطعام (الاستجابة). ركّز على أن REST مجرد اتفاقية وليس قاعدة صارمة، ولا تضع مفاتيح سرية في كود JavaScript الذي يصل للعميل.
الدرس 11.2 — استهلاك APIs بـ JavaScript fetch
المدة: 60 دقيقة
أهداف التعلم
- استخدم
fetch() لاستدعاء API عن بعد.
- تعامل مع الوعود عبر
.then() و async/await.
- حوّل الاستجابة JSON إلى كائن JavaScript.
- اعرض بيانات API في الصفحة.
- تعرّف على معالجة الأخطاء بـ
try/catch.
ملخّص: تبدأ بـ .then() ثم تنتقل إلى async/await. تحذير مهم: fetch لا يرمي خطأ تلقائياً عند 404؛ يجب فحص response.ok. الكود النهائي يعرض قائمة من العناوين في <ul>.
الدرس 11.3 — بناء API بسيط بـ PHP
المدة: 60 دقيقة
أهداف التعلم
- أنشئ ملف PHP يرجع JSON بدلاً من HTML.
- اقرأ بيانات الطلب وأعد أكواد حالة مناسبة.
- نفذ معالجات GET و POST في ملف PHP واحد.
- اضع رأس
Content-Type: application/json.
- خزّن البيانات في مصفوفة بسيطة (لا قاعدة بيانات بعد).
ملخّص: استخدم XAMPP لتشغيل PHP محلياً. استخدم json_encode() و json_decode() و file_get_contents('php://input'). النموذج النهائي يدير GET و POST ويعيد 201 عند النجاح و 400 عند نقص البيانات.
الدرس 11.4 — تأمين واختبار الـ API
المدة: 45 دقيقة
أهداف التعلم
- اشرح لماذا يجب أن تبقى مفاتيح السر على السيرفر.
- تحقق من المدخلات وطهّرها في PHP.
- اختبر الـ API من المتصفح وبرنامج fetch بسيط.
- استخدم أكواد حالة HTTP بشكل متناسق.
- تعرّف على الأخطاء الشائعة في APIs.
ملخّص: أضف التحقق باستخدام filter_var() وطهّر المدخلات بـ htmlspecialchars() لمنع XSS. اختبر كل نقطة نهاية يدوياً وتأكد من شكل JSON. الأخطاء الشائعة: مفاتيح ظاهرة، وعدم معالجة الأخطاء.