week-7 Task-2 # HTTP & REST APIs: Understanding How the Web Actually Talks
When I started backend development, I kept seeing terms like: HTTP methods GET, POST, PUT, PATCH, DELETE status codes headers REST statelessness idempotency resources At first, they felt like a bunch of rules I just
When I started backend development, I kept seeing terms like:
- HTTP methods
- GET, POST, PUT, PATCH, DELETE
- status codes
- headers
- REST
- statelessness
- idempotency
- resources
At first, they felt like a bunch of rules I just had to memorize.
But once I understood what actually happens when a browser or frontend talks to a backend, these concepts started fitting together.
This blog is my attempt to understand HTTP and REST as a conversation between a client and a server.
1. The Basic Idea: Client Talks to Server
Whenever we use an application, there is usually some communication happening between a client and a server.
For example, imagine a Twitter-like application.
I open my profile.
The frontend might send:
GET /users/123
The server processes the request and sends something back:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 123,
"name": "Koushik"
}
That's HTTP communication.
The basic pattern is:
Client
|
| HTTP Request
v
Server
|
| HTTP Response
v
Client
This is the foundation of most web APIs.
2. What Is HTTP?
HTTP stands for:
HyperText Transfer Protocol
It is a protocol that defines how clients and servers communicate.
A client could be:
- browser
- React application
- mobile app
- Postman
- another backend service
A server could be:
- Node.js server
- Express application
- NestJS application
- Java/Spring application
- Python/Django application
- Go server
The important thing is that both sides understand the HTTP rules.
3. The Request/Response Cycle
This is one of the most important concepts to understand.
Let's say I open:
GET /users/123
The process roughly looks like this:
1. Client creates request
β
2. Request travels to server
β
3. Server receives request
β
4. Server finds the route
β
5. Server runs application logic
β
6. Server may query a database
β
7. Server creates response
β
8. Response travels back
β
9. Client receives response
Let's go through it.
4. Step 1: The Client Creates a Request
Suppose my frontend wants to get a user.
It might send:
GET /users/123 HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer token
This request contains information telling the server what the client wants.
5. Step 2: The Request Travels to the Server
The request travels over the network.
The client needs to know where the server is.
For example:
https://api.example.com/users/123
The browser or HTTP client handles things like:
- DNS lookup
- establishing a network connection
- TLS encryption for HTTPS
- sending the HTTP request
We don't usually think about all of these steps when writing backend code, but they happen underneath.
6. Step 3: The Server Receives the Request
Our Node.js application receives the HTTP request.
For example:
const http = require("node:http");
const server = http.createServer((req, res) => {
console.log(req.method);
console.log(req.url);
});
server.listen(3000);
If the client sends:
GET /users/123
we can access:
req.method
which gives:
GET
and:
req.url
which gives:
/users/123
7. Step 4: Routing
The server needs to figure out:
"What code should handle this request?"
For example:
GET /users
GET /users/123
POST /users
PATCH /users/123
DELETE /users/123
Each route can perform a different operation.
In a framework like Express or NestJS, routing becomes much easier to organize.
8. Step 5: Business Logic
Once the correct route is found, the application performs its work.
For example:
GET /users/123
β
Find user 123
β
Check permissions
β
Fetch user from database
β
Create response
The server might interact with:
- PostgreSQL
- MongoDB
- Redis
- another API
- file storage
9. Step 6: The Server Sends a Response
The server eventually sends something back.
For example:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 123,
"name": "Koushik"
}
The response tells the client:
"Here is the result of your request."
10. The Complete Story
So the entire process looks like:
Frontend
|
| GET /users/123
β
HTTP Server
|
β
Router
|
β
Controller
|
β
Service
|
β
Database
|
β
Service
|
β
Controller
|
β
HTTP Response
|
β
Frontend
This pattern becomes very familiar when working with Node.js and NestJS.
11. HTTP Methods
HTTP methods describe what the client wants to do.
The most common methods are:
GET
POST
PUT
PATCH
DELETE
Instead of inventing URLs like:
/createUser
/getUser
/updateUser
/deleteUser
REST APIs generally use the resource name and let the HTTP method describe the action.
For example:
GET /users
POST /users
GET /users/123
PATCH /users/123
DELETE /users/123
The URL identifies the resource.
The method tells us what we want to do with it.
12. GET
GET means:
"Give me this resource."
Example:
GET /users/123
The server might respond:
{
"id": 123,
"name": "Koushik"
}
Another example:
GET /users
could return a list of users.
GET should generally be safe
A GET request should not change the server's state.
For example:
GET /users/123
shouldn't delete the user or change their name.
13. POST
POST is commonly used to create a new resource.
For example:
POST /users
Content-Type: application/json
{
"name": "Koushik",
"email": "[email protected]"
}
The server may create:
User ID = 124
and respond:
201 Created
with the new resource.
14. PUT
PUT is commonly used to replace a resource with a new representation.
For example:
PUT /users/123
{
"name": "Koushik",
"email": "[email protected]"
}
Conceptually:
Old User
β
Replace with
β
New User representation
PUT can also be used for an upsert-style operation depending on the API design, but the exact behavior should be documented.
The important idea is:
PUT represents replacing the target resource with the supplied representation.
15. PATCH
PATCH is generally used for a partial update.
Suppose the user currently has:
{
"id": 123,
"name": "Koushik",
"email": "[email protected]",
"age": 20
}
We only want to change the name.
We can send:
PATCH /users/123
{
"name": "Koushik Maya"
}
Only the specified field needs to change.
So:
PUT
β replace/update the complete representation
PATCH
β partially modify the resource
In real APIs, the exact semantics of PATCH depend on the patch format and API design.
16. DELETE
DELETE means:
"Remove this resource."
Example:
DELETE /users/123
The server may respond:
204 No Content
There is no need to return the deleted user.
17. Quick HTTP Method Table
| Method | Typical Purpose | Example |
|---|---|---|
| GET | Read | GET /users/123 |
| POST | Create/process | POST /users |
| PUT | Replace | PUT /users/123 |
| PATCH | Partial update | PATCH /users/123 |
| DELETE | Delete | DELETE /users/123 |
18. What Is Idempotency?
This word sounds complicated, but the idea is simple.
A request is idempotent if making the same request multiple times has the same intended effect on the server's state as making it once.
For example:
PUT /users/123
with:
{
"name": "Koushik"
}
If I send it once:
User name = Koushik
If I send it five times:
User name = Koushik
The final intended state is still the same.
That's idempotency.
19. GET Is Idempotent
Suppose:
GET /users/123
I send it:
1 time β get user
10 times β get user
100 times β get user
The server's resource state should not change.
GET is therefore considered idempotent and safe.
20. PUT Is Idempotent
Suppose:
PUT /users/123
{
"name": "Koushik"
}
Sending it repeatedly should leave the resource in the same intended state.
Therefore, PUT is idempotent.
21. DELETE Is Idempotent
Suppose:
DELETE /users/123
First request:
User exists
β
Delete user
Second request:
User already deleted
The response may be different, such as 404 Not Found, but the intended final state is still:
User does not exist
Therefore DELETE is considered idempotent.
This is an important distinction:
Idempotent does not mean every response must be identical.
It means repeated requests have the same intended effect on the resource state.
22. POST Is Generally Not Idempotent
Suppose:
POST /orders
{
"productId": 10,
"quantity": 1
}
If I send it once:
Order #1001 created
If I send it again:
Order #1002 created
Now I have two orders.
So POST is generally not idempotent.
This is one reason duplicate POST requests can be dangerous for operations like:
- payments
- order creation
- account creation
Some APIs solve this with an idempotency key.
23. What About PATCH?
PATCH is more nuanced.
PATCH is not automatically idempotent.
It depends on what the patch operation actually does.
For example, imagine:
PATCH /users/123
{
"name": "Koushik"
}
Repeatedly applying that update may result in the same state.
But imagine a patch operation meaning:
increase balance by βΉ100
Repeating it could produce:
βΉ100
βΉ200
βΉ300
So PATCH can be idempotent or non-idempotent depending on its semantics.
24. HTTP Status Codes
When a server responds, it sends a status code.
For example:
200 OK
The first digit tells us the broad category.
1xx β Informational
2xx β Success
3xx β Redirection
4xx β Client Error
5xx β Server Error
The categories are more important to memorize than every individual status code.
25. 1xx β Informational
These indicate that the request has been received and the process is continuing.
You won't use these directly very often in typical REST API development.
26. 2xx β Success
This means:
"The request was successfully handled."
Common examples:
200 OK
General successful response.
GET /users/123
β 200 OK
201 Created
A resource was successfully created.
POST /users
β 201 Created
204 No Content
Successful request with no response body.
DELETE /users/123
β 204 No Content
27. 3xx β Redirection
These indicate that the client may need to take another action or use another location.
A familiar example is:
301 Moved Permanently
This tells clients that a resource has permanently moved.
Another is:
304 Not Modified
which is commonly involved with caching.
28. 4xx β Client Errors
These generally mean:
"There is something wrong with the request from the client."
Common examples:
400 Bad Request
The request is invalid.
POST /users
with malformed or invalid input might result in:
400 Bad Request
401 Unauthorized
Authentication is required or the provided authentication is invalid.
A useful way to remember it:
"I don't know who you are."
403 Forbidden
The server understood who you are, but you don't have permission.
Think:
"I know who you are, but you're not allowed to do this."
404 Not Found
The requested resource doesn't exist.
GET /users/999999
β 404 Not Found
409 Conflict
The request conflicts with the current state.
For example, trying to create a username that must be unique.
422 Unprocessable Content
The server understands the request format, but the submitted data fails validation or semantic rules.
29. 5xx β Server Errors
These generally mean:
"The server failed while trying to handle a valid request."
For example:
500 Internal Server Error
Maybe our application crashed while processing the request.
Other examples include:
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
These are especially important when dealing with distributed systems and reverse proxies.
30. Status Code Mental Model
I find this easier to remember:
2xx
"Everything worked."
3xx
"Go somewhere else / use cached information."
4xx
"Your request has a problem."
5xx
"Something went wrong on the server."
31. HTTP Headers
Headers are metadata attached to HTTP requests and responses.
Think of them like labels attached to a package.
The package contains the actual content.
The labels tell us things about it.
For example:
Content-Type: application/json
Authorization: Bearer abc123
Cache-Control: no-cache
32. Content-Type
Content-Type tells the receiver what format the message body uses.
For example:
Content-Type: application/json
means:
"The body contains JSON."
A request might look like:
POST /users
Content-Type: application/json
{
"name": "Koushik"
}
Other examples include:
text/plain
text/html
multipart/form-data
application/xml
This becomes particularly important when uploading files.
33. Accept Header
Although not in the original list, Accept is worth knowing alongside Content-Type.
Content-Type describes:
"What I am sending."
Accept describes:
"What I would like to receive."
For example:
Content-Type: application/json
Accept: application/json
This distinction is very useful when working with APIs.
34. Authorization
The Authorization header is commonly used to send authentication credentials.
For example:
Authorization: Bearer eyJhbGciOi...
The server can use the token to determine:
- who the user is
- whether the token is valid
- what the user is allowed to do
A common pattern is:
Client
|
| Authorization: Bearer token
β
Server
|
β
Validate token
|
β
Identify user
Important:
Authentication answers "Who are you?"
Authorization answers "Are you allowed to do this?"
35. Cache-Control
Cache-Control tells clients and intermediate caches how a response may be cached.
For example:
Cache-Control: max-age=3600
This can indicate that the response can be considered fresh for a certain period.
Another example:
Cache-Control: no-store
means the response should not be stored by a cache.
Caching can dramatically reduce unnecessary requests and improve performance.
36. Headers + Body
An HTTP message can be thought of like this:
HTTP Request
βββ Method
βββ URL
βββ Headers
βββ Body
Example:
POST /users HTTP/1.1
Content-Type: application/json
Authorization: Bearer token
{
"name": "Koushik"
}
And the response:
HTTP Response
βββ Status Code
βββ Headers
βββ Body
Example:
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": 123,
"name": "Koushik"
}
37. What Does Stateless Mean?
REST APIs are commonly described as stateless.
At first this sounds like:
"The server doesn't remember anything."
That's not quite right.
Stateless means:
Each request should contain the information necessary for the server to understand and process that request.
The server shouldn't have to rely on hidden conversational state from a previous request.
38. Example of Stateless Authentication
Suppose I make:
GET /profile
Authorization: Bearer abc123
The server validates the token and identifies me.
Then I make another request:
GET /orders
Authorization: Bearer abc123
The second request contains the authentication information it needs.
The server doesn't need to think:
"This must be the same person who called
/profilefive seconds ago."
Each request carries the required context.
39. Why Statelessness Is Useful
Imagine you have three backend servers:
Load Balancer
/ | \
/ | \
Server A Server B Server C
A user makes one request:
Request 1 β Server A
Another request might go:
Request 2 β Server C
If the request contains the necessary authentication/context, any server can process it.
This makes horizontal scaling easier.
40. Stateless Does NOT Mean No Database
This is an important distinction.
A stateless API can absolutely use a database.
For example:
Request
β
API Server
β
Database
β
Response
The database stores persistent application data.
Statelessness is about request-to-request application state, not about whether the application has storage.
41. REST
REST stands for:
Representational State Transfer
The name sounds intimidating, but the practical idea is much easier.
REST encourages us to model our API around resources.
Examples of resources:
users
posts
comments
orders
products
Instead of thinking:
"What function should this URL call?"
think:
"What resource am I working with?"
42. Resource Naming
A good REST API usually uses nouns rather than verbs.
Prefer:
GET /users
instead of:
GET /getUsers
Prefer:
POST /users
instead of:
POST /createUser
The HTTP method already tells us the action.
43. Resource Naming Examples
Good:
/users
/users/123
/posts
/posts/123
/comments
/comments/456
Less REST-like:
/getUsers
/createUser
/updateUser
/deleteUser
/getAllPosts
The idea is:
HTTP Method + Resource URL
together describe the operation.
44. Collections vs Individual Resources
A collection represents multiple resources:
/users
A specific resource:
/users/123
So:
GET /users
means:
"Give me users."
While:
GET /users/123
means:
"Give me user 123."
This distinction becomes extremely useful when designing APIs.
45. Nested Resources
Sometimes a resource belongs naturally to another resource.
For example:
/users/123/posts
could mean:
Posts belonging to user 123.
Or:
/posts/456/comments
could mean:
Comments belonging to post 456.
But nesting should not become unnecessarily deep.
Avoid things like:
/users/123/posts/456/comments/789/likes/10
if a simpler resource structure communicates the relationship.
46. Plural Resource Names
A common convention is to use plural nouns:
/users
/posts
/orders
/products
This makes collection endpoints intuitive.
For example:
GET /products
POST /products
GET /products/10
PATCH /products/10
DELETE /products/10
47. URLs Should Identify Resources
One of the biggest ideas in REST is:
The URL should identify the resource, while the HTTP method describes the operation.
For example:
GET /users/123
POST /users
PATCH /users/123
DELETE /users/123
We don't need five completely different URLs.
The resource is:
/users/123
The method changes what we want to do with it.
48. Query Parameters
Query parameters are useful for filtering, sorting, searching, and pagination.
For example:
GET /users?role=admin
or:
GET /posts?limit=20&cursor=abc123
The path identifies the resource:
/posts
The query parameters describe how we want the collection represented.
49. A Real Example: Social Media API
Let's imagine we're building a Twitter-like application.
Get posts
GET /posts
Get one post
GET /posts/123
Create a post
POST /posts
{
"content": "Learning Node.js!"
}
Update a post
PATCH /posts/123
{
"content": "Learning Node.js and NestJS!"
}
Delete a post
DELETE /posts/123
This is much easier to understand than creating action-based URLs for everything.
50. Putting the Whole Concept Together
Imagine I click:
"Create Post"
The frontend sends:
POST /posts
Content-Type: application/json
Authorization: Bearer token
{
"content": "Learning Node.js!"
}
The server receives the request.
Request
β
Routing
β
Authentication
β
Validation
β
Business Logic
β
Database
β
Response
The server might respond:
HTTP/1.1 201 Created
Content-Type: application/json
Cache-Control: no-cache
{
"id": 501,
"content": "Learning Node.js!",
"authorId": 123
}
Now almost every concept from this blog has appeared:
- HTTP
- request/response cycle
- POST
- headers
- Content-Type
- Authorization
- status code
- REST resource
- database
- response body
51. A Simple Mental Model
If I had to remember everything with one diagram:
HTTP
|
βββββββββββ΄ββββββββββ
| |
REQUEST RESPONSE
| |
ββββββ΄βββββ ββββββ΄βββββ
| | | |
Method Headers Status Headers
| | | |
URL Body Body Body
|
βββ GET
βββ POST
βββ PUT
βββ PATCH
βββ DELETE
And REST gives us a way to organize the URLs around resources:
/users
/users/123
/posts
/posts/123
/orders
/orders/123
52. Quick Revision Cheat Sheet
| Topic | Simple Meaning |
|---|---|
| HTTP | Rules for client-server communication |
| Request | Message sent by client |
| Response | Message sent by server |
| GET | Read a resource |
| POST | Create/process something |
| PUT | Replace a resource representation |
| PATCH | Partially modify a resource |
| DELETE | Remove a resource |
| Idempotent | Repeating the request has the same intended state effect |
| 2xx | Success |
| 3xx | Redirection |
| 4xx | Client-side/request problem |
| 5xx | Server-side problem |
| Content-Type | Format of the message body |
| Authorization | Credentials used to authenticate/authorize a request |
| Cache-Control | Caching instructions |
| Stateless | Each request carries the context needed to process it |
| REST | Resource-oriented API design style |
| Resource | Something represented by the API |
| Query parameter | Filtering/sorting/pagination/search information |
53. Final Takeaway
The biggest thing I learned is that HTTP isn't just:
"GET gets data and POST sends data."
There is a much bigger picture.
A client sends a request.
The request has:
Method
URL
Headers
Body
The server processes it and sends a response containing:
Status Code
Headers
Body
HTTP methods communicate intent:
GET β read
POST β create/process
PUT β replace
PATCH β partially modify
DELETE β remove
Status codes communicate the result:
2xx β success
3xx β redirection
4xx β client/request problem
5xx β server problem
Headers provide metadata:
Content-Type
Authorization
Cache-Control
And REST gives us a clean way to organize the API around resources:
/users
/posts
/orders
/products
Once this mental model is clear, frameworks like Express.js and NestJS become much easier to understand.
They aren't replacing HTTP.
They're giving us better tools for building applications that communicate using HTTP.
And that's the real foundation of backend development.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.