HTTP: How Does It Work?
24/10/2024 • Melvynx
If there's one thing you'll use constantly in your developer career, it's network requests.
Whether you're working on a mobile app, a website, or even a video game, network requests over HTTP are almost always involved.
When I started coding, I found it quite complicated, so I'll try to explain it simply.
HTTP stands for:
HyperTextTransferProtocolAnd that last word, protocol, is very important. You might wonder:
A protocol is a kind of convention. Let's take the most well-known one in the world: The Postal Service.
We agree that when you send a letter:
Ultimately, the postal service is a protocol. Why? Because a protocol is just a set of rules that both parties know.
If you know the postal rules and follow them, when you hand your letter to the postal service, they will know exactly what to do with it.
That's a protocol.
Similarly, HTTP defines a lot of rules. There are two parts:
Both are simply text:
const request = "Blablabla";
const response = "What are you saying?";Except this text is formatted very precisely. Every character is important.
A request and a response have what we call a header. The header provides information about this request or response.
Here's an example of a header to fetch users from my server, codelynx.dev:
GET /users HTTP/1.1
Host: codelynx.dev
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Accept: application/json
Here, there are several parts. In the first line:
GET defines the HTTP method, GET indicates that we want to retrieve data, POST for example allows creating a resource./users defines the resource address, or simply the URL where we will fetch data.HTTP/1.1 defines the protocol, here it's the HTTP protocol version 1.1.Then, everything below is the header. It's a list of key-value pairs that define information about the request or response.
Host defines the server addressUser-Agent defines the user agent (your browser data, etc.)Accept defines the format you want to receiveYou can have hundreds of Headers.
That's for the request, here's what the response might look like:
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": [
{
"id": 1,
"name": "Leanne Graham",
"email": "Sincere@april.biz",
}
]
}
Boom, this time we have a response, the first line as before describes:
HTTP/1.1200 OKThe status basically indicates the state of the response. It tells us if the request was processed correctly. What you need to look at is the first number:
There are many statuses.
Then there are the headers again, here there's only one that tells us the content type of the response:
Content-Type: application/jsonAnd finally, finally, there's the response, the content, the JSON that contains all the information we want.
You can easily see all this in the browser:
We've seen that HTTP is just text, which is unsettling. Now this text contains several parameters that we'll see together.
The HTTP method defines an action you want to perform.
It's important to know that these methods are best practices to follow, but they don't change the result.
The purpose of these methods is just to allow you, by going to the same URL, to make GET, POST, PUT, DELETE, or PATCH requests.
Without them, you would have to create URLs like:
/users/1/delete/users/1/updateWhereas you can just do:
/users/1/users/1This allows for a simpler "resource" system to manage.
The URL is really the address. By default, websites work with routing with URLs like:
/users/users/1/users/1/updateEtc... the same thing when you go on Twitter, you'll notice that the URLs you have in your bar look like:
/home/tweets/32320rdnldsnogsAll this allows for routing, on the backend there are lots of if statements (libraries usually handle this) that do:
if (url.pathname === "/users") {
if (url.method === "GET") {
// Retrieve all users
}
if (url.method === "POST") {
// Create a user
}
}
// ...It's the simplest way to communicate the state of the response. There are many possible statuses, but the most important is the first number:
You can see it like this:
These statuses allow your client, the one sending the request, to know the state of the response.
Finally, the body, like everything else, is just a string of characters. To understand it, we use the Headers that define its type.
Depending on this type, the frontend handles the response.
It's important to know that generally, the body is "streamed" which is why in JavaScript you do this with fetch:
const response = await fetch("https://jsonplaceholder.typicode.com/posts");
const json = await response.json();It often happens that the backend sends the response before the body is complete.
By doing await response.json() you're telling the frontend to "wait until the body is complete".
Headers are information sent by the server. They are used to describe the content of the response.
Here are some headers you might encounter:
Content-Type = The content type of the responseContent-Length = The size of the response contentContent-Encoding = The encoding type of the response contentContent-Disposition = The disposition type of the response contentContent-Language = The language of the response contentIt's important to know that you can communicate any information via the headers.
Now that you understand the basics of the HTTP protocol, let's see how to use this knowledge to perform a fetch request in JavaScript. Fetch is a modern API that allows you to make HTTP requests in a simple and efficient way.
fetch RequestTo make a fetch request, you'll use the fetch() method which is native in modern browsers. Here's an example of how you might retrieve data from an API:
const fetchData = async () => {
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "GET", // The HTTP method
headers: {
Accept: "application/json", // The content type you want to receive
"Content-Type": "application/json", // The content type you send
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json(); // Convert the response to JSON
console.log(data); // Display the data in the console
} catch (error) {
console.error("Error fetching data:", error);
}
};
fetchData();URL: This is the address of the API you want to query. In this example, it's https://jsonplaceholder.typicode.com/posts.
Method: The HTTP method you're using. Here, it's GET because you want to retrieve data.
Headers: These are additional pieces of information you send with your request. In this example, you specify that you accept JSON and that you send JSON.
Error Handling: Use response.ok to check if the request was successful. If not, you throw an error with the HTTP status.
Response Conversion: Use await response.json() to convert the response into a JavaScript object.
fetch?Fetch is asynchronous and uses Promises, allowing you to handle requests in a non-blocking manner. This means your application can continue to function while the request is in progress, which is essential for a good user experience.
By using fetch, you can easily interact with APIs and retrieve data to display in your application. It's a powerful tool for any web developer.
By the way, I have a free course for you, it's BeginWeb to get you started right: