# Backend and HTTP: Who Does What, Methods and Status Codes<no value>

## In this lesson

This lesson is built from two chapters, in the same order as the slides:

1. **Chapter 1** — what a Backend is: Client, Server, Database, API and Endpoint
2. **Chapter 2** — HTTP Methods and Status Codes

## Chapter 1: What a Backend Is — Client, Server, Database, API and Endpoint

### What will we learn?

Now we move from programs that run **on our own computer** to software that **others** talk to over the network. This lesson gives the big picture and the words:

- **Backend** and **Frontend**.
- **Client**, **Server** and **Database**: how they work together.
- **API** and **Endpoint**.

### Why do we need this?

Every app you know (Wolt, Instagram, the bank's website) is built from two parts: what you see (the Frontend), and what happens "behind the scenes" (the Backend): saving the data, checking permissions, calculating prices. Full Stack developers write both. Data developers work every day with APIs and databases.

By the end of these topics you will build a real Backend: a server that receives requests from the internet, saves to a database, and returns responses.

### Explanation from the basics

#### Frontend versus Backend

| | Frontend | Backend |
|---|---|---|
| What it is | The part that **the user sees** and operates | The part that runs **on the server**, behind the scenes |
| Where it runs | In the browser / in the phone app | On a server computer (in the cloud / in the company) |
| Role | Display, forms, buttons | Business logic, saving data, security |
| Example in a shop | The product page, the "add to cart" button | Checking stock, calculating the price, saving the order |
| Technologies | HTML, CSS, JavaScript, React | **Python + FastAPI**, Node.js, Java... |

{{< box "analogy" "Analogy: a restaurant" >}}
**Frontend** = the restaurant's dining room: the menu, the tables, the waiter who takes the order. **Backend** = the kitchen: that is where the food is really prepared, where they check that there are ingredients and keep the rules (no meat with dairy in a kosher kitchen). **Database** = the storeroom and the fridge: that is where all the stock is kept. The diner never goes into the kitchen or the storeroom. They talk only to the waiter.
{{< /box >}}

#### Client, Server, Database — the three players

Remember the topic on the computer, the operating system and the network? The Client initiates, the Server answers. Now we add a third player:

```text
  ┌──────────┐   HTTP Request    ┌──────────┐     SQL query     ┌──────────┐
  │  Client  │ ────────────────► │  Server  │ ─────────────────► │ Database │
  │ (browser,│                   │ (FastAPI │                    │ (MySQL)  │
  │  app)    │ ◄──────────────── │  backend)│ ◄───────────────── │          │
  └──────────┘   HTTP Response   └──────────┘     rows           └──────────┘
```

1. The **Client** sends a **Request**: "give me the list of students".
2. The **Server** (our Backend) receives it, understands what is being asked, and checks permissions and rules.
3. The server asks the **Database**: "SELECT all the students". (This is **another** Client-Server: towards the Database, our server is the Client! We saw this in the networking practice.)
4. The Database returns rows.
5. The server processes them and returns a **Response** to the Client, usually as **JSON** (remember the JSON lesson!).

**Why doesn't the Client talk directly to the Database?** Because then every user could read and delete everything. The Server is **the guard**: it decides what is allowed, checks validity, and enforces rules. Exactly like Encapsulation in the OOP topic, only at the level of the whole system.

#### API — Application Programming Interface

**API** = an **interface** that a piece of software exposes, so that **other** software can use it. An interface = a defined set of actions: what you can ask for, how you ask, and what you get back.

You already know the idea! In OOP, the **Public Interface** of a Class (the public methods) is exactly "an object's API". A **Web API** is the same idea over the network: instead of `shop.place_order(...)`, you send an HTTP request.

| OOP (the OOP topic) | Web API (now) |
|---|---|
| `shop.get_product("P1")` | `GET /products/P1` |
| `shop.add_customer("Dana", ...)` | `POST /customers` with a Body |
| `ProductNotFoundError` | Status Code `404` |
| The public methods | The Endpoints |

#### Endpoint

**Endpoint** = **one address in the API + one action**. The combination of a **Method** (GET/POST...) and a **Path** (`/students`).

```text
GET     /students        → list all students
GET     /students/7      → get student 7
POST    /students        → create a new student
PUT     /students/7      → update student 7
DELETE  /students/7      → delete student 7
```

These are **five different Endpoints**, even though some of them share the same Path. The Method is part of the "address".

**Resource** = the "thing" the API manages: `students`, `products`, `orders`. An accepted convention: the Path in the **plural**, and an identifier after a slash.

#### What does the Backend do on every request?

| Step | Example |
|---|---|
| **Receiving** — decode the Method, the Path, the Body | `POST /students` with `{"name": "Dana", ...}` |
| **Validation** — is the data valid? | The age is a number, the email has an `@` |
| **Logic** — the business rules | The email does not already exist |
| **Data access** — the Database | `INSERT INTO students ...` |
| **Response** — a Status Code + JSON | `201 Created` + the new student |

### What an API response looks like

When the Client turns to an API, it sends a **request**, and the server returns a **response**. This is what both look like — for example, a request to GitHub's API about a user named octocat:

```text
GET /users/octocat              <- the request
Host: api.github.com

HTTP/1.1 200 OK                 <- the response
Content-Type: application/json

{"login": "octocat", "name": "The Octocat", "public_repos": 8}
```

| Part | What it says |
|---|---|
| `GET /users/octocat` | The Method and the path — **what** is being asked for |
| `200 OK` | The response code — the request **succeeded** |
| `Content-Type: application/json` | The body is in **JSON** format |
| `{"login": ...}` | The data itself — not design, not a page, only data |

An API returns **data** and not a display: every Client — a website, a phone app or another program — gets the same data and displays it in its own way.

{{< box "analogy" "Analogy: a restaurant" >}}
The diner (**Client**) does not go into the kitchen. They order through the waiter, according to the menu — that is the **API**, and every dish on the menu is an **Endpoint**. The kitchen (**Server**) prepares the dish, using what is in the pantry (**Database**), and the waiter brings it back.
{{< /box >}}

Later on we will learn to build an API like this ourselves, with **FastAPI**.

### Common mistake

**Mistake 1: "The Frontend will save the data, why do we need a Backend?"** Data in the browser stays **with one user**, on one computer, and anyone can change it. A price saved in the browser? A user can change it to 1 NIS. **Everything that needs to be reliable, shared and secure lives in the Backend.**

**Mistake 2: confusing an API with a Database.** The API is **the door**. The Database is **the storeroom** behind it. The Client never gets direct access to the storeroom, and always goes through the door, with its rules.

**Mistake 3: Paths that describe actions instead of resources.**

```text
GET  /getAllStudents
POST /createNewStudent
GET  /deleteStudent?id=7
```

The convention (called **REST**): the Path is **a noun** (the resource), and the **Method** is the verb. `DELETE /students/7` and not `GET /deleteStudent`. In particular: **GET never changes data**. Browsers and search-engine robots send GET automatically, and deleting through GET is a recipe for disaster. (We will expand on this in the second chapter.)

### Summary

- **Frontend** = what the user sees. **Backend** = logic, data and security, on the server.
- The flow: **Client → Server → Database → Server → Client**. The server is the guard: the Client does not access the Database directly.
- **API** = an interface that software exposes to other software. On the Web, through HTTP and JSON.
- **Endpoint** = Method + Path. `GET /students/7` and `DELETE /students/7` are two different Endpoints.
- The convention: Path = **a resource** (a noun, in the plural). Method = **an action**. GET does not change data.

<!-- docs:start — generated by scripts/intro6/site_docs.py; edit the links there -->

### Official documentation

- [MDN — Introduction to the server side](https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Server-side/First_steps/Introduction)
- [MDN Glossary — API](https://developer.mozilla.org/en-US/docs/Glossary/API)
- [MDN Glossary — JSON](https://developer.mozilla.org/en-US/docs/Glossary/JSON)

<!-- docs:end -->

## Chapter 2: HTTP Methods and Status Codes

### What will we learn?

- The four main **HTTP Methods**: **GET**, **POST**, **PUT**, **DELETE**.
- How they map to **CRUD**: Create, Read, Update, Delete.
- Basic **Status Codes**: which code to return when.
- What a request and a response look like in each of the actions.

### Why do we need this?

In the students API topic you will write a server, and for every Endpoint you will need to decide: which Method? Which code to return on success, and which on every kind of failure? A Client that talks to your server (an app, a Frontend, another service) decides what to do **according to the code**: show the data, show "not found", or ask the user to fix a form. A wrong code = a Client that behaves incorrectly.

### Explanation from the basics

#### CRUD — the four actions on data

Almost every system does four things with its data:

| CRUD | Meaning | HTTP Method | SQL (the databases topic) |
|---|---|---|---|
| **C**reate | Creating | **POST** | `INSERT` |
| **R**ead | Reading | **GET** | `SELECT` |
| **U**pdate | Updating | **PUT** | `UPDATE` |
| **D**elete | Deleting | **DELETE** | `DELETE` |

**This table is the whole backend part.** Every row will be an Endpoint, and a function that runs SQL.

#### The four Methods

**GET — reading.**

- "Give me": `GET /students`, `GET /students/7`.
- **No Body.** All the information is in the Path and the Query (in the next lesson).
- **Changes nothing** on the server. It is called **Safe**. You can send it 100 times, and nothing will change.

**POST — creating.**

- "Create something new": `POST /students`, with a **Body** that describes it.
- Every send creates **another** item. Two sends = two students.
- Usually the server sets the identifier (`id`) and returns the new item.

**PUT — updating (replacing).**

- "Update this item": `PUT /students/7`, with a **Body** of **all** the new data.
- Sending the same request again = the same result (the student stays with the same values). It is called **Idempotent**.

**DELETE — deleting.**

- "Delete this item": `DELETE /students/7`.
- Usually **no Body**.

(There are more Methods, like **PATCH** for a partial update of single fields, but these four are enough for us.)

{{< box "analogy" "Analogy: a lending library" >}}
**GET** = "can I see the book?" (you look, you don't take). **POST** = "I am donating a new book to the library" (a copy is added). **PUT** = "replace the torn cover of book 7 with a new cover" (the same book, updated). **DELETE** = "take book 7 off the shelves".
{{< /box >}}

#### Status Codes — what the server answers

A reminder from the topic on the computer, the operating system and the network: **2xx** success, **4xx** the Client's mistake, **5xx** the server's mistake. These are the codes we will use:

| Code | Name | When to return it | Example in our server |
|---|---|---|---|
| **200** | OK | Success, and there is a response | GET succeeded, PUT succeeded |
| **201** | Created | A new resource **was created** | POST succeeded |
| **204** | No Content | Success, **without** a Body | DELETE succeeded |
| **400** | Bad Request | The request is invalid in terms of the rules | Age 7 (needs 16+), an empty name |
| **404** | Not Found | The resource does not exist | `GET /students/999` |
| **409** | Conflict | Conflicts with an existing state | An email that is already registered |
| **422** | Unprocessable Content | The **structure** of the data is wrong | A missing field, text instead of a number (FastAPI returns it automatically) |
| **500** | Internal Server Error | **A bug in the server** | An Exception that was not caught in our code |

**The decision principle:**

```text
Did it work?
├── yes → created something new?  → 201
│         nothing to return?      → 204
│         otherwise               → 200
└── no  → the client's fault?
          ├── resource doesn't exist        → 404
          ├── wrong structure / types       → 422
          ├── breaks a business rule        → 400
          ├── conflicts with existing data  → 409
          └── our code crashed              → 500  (fix the bug!)
```

#### 4xx versus 5xx — why does it matter?

- **4xx** = "**you** (the Client) need to change something": fix the form, or ask for something that exists. Trying again **without a change** will fail again.
- **5xx** = "**I** (the server) failed". The Client did nothing wrong. The server's code needs fixing.

**A server that returns 500 on bad user input contains a bug**: it should have checked the input and returned a 4xx. (Remember the calculator server from the topic on the computer, the operating system and the network, which crashed on "hello"?)

### Requests and responses — examples

This is what the requests for each of the actions look like, and the code the server returns:

```text
POST   /students     {"name": "Dana"}   -> 201 Created
GET    /students/7                      -> 200 OK
PUT    /students/7   {"name": "Dana C"} -> 200 OK
DELETE /students/7                      -> 204 No Content
GET    /students/99                     -> 404 Not Found
```

### When to send a Body

| Method | Body? | What is in it |
|---|---|---|
| `GET` | No | You only read — there is nothing to send |
| `POST` | **Yes** | The data of the new resource, in JSON |
| `PUT` | **Yes** | All the updated data |
| `DELETE` | No | The identifier in the path is enough |

Later on, in FastAPI, we will see how our server receives each of these requests and returns the right code.

### Common mistake

**Mistake 1: a GET that changes data.**

```text
GET /students/7/delete
```

Browsers preload links, and search engines go over every link (Crawling). A link like this **will delete students without anyone meaning to**. Changing data: only POST, PUT and DELETE.

**Mistake 2: returning 200 for everything, with "error" inside the JSON.**

```json
{"status": "error", "message": "student not found"}
```

...with code 200. The Client (and also browsers and monitoring systems) see 200 and "think" that everything succeeded. **The code is part of the response.** A student that does not exist = **404**.

**Mistake 3: 500 on bad input.** A server that runs `int(age)` without checking, and crashes on `"abc"` → 500. This is **not** a mistake of the Client, which should not be punished. It is a bug in the server. Check the input, and return a **4xx** with an explanation.

**Mistake 4: 404 versus 400.** `GET /students/999` (valid, but does not exist) → **404**. `POST /students` with age `-5` (exists, but not valid) → **400**. The question: "does the resource not exist, or is the request not valid?"

### Summary

- **CRUD ↔ HTTP**: Create = **POST**, Read = **GET**, Update = **PUT**, Delete = **DELETE**.
- **GET** is safe: it does not change data, and has no Body. POST/PUT send a Body in JSON with `Content-Type: application/json`.
- Success: **200** (there is a response), **201** (created), **204** (no content).
- A Client mistake: **404** (does not exist), **400** (breaks a rule), **409** (a conflict), **422** (wrong structure or type).
- **500** = a bug in the server. Bad input should get a 4xx, and not cause a crash.
- The code is part of the response. Don't return 200 with "error" inside.

<!-- docs:start — generated by scripts/intro6/site_docs.py; edit the links there -->

### Official documentation

- [MDN — HTTP request methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods)
- [MDN — HTTP response status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status)
- [MDN — HTTP messages](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Messages)

<!-- docs:end -->

<!-- exercises:start — generated by scripts/intro6/sync_site_exercises.py; edit scripts/intro6/exercises/ -->
## Practice

Comprehension questions on the lesson material — no code.

### Exercise 1: Who does what?

For each action — does it happen in the Client, in the Server or in the Database?

1. The user clicks the "Sign up" button.
2. Checking that the email is not registered yet.
3. Saving the new student for the long term.
4. Showing the message "You signed up successfully".
5. Deciding which Status Code to return.

{{< solution >}}
1. **Client** — the interface the user sees.
2. **Server** — the logic and the rules (with the help of a query to the database).
3. **Database** — permanent storage.
4. **Client** — shows what the server returned.
5. **Server** — it is the one that decides what happened and returns a response.

```text
Client  --HTTP request-->  Server  --SQL query-->  Database
Client  <--HTTP response-- Server  <---rows------  Database
```
{{< /solution >}}

### Exercise 2: Endpoints

Write the five Endpoints of an API for managing **products** (`/products`): a list, one product, creating, updating and deleting. For each — the Method, the path and what it does.

{{< solution >}}
```text
GET     /products      -> list all products
GET     /products/7    -> get product 7
POST    /products      -> create a new product
PUT     /products/7    -> update product 7
DELETE  /products/7    -> delete product 7
```

**Endpoint** = Method + path. The same path (`/products/7`) does three different things according to the Method.
{{< /solution >}}

### Exercise 3: Reading an API response

A server returned the following response:

```text
HTTP/1.1 200 OK
Content-Type: application/json

{"login": "octocat", "name": "The Octocat", "public_repos": 8, "blog": null}
```

1. Did the request succeed? How do you know?
2. In which format is the data, and how do you know?
3. What is the user's name, and how many repositories do they have?
4. What does `null` mean?

{{< solution >}}
1. **Yes** — the code is **200 OK**.
2. **JSON** — that is what the Header `Content-Type: application/json` says, and that is also what the body looks like.
3. The name is **The Octocat**, and they have **8** repositories.
4. `null` in JSON means **"no value"** — the user has no website (`blog`). (In Python, when we read it later on, it will become `None`.)
{{< /solution >}}

### Exercise 4: CRUD ↔ Methods

Match each CRUD action to an HTTP Method, and to the suitable response code when it succeeds.

```text
Create    Read    Update    Delete
```

{{< solution >}}
| CRUD | Method | Code on success |
|---|---|---|
| Create | `POST` | **201** Created |
| Read | `GET` | **200** OK |
| Update | `PUT` | **200** OK |
| Delete | `DELETE` | **204** No Content |
{{< /solution >}}

### Exercise 5: Which code to return?

For each case — which Status Code should the server return?

1. A new student was created.
2. Student 99 was requested, and it does not exist.
3. Someone tried to create a student with an email that is already registered.
4. A student was deleted — and there is nothing to return.
5. Age 7 was sent, but the minimum age is 16.
6. The server crashed because of a bug in the code.

{{< solution >}}
1. **201** — something new was created.
2. **404** — the resource does not exist.
3. **409** — a conflict with what already exists.
4. **204** — it succeeded, without a body.
5. **400** — the request does not meet the rules (the Client's mistake).
6. **500** — the Server's mistake.
{{< /solution >}}

<!-- exercises:end -->
