Servers and Flask Web Applications
Create dynamic server-side apps with Flask, templates, and databases.
Content
HTTP and REST Basics
Versions:
Watch & Learn
AI-discovered learning video
Sign in to watch the learning video for this topic.
HTTP and REST Basics — the Missing Link Between Your JS and the Server
Imagine your browser as a polite but nosy neighbor dropping off tiny letters at a mansion called the server. HTTP is the postal system. REST is the house rules that make the delivery predictable.
You just built an accessible, responsive page and added interactivity with client-side JavaScript. Great — now let that interactivity talk to the server. This lesson shows how HTTP and REST let your frontend (the part you styled and debugged in DevTools) communicate with a Flask backend so your app can create, read, update, and delete data like a civilized web citizen.
What is HTTP, and why does it matter here?
- HTTP (HyperText Transfer Protocol) is the set of rules for exchanging messages between clients (browsers, fetch, curl) and servers (Flask apps). Think of it as the language and etiquette for web conversations.
- You already used HTTP in the browser: when you enter a URL or use fetch from client-side JavaScript, you issue an HTTP request.
Why care? Because HTML/CSS/JS only make the UI. To persist data, authenticate users, or build APIs, you need HTTP + a server-side app (Flask) to process requests and respond with HTML, JSON, or files.
HTTP building blocks — quick tour
- Request line: METHOD PATH PROTOCOL (e.g., GET /notes HTTP/1.1)
- Headers: metadata like Content-Type, Authorization, Accept
- Body: optional payload (JSON, form data) for POST/PUT/PATCH
- Response: status code (200, 404, 500), headers, and body
Common HTTP methods (micro explanations)
- GET — fetch data; safe and idempotent. Use for read-only actions.
- POST — create something new; not idempotent (repeating may create duplicates).
- PUT — replace a resource entirely; idempotent.
- PATCH — modify part of a resource; usually not idempotent.
- DELETE — remove a resource; idempotent (deleting twice yields the same result)
Idempotency matters for retries: if a request times out, safe methods let you retry without surprise.
What is REST? (The minimalist manifesto)
REST (Representational State Transfer) is an architectural style, not a strict spec. Key principles:
- Resources, not actions: endpoints should represent nouns (e.g., /users, /posts/42), not verbs like /getUser
- Statelessness: each request carries all info needed. Server does not store client context between requests (session-less by default)
- Uniform interface: use HTTP verbs and status codes consistently
- Cacheable: responses can be cached when appropriate
- Layered system: clients need not know if there's a proxy, gateway, or actual server behind the scene
Why follow REST? Predictability. APIs that follow REST are easier to understand and use across teams and services.
Example: Flask routes that speak REST
Here is a tiny Flask app exposing a simple notes resource. This builds directly on your client-side fetch skills and DevTools debugging practice.
from flask import Flask, request, jsonify
app = Flask(__name__)
notes = {1: {'id': 1, 'text': 'Learn CS50!'}}
next_id = 2
@app.route('/notes', methods=['GET'])
def list_notes():
return jsonify(list(notes.values())), 200
@app.route('/notes', methods=['POST'])
def create_note():
global next_id
data = request.get_json() # client sends JSON
note = {'id': next_id, 'text': data.get('text', '')}
notes[next_id] = note
next_id += 1
return jsonify(note), 201
@app.route('/notes/<int:note_id>', methods=['PUT'])
def replace_note(note_id):
if note_id not in notes:
return jsonify({'error': 'Not found'}), 404
data = request.get_json()
notes[note_id] = {'id': note_id, 'text': data.get('text', '')}
return jsonify(notes[note_id]), 200
@app.route('/notes/<int:note_id>', methods=['DELETE'])
def delete_note(note_id):
if note_id in notes:
del notes[note_id]
return '', 204
return jsonify({'error': 'Not found'}), 404
Micro notes:
- Use jsonify to return proper JSON and headers.
- Use status codes (200 OK, 201 Created, 204 No Content, 404 Not Found).
How the client talks to Flask (fetch and curl examples)
From your client-side JS (remember fetch from earlier modules):
// GET notes
fetch('/notes')
.then(r => r.json())
.then(data => console.log(data))
// POST a new note
fetch('/notes', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: 'Write more comments' })
})
.then(r => r.json())
.then(note => console.log('Created', note))
Or test from terminal with curl:
curl -X POST -H 'Content-Type: application/json' -d '{"text":"Hello"}' http://localhost:5000/notes
Pro tip: open DevTools Network tab to inspect requests and responses. You used it for performance and debugging earlier — same skillset applies: check headers, payloads, and status codes.
Common patterns and gotchas
- Use nouns in endpoints: /users/7/friends, not /getUserFriends
- Query params for filtering/sorting: GET /posts?author=alice&limit=10
- Authentication often uses headers (Authorization: Bearer token)
- Watch CORS: browsers block cross-origin requests unless the server allows them; configure Flask-CORS in development
- CSRF: protect state-changing endpoints when using cookies for auth
Quick REST checklist for your Flask endpoints
- Is the endpoint a resource (noun)?
- Does the method match the action (GET for read, POST for create)?
- Are responses using correct HTTP status codes?
- Are requests and responses using JSON Content-Type consistently?
- Can you test the route easily from fetch or curl and inspect with DevTools?
Key takeaways
- HTTP is the protocol; REST is a style. HTTP gives you the verbs and status codes; REST recommends how to use them for resource-oriented APIs.
- Flask maps HTTP methods to Python functions. Use decorators and return JSON with appropriate status codes.
- Idempotency and statelessness matter. They make your API robust and predictable when clients retry requests.
- DevTools + curl + fetch = your debugging dream team. Use them to inspect requests, responses, headers, and payloads.
This is the moment where the concept finally clicks: HTTP is the conversation; REST is polite small talk that keeps the conversation meaningful, and Flask is the capable translator handling both sides like a pro.
If you want, I can: show a full CS50-style example that includes client-side fetch, storing tokens in localStorage (remember client-side storage from earlier), and a tiny auth flow with Flask. Want that demo next?
Comments (0)
Please sign in to leave a comment.
No comments yet. Be the first to comment!