<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mahmoud Ayman</title>
    <description>The latest articles on DEV Community by Mahmoud Ayman (@0xmahmoudd).</description>
    <link>https://dev.to/0xmahmoudd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4063153%2F084c8107-a42a-4bc3-b009-828b31b92c46.jpg</url>
      <title>DEV Community: Mahmoud Ayman</title>
      <link>https://dev.to/0xmahmoudd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/0xmahmoudd"/>
    <language>en</language>
    <item>
      <title>HTTP Deep Dive: What Every Backend Engineer Needs to Know</title>
      <dc:creator>Mahmoud Ayman</dc:creator>
      <pubDate>Sat, 15 Aug 2026 00:26:38 +0000</pubDate>
      <link>https://dev.to/0xmahmoudd/http-deep-dive-what-every-backend-engineer-needs-to-know-3h9i</link>
      <guid>https://dev.to/0xmahmoudd/http-deep-dive-what-every-backend-engineer-needs-to-know-3h9i</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;These are my own study notes, turned into a guide. I wrote it after learning how HTTP really works under the hood. If you are a backend engineer, or you want to become one, this covers the small part of HTTP that explains most of the bugs you will debug in production.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The Two Main Ideas Behind HTTP&lt;/li&gt;
&lt;li&gt;Network Layers and the History of HTTP&lt;/li&gt;
&lt;li&gt;The Structure of an HTTP Message&lt;/li&gt;
&lt;li&gt;HTTP Methods and Idempotency&lt;/li&gt;
&lt;li&gt;CORS: The Browser's Security Guard&lt;/li&gt;
&lt;li&gt;HTTP Status Codes&lt;/li&gt;
&lt;li&gt;HTTP Caching&lt;/li&gt;
&lt;li&gt;Content Negotiation and Compression&lt;/li&gt;
&lt;li&gt;Persistent Connections and Large Payloads&lt;/li&gt;
&lt;li&gt;TLS, SSL, and HTTPS&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The Two Main Ideas Behind HTTP
&lt;/h2&gt;

&lt;p&gt;HTTP is the language of the web. Every time a browser talks to a server, it uses HTTP. The whole protocol is built on two simple ideas: it is &lt;strong&gt;stateless&lt;/strong&gt;, and it follows the &lt;strong&gt;client-server model&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Statelessness
&lt;/h3&gt;

&lt;p&gt;HTTP has no memory of past requests. Every request is &lt;strong&gt;self-contained&lt;/strong&gt;. It carries everything the server needs to handle it: headers, URL, method, and body. Once the server sends a response back, it forgets the request happened. If the same client sends another request one second later, the server treats it as something completely new, with no link to what came before.&lt;/p&gt;

&lt;p&gt;This is why every request needs to carry proof of who is sending it, like an auth token or a session cookie. The server does not remember you from one request to the next, so you have to remind it every time.&lt;/p&gt;

&lt;p&gt;Why is this actually good design?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity&lt;/strong&gt;: the server does not need to store session data in memory. This keeps the server code simpler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: you can spread requests across many servers with no problem, because no single server has to track a client's session. If one server crashes, the client is not affected, because there was no state to lose in the first place.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since HTTP has no memory on its own, developers built techniques on top of it, like cookies, sessions, and tokens, to keep some kind of continuity for things like logins or shopping carts.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Client-Server Model
&lt;/h3&gt;

&lt;p&gt;In any HTTP flow, there is always a client and a server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Client&lt;/strong&gt;: usually a browser or an app. It always starts the connection and sends the request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server&lt;/strong&gt;: hosts the resources, like websites or APIs, and waits for requests. When a request arrives, the server processes it and sends back a response, such as HTML, JSON, or a plain text file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HTTP and HTTPS follow the same principles. HTTPS is just HTTP with TLS encryption on top for extra security.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjrrvy26r453clw0wt54d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjrrvy26r453clw0wt54d.png" alt=" " width="800" height="614"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good questions for interviews or exams:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is statelessness in HTTP, and what are its benefits?&lt;/li&gt;
&lt;li&gt;How do we work around HTTP being stateless?&lt;/li&gt;
&lt;li&gt;Who always starts the connection in the client-server model?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Network Layers and the History of HTTP
&lt;/h2&gt;

&lt;p&gt;Before a client and server can talk over HTTP, they need a path between them. HTTP needs a &lt;strong&gt;reliable&lt;/strong&gt; transport, one that does not lose messages. That is why it runs on top of &lt;strong&gt;TCP&lt;/strong&gt;, which is connection-based, instead of UDP.&lt;/p&gt;

&lt;p&gt;In the OSI model, HTTP lives at &lt;strong&gt;Layer 7, the Application Layer&lt;/strong&gt;. As backend engineers, this is mostly where our work happens. We do not need to go deep into TCP handshakes or the lower layers. That part is network engineering.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsq5phbzhbne9ztm71j4l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsq5phbzhbne9ztm71j4l.png" alt=" " width="280" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How HTTP Changed Over the Years
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcyke2znd9cpo5as0a21b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcyke2znd9cpo5as0a21b.png" alt=" " width="319" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTTP/1.0&lt;/strong&gt;: opened a new TCP connection for every request, then closed it. This was slow and wasted resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP/1.1&lt;/strong&gt;: added &lt;strong&gt;persistent connections&lt;/strong&gt;. One TCP connection could now handle many requests and responses. It also added caching and chunked transfer encoding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP/2&lt;/strong&gt;: added &lt;strong&gt;multiplexing&lt;/strong&gt;, so many requests and responses can travel at the same time over one connection. It moved from plain text to &lt;strong&gt;binary framing&lt;/strong&gt;, and added header compression, called &lt;strong&gt;HPACK&lt;/strong&gt;, plus server push.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP/3&lt;/strong&gt;: built on the &lt;strong&gt;QUIC&lt;/strong&gt; protocol, which runs over UDP instead of TCP. This gives a faster connection start, lower latency, and fixes a problem called head of line blocking that still existed in HTTP/2.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Good questions for interviews or exams:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the main difference between HTTP/1.0 and HTTP/1.1?&lt;/li&gt;
&lt;li&gt;What are the main additions in HTTP/2?&lt;/li&gt;
&lt;li&gt;Which OSI layer does HTTP work in?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Structure of an HTTP Message
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A request has
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Method&lt;/strong&gt; (GET, POST, and so on)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource URL&lt;/strong&gt; (the path you are asking for)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP version&lt;/strong&gt; (like &lt;code&gt;HTTP/1.1&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Host&lt;/strong&gt; (the domain)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Headers&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;blank line&lt;/strong&gt; that separates the headers from the body&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Body&lt;/strong&gt; (only if needed)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A response has
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HTTP version&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status code&lt;/strong&gt; (like &lt;code&gt;200&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status text&lt;/strong&gt; (like &lt;code&gt;OK&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Headers&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;blank line&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Body&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Headers: Extra Information About the Message
&lt;/h3&gt;

&lt;p&gt;Headers are key-value pairs that carry extra information about the request or the response. Think about sending a parcel. You write the name and address of the receiver on the outside of the box, not inside it. This lets the shipping company read the information fast, without opening the box. Headers work the same way. They let the client and server share information without touching the actual data, which is the body.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Request Headers
&lt;/h4&gt;

&lt;p&gt;These are sent by the client to tell the server who it is, what it wants, and what format it understands.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Header&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;User-Agent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Tells the server what client is making the request&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Mozilla/5.0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Authorization&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Carries login credentials&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Bearer abc123token&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Accept&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Tells the server what format the client wants back&lt;/td&gt;
&lt;td&gt;&lt;code&gt;application/json&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Accept-Language&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The client's preferred language&lt;/td&gt;
&lt;td&gt;&lt;code&gt;en-US,ar-EG&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Accept-Encoding&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;What compression the client supports&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gzip, br&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="nf"&gt;GET&lt;/span&gt; &lt;span class="nn"&gt;/users&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt;
&lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
&lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Bearer token123&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This request means: "send me JSON, and here is my token to prove I am logged in."&lt;/p&gt;

&lt;h4&gt;
  
  
  2. General Headers
&lt;/h4&gt;

&lt;p&gt;These carry information about the message itself, and they are not specific to just the request or just the response.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Header&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Date&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;When the message was sent&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Date: Fri, 05 Jun 2026 01:00:00 GMT&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Cache-Control&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;How the response should be cached&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Cache-Control: max-age=3600&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Connection&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether the connection should stay open&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Connection: keep-alive&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  3. Representation Headers
&lt;/h4&gt;

&lt;p&gt;These describe the shape of the data inside the body.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Header&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Content-Type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The format of the body&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;application/json&lt;/code&gt;, &lt;code&gt;text/html&lt;/code&gt;, &lt;code&gt;image/png&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Content-Length&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The size of the body in bytes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;245&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Content-Encoding&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether the body is compressed&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gzip&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ETag&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A fingerprint of the current version of the resource&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"v1.7-abc"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;ETag&lt;/code&gt; is technically a representation header, but in real use it works more like a &lt;strong&gt;cache validator&lt;/strong&gt; than just a description of the content. You will see it a lot in the caching section below.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Security Headers
&lt;/h4&gt;

&lt;p&gt;These help protect the connection from attacks.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Header&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Strict-Transport-Security&lt;/code&gt; (HSTS)&lt;/td&gt;
&lt;td&gt;Forces the browser to only use HTTPS, so it cannot be tricked into using plain HTTP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Content-Security-Policy&lt;/code&gt; (CSP)&lt;/td&gt;
&lt;td&gt;Limits where scripts, styles, and images can load from, which reduces XSS attacks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;X-Frame-Options&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stops the page from being loaded inside an &lt;code&gt;iframe&lt;/code&gt;, which prevents clickjacking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Set-Cookie&lt;/code&gt; with &lt;code&gt;HttpOnly&lt;/code&gt; / &lt;code&gt;Secure&lt;/code&gt; / &lt;code&gt;SameSite&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Stops JavaScript from reading the cookie, forces it to be sent only over HTTPS, and reduces CSRF&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Two more ideas worth remembering
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Extensibility&lt;/strong&gt;: HTTP lets you add custom headers, often with an &lt;code&gt;X-&lt;/code&gt; prefix, without breaking the protocol. The server can read them if it understands them, or just ignore them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remote control&lt;/strong&gt;: headers work like a remote control for the server. Content negotiation (&lt;code&gt;Accept&lt;/code&gt;), caching (&lt;code&gt;Cache-Control&lt;/code&gt;), and authentication (&lt;code&gt;Authorization&lt;/code&gt;) all guide server behavior without changing the URL or the body.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Good questions for interviews or exams:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why do we put metadata in headers instead of the body?&lt;/li&gt;
&lt;li&gt;Give an example of a security header and explain what it does.&lt;/li&gt;
&lt;li&gt;What are representation headers? Give some examples.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  HTTP Methods and Idempotency
&lt;/h2&gt;

&lt;p&gt;Methods show the client's &lt;strong&gt;intent&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Intent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Get data, do not change anything&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create new data, comes with a body&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PATCH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Update part of a resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PUT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Replace the whole resource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DELETE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove a resource&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Best practice&lt;/strong&gt;: many developers use &lt;code&gt;PUT&lt;/code&gt; when they actually mean &lt;code&gt;PATCH&lt;/code&gt;, and this is a mistake. A simple rule: &lt;strong&gt;always use &lt;code&gt;PATCH&lt;/code&gt; for updates&lt;/strong&gt;, unless you have a real reason to replace the whole resource. Only then use &lt;code&gt;PUT&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idempotent vs Non-Idempotent
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Idempotent&lt;/strong&gt; means: if you run the same request many times, the result stays the same and does not break the data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET&lt;/code&gt;: fetching the data 10 times gives you the same data every time.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PUT&lt;/code&gt;: replacing a resource with the same data 10 times still ends with the same final state.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DELETE&lt;/code&gt;: deleting something once removes it. Deleting it again does nothing new.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Non-idempotent&lt;/strong&gt; means the result changes with each call. &lt;code&gt;POST&lt;/code&gt; is the main example. If you click "create note" twice, you get two different notes.&lt;/p&gt;

&lt;p&gt;There is also &lt;code&gt;OPTIONS&lt;/code&gt;. The client uses this not to get data, but to ask the server what it can do. This is the method behind CORS preflight requests, which we cover next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frzmfncrpkidmxw4n62fr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frzmfncrpkidmxw4n62fr.png" alt=" " width="593" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good questions for interviews or exams:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the main difference between &lt;code&gt;PUT&lt;/code&gt; and &lt;code&gt;PATCH&lt;/code&gt;, and why is &lt;code&gt;PATCH&lt;/code&gt; the best practice?&lt;/li&gt;
&lt;li&gt;Explain idempotency, with examples of idempotent and non-idempotent methods.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  CORS: The Browser's Security Guard
&lt;/h2&gt;

&lt;p&gt;Browsers follow a &lt;strong&gt;Same-Origin Policy&lt;/strong&gt;. A frontend running on one domain is blocked from freely calling a backend on a different domain, for security reasons. &lt;strong&gt;CORS (Cross-Origin Resource Sharing)&lt;/strong&gt; is the mechanism that lets a server allow specific origins to bypass this rule.&lt;/p&gt;

&lt;p&gt;There are two request flows:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Simple Request
&lt;/h3&gt;

&lt;p&gt;A request counts as "simple" if its method is &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, or &lt;code&gt;HEAD&lt;/code&gt;, and it does not carry complex headers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjqbxsra6moccimvlfvr9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjqbxsra6moccimvlfvr9.png" alt=" " width="738" height="570"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The browser adds an &lt;code&gt;Origin&lt;/code&gt; header on its own. If the server replies with &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; that matches this origin, or with &lt;code&gt;*&lt;/code&gt;, the browser lets your JavaScript see the response. If not, it blocks it and shows a CORS error in the console.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Preflight Request
&lt;/h3&gt;

&lt;p&gt;The browser sends a preflight request &lt;strong&gt;before&lt;/strong&gt; the real one if any of these are true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The method is not "simple" (like &lt;code&gt;PUT&lt;/code&gt; or &lt;code&gt;DELETE&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The request has non-simple headers, like &lt;code&gt;Authorization&lt;/code&gt; or a custom header.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Content-Type&lt;/code&gt; is not simple. Most JSON APIs fall into this case, since &lt;code&gt;application/json&lt;/code&gt; triggers a preflight.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbjiflwjt1fixkvd5klum.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbjiflwjt1fixkvd5klum.png" alt=" " width="800" height="638"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The preflight &lt;code&gt;OPTIONS&lt;/code&gt; request has no body. It is just a question: "can I send you a &lt;code&gt;PUT&lt;/code&gt;? Can I include &lt;code&gt;Authorization&lt;/code&gt;?" If the server agrees, it replies with &lt;code&gt;204 No Content&lt;/code&gt;, plus the allowed origins, methods, and headers, and &lt;code&gt;Access-Control-Max-Age&lt;/code&gt; so the browser can save this approval instead of repeating the preflight on every single request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good questions for interviews or exams:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When does the browser decide to send a preflight instead of a simple request?&lt;/li&gt;
&lt;li&gt;What is the &lt;code&gt;OPTIONS&lt;/code&gt; method and what is its role in CORS?&lt;/li&gt;
&lt;li&gt;What does &lt;code&gt;Access-Control-Max-Age&lt;/code&gt; do in the preflight response?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  HTTP Status Codes
&lt;/h2&gt;

&lt;p&gt;Status codes give the client a standard way to understand the result of a request, without needing to read the response body. They are grouped by their first digit:&lt;/p&gt;

&lt;h3&gt;
  
  
  1xx: Informational
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;100 Continue&lt;/code&gt;: the server got the headers and the client can now send the body (useful for large uploads).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;101 Switching Protocols&lt;/code&gt;: used when moving from HTTP to WebSocket.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2xx: Success
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;200 OK&lt;/code&gt;: the request worked (usually with &lt;code&gt;GET&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;201 Created&lt;/code&gt;: the request worked and created a new resource (usually with &lt;code&gt;POST&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;204 No Content&lt;/code&gt;: the request worked but there is no body to return (common with &lt;code&gt;OPTIONS&lt;/code&gt; or &lt;code&gt;DELETE&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3xx: Redirection
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;301 Moved Permanently&lt;/code&gt;: the resource moved for good. For example, if you rename &lt;code&gt;/user&lt;/code&gt; to &lt;code&gt;/person&lt;/code&gt;, you return &lt;code&gt;301&lt;/code&gt; so old clients still work and nothing breaks for them.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;302 Found&lt;/code&gt;: a temporary redirect. The client should still use the original path in the future.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;304 Not Modified&lt;/code&gt;: the resource did not change, so the client can use its cached copy (used together with &lt;code&gt;ETag&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4xx: Client Errors
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;400 Bad Request&lt;/code&gt;: the client sent bad data.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;401 Unauthorized&lt;/code&gt;: no auth token was sent, or the token expired.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;403 Forbidden&lt;/code&gt;: the token is valid, but the client does not have permission for this action.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;404 Not Found&lt;/code&gt;: the resource or path does not exist.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;405 Method Not Allowed&lt;/code&gt;: using a method that this endpoint does not support.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;409 Conflict&lt;/code&gt;: a conflict in the data, like trying to create something that already exists.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;429 Too Many Requests&lt;/code&gt;: the client went over a rate limit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5xx: Server Errors
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;500 Internal Server Error&lt;/code&gt;: something went wrong on the server and was not handled properly.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;501 Not Implemented&lt;/code&gt;: this feature does not exist yet, but it might be added later.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;502 Bad Gateway&lt;/code&gt;: seen with proxies like Nginx, when the main server sends back an invalid response.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;503 Service Unavailable&lt;/code&gt;: the server is down for a short time, because of high traffic or maintenance.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;504 Gateway Timeout&lt;/code&gt;: the proxy got no response from the main server in time.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;401 vs 403, in one line:&lt;/strong&gt; &lt;code&gt;401&lt;/code&gt; means "I do not know who you are." &lt;code&gt;403&lt;/code&gt; means "I know exactly who you are, but you are not allowed in."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Good questions for interviews or exams:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the difference between &lt;code&gt;401 Unauthorized&lt;/code&gt; and &lt;code&gt;403 Forbidden&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;When do you use &lt;code&gt;409 Conflict&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;What is the difference between &lt;code&gt;301&lt;/code&gt; and &lt;code&gt;302&lt;/code&gt; redirects?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  HTTP Caching
&lt;/h2&gt;

&lt;p&gt;Caching means saving copies of responses, so we do not have to ask the server for them again. This lowers load time and saves bandwidth.&lt;/p&gt;

&lt;h3&gt;
  
  
  How ETag-based caching works
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fazfht2yyz5cbfqo2s8rx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fazfht2yyz5cbfqo2s8rx.png" alt=" " width="800" height="952"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First &lt;code&gt;GET&lt;/code&gt;: the server responds with &lt;code&gt;200&lt;/code&gt;, plus &lt;code&gt;Cache-Control: max-age=10&lt;/code&gt;, an &lt;code&gt;ETag&lt;/code&gt; (a fingerprint of the response), and &lt;code&gt;Last-Modified&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Second &lt;code&gt;GET&lt;/code&gt; for the same resource: the browser automatically adds &lt;code&gt;If-None-Match&lt;/code&gt; (the old &lt;code&gt;ETag&lt;/code&gt;) and &lt;code&gt;If-Modified-Since&lt;/code&gt; (the old date). This basically asks the server: "is this ETag still current, or did the data change since this date?"&lt;/li&gt;
&lt;li&gt;If nothing changed, the server responds with &lt;code&gt;304 Not Modified&lt;/code&gt;. This tells the browser it can safely use its own cached copy.&lt;/li&gt;
&lt;li&gt;Once the resource gets updated, for example through &lt;code&gt;POST&lt;/code&gt; or &lt;code&gt;PATCH&lt;/code&gt;, the server generates a &lt;strong&gt;new&lt;/strong&gt; &lt;code&gt;ETag&lt;/code&gt;. On the next &lt;code&gt;GET&lt;/code&gt;, the browser still sends the old &lt;code&gt;ETag&lt;/code&gt; in &lt;code&gt;If-None-Match&lt;/code&gt;, the server sees it is no longer valid, and responds with &lt;code&gt;200 OK&lt;/code&gt;, the fresh data, and the new &lt;code&gt;ETag&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Best practice&lt;/strong&gt;: relying only on plain HTTP caching with &lt;code&gt;ETag&lt;/code&gt;s in production can get complicated and puts extra load on the server to manage. A better option is often a client-side caching library, like &lt;strong&gt;React Query&lt;/strong&gt;, which gives the client full control over when to fetch new data and when to reuse the cache. Still, it is worth knowing that the native HTTP caching option exists for simpler cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good questions for interviews or exams:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is an &lt;code&gt;ETag&lt;/code&gt;, and how does it work with &lt;code&gt;If-None-Match&lt;/code&gt; to enable caching?&lt;/li&gt;
&lt;li&gt;When does the server respond with &lt;code&gt;304 Not Modified&lt;/code&gt;?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Content Negotiation and Compression
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Content negotiation&lt;/strong&gt; is how the client and server agree on the best format to exchange data. It has three main types:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Media type negotiation&lt;/strong&gt;: through the &lt;code&gt;Accept&lt;/code&gt; header (like &lt;code&gt;application/json&lt;/code&gt; vs &lt;code&gt;application/xml&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language negotiation&lt;/strong&gt;: through &lt;code&gt;Accept-Language&lt;/code&gt; (like English vs Spanish).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encoding negotiation&lt;/strong&gt;: through &lt;code&gt;Accept-Encoding&lt;/code&gt; (like &lt;code&gt;gzip&lt;/code&gt; vs &lt;code&gt;deflate&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The client can ask for JSON in Spanish, then switch to XML in English, and the server adapts, without the client needing to change anything else about the request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compression
&lt;/h3&gt;

&lt;p&gt;Since we are already talking about &lt;code&gt;Accept-Encoding&lt;/code&gt;, compression deserves its own note. On a dataset with 11,000 entries, a response compressed with &lt;code&gt;gzip&lt;/code&gt; came out to about &lt;strong&gt;3.8 MB&lt;/strong&gt;, while the same response without compression was about &lt;strong&gt;26 MB&lt;/strong&gt;. That is the real impact of compression. It shrinks payload size by a large amount, and this matters a lot when many clients are downloading the same large file. The client, meaning the browser, receives the compressed data and decompresses it on its own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good questions for interviews or exams:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;List the different types of content negotiation and their headers.&lt;/li&gt;
&lt;li&gt;Why do we use HTTP compression, and which header controls it?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Persistent Connections and Large Payloads
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Keep-Alive
&lt;/h3&gt;

&lt;p&gt;In HTTP/1.0, every request opened and closed a new TCP connection. This was slow and wasted resources. HTTP/1.1 made &lt;strong&gt;persistent connections&lt;/strong&gt; the default, using the &lt;code&gt;Connection: keep-alive&lt;/code&gt; header. This lets the client and server reuse the same connection for many requests, until one side decides to close it, which reduces latency and saves resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uploading large payloads: &lt;code&gt;multipart/form-data&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;When you upload binary data, like an image or a video, the request uses &lt;code&gt;multipart/form-data&lt;/code&gt;. The key detail here is the &lt;strong&gt;boundary&lt;/strong&gt; parameter. Since binary data is sent in parts, a delimiter string, called the boundary, marks where each part starts and ends, so the server can split them apart inside the request body.&lt;/p&gt;

&lt;h3&gt;
  
  
  Downloading large payloads: streaming
&lt;/h3&gt;

&lt;p&gt;To send a large text response without freezing, the server streams it in &lt;strong&gt;chunks&lt;/strong&gt; instead of sending one huge block. Two things make this work:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Content-Type: text/event-stream&lt;/code&gt;: tells the client to expect the data as a series of events.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Connection: keep-alive&lt;/code&gt;: the connection needs to stay open until every chunk arrives.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The client keeps appending each chunk as it arrives, until the full file is complete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good questions for interviews or exams:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the benefit of &lt;code&gt;Connection: keep-alive&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;What is the &lt;code&gt;boundary&lt;/code&gt;, and why do we use it in &lt;code&gt;multipart/form-data&lt;/code&gt; requests?&lt;/li&gt;
&lt;li&gt;How does a server stream a large response to a client?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  TLS, SSL, and HTTPS
&lt;/h2&gt;

&lt;p&gt;You will not work with these directly most of the time as a backend engineer, but you still need to know what they mean.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SSL (Secure Sockets Layer)&lt;/strong&gt;: the original protocol for encrypting data between client and server. It is now &lt;strong&gt;outdated&lt;/strong&gt; and no longer used, because of known security weaknesses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TLS (Transport Layer Security)&lt;/strong&gt;: the modern replacement for SSL, and much more secure. It encrypts data while it travels, using certificates to confirm the server's identity and set up an encrypted connection. This stops eavesdropping and data leaks. The current recommended version is &lt;strong&gt;TLS 1.3&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTPS&lt;/strong&gt;: simply regular HTTP with TLS or SSL security added on top. It uses TLS as the encryption layer to protect login details and other sensitive data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Good questions for interviews or exams:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the difference between SSL and TLS, and why did we stop using SSL?&lt;/li&gt;
&lt;li&gt;What is HTTPS, and how does it work together with TLS?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Understanding this flow, from statelessness, to headers, methods, CORS, status codes, caching, negotiation, streaming, and TLS, is the key to debugging most of the problems you will meet as a backend engineer. You do not need to master TCP internals or the full TLS handshake to be effective. You need to picture this pipeline clearly enough to reason about where things break.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus: A Few Code Examples
&lt;/h2&gt;

&lt;p&gt;Some of these ideas are easier to understand with real code. Below are small examples in both &lt;strong&gt;C# (ASP.NET Core)&lt;/strong&gt; and &lt;strong&gt;Go&lt;/strong&gt;, covering idempotent updates, custom headers, CORS, and cache headers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 1: PATCH (partial update) vs PUT (full replace)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;C# (ASP.NET Core)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// PATCH: partial update, the recommended default&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpPatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{id}"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;PatchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FromBody&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;JsonPatchDocument&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserDto&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetByIdAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ApplyTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UpdateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NoContent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 204&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// PUT: full replacement, only use it when you really mean it&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpPut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{id}"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ReplaceUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FromBody&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;UserDto&lt;/span&gt; &lt;span class="n"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;exists&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExistsAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReplaceAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// idempotent: same result every call&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NoContent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Go&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// PATCH: partial update&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;PatchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mux&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Vars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt; &lt;span class="n"&gt;UserPatch&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewDecoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"invalid body"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;userService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ApplyPatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"not found"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusNotFound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusNoContent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 204&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// PUT: full replacement, idempotent&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;ReplaceUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mux&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Vars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;replacement&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewDecoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"invalid body"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;userService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusNoContent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 2: Enabling CORS for a specific origin
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;C# (ASP.NET Core)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Program.cs&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddCors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AllowFrontend"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithOrigins&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://myfrontend.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AllowAnyMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
              &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AllowAnyHeader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
              &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AllowCredentials&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// needed if you send cookies or Authorization&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseCors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AllowFrontend"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Go&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;corsMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandlerFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Origin"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"https://myfrontend.com"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Access-Control-Allow-Origin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Access-Control-Allow-Methods"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"GET, POST, PUT, PATCH, DELETE"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Access-Control-Allow-Headers"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Content-Type, Authorization"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Access-Control-Allow-Credentials"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Access-Control-Max-Age"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"3600"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MethodOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusNoContent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 204 preflight response&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServeHTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 3: ETag-based caching
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;C# (ASP.NET Core)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{id}"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_resourceService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetByIdAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;etag&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$"\"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;\""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TryGetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"If-None-Match"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;clientEtag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;clientEtag&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;etag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StatusCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status304NotModified&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ETag&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;etag&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CacheControl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"max-age=10"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Go&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;GetResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mux&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Vars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;resourceStore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;etag&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`"%s"`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"If-None-Match"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;etag&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusNotModified&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 304&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ETag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;etag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cache-Control"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"max-age=10"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>backend</category>
      <category>http</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What is a Backend? A Complete Guide to How They Work and Why We Need Them</title>
      <dc:creator>Mahmoud Ayman</dc:creator>
      <pubDate>Tue, 04 Aug 2026 22:04:00 +0000</pubDate>
      <link>https://dev.to/0xmahmoudd/what-is-a-backend-a-complete-guide-to-how-they-work-and-why-we-need-them-18bd</link>
      <guid>https://dev.to/0xmahmoudd/what-is-a-backend-a-complete-guide-to-how-they-work-and-why-we-need-them-18bd</guid>
      <description>&lt;h2&gt;
  
  
  1. The Simple Definition
&lt;/h2&gt;

&lt;p&gt;Think of a backend as a computer that never sleeps. Its only job is to &lt;strong&gt;listen&lt;/strong&gt;. It waits for requests coming from outside — these can be HTTP requests, WebSocket connections, gRPC calls, or other protocols.&lt;/p&gt;

&lt;p&gt;This computer listens through &lt;strong&gt;open ports&lt;/strong&gt;, like port 80 or port 443. A port is like a door. If the door is closed, nobody can knock. If it's open, clients (browsers, mobile apps, other servers) can connect and send or receive data.&lt;/p&gt;

&lt;p&gt;We call this computer a &lt;strong&gt;server&lt;/strong&gt; because it &lt;em&gt;serves&lt;/em&gt; content:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static files (images, JavaScript, HTML)&lt;/li&gt;
&lt;li&gt;Data (usually as JSON)&lt;/li&gt;
&lt;li&gt;It can also &lt;em&gt;receive&lt;/em&gt; data from the client (like a form submission)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This definition is correct, but it's only half the picture. To really understand a backend, we need to follow a request step by step, from the moment it leaves your browser to the moment it reaches the server.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Journey of a Request
&lt;/h2&gt;

&lt;p&gt;Let's say you open &lt;code&gt;backend-demo.senus.xyz&lt;/code&gt; in your browser. Here is exactly what happens:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff0uvjojq9klio001ur3o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff0uvjojq9klio001ur3o.png" alt=" " width="509" height="1243"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — DNS: The Phone Book of the Internet
&lt;/h3&gt;

&lt;p&gt;Your browser doesn't understand domain names like &lt;code&gt;senus.xyz&lt;/code&gt;. It only understands IP addresses. So the browser asks a &lt;strong&gt;DNS server&lt;/strong&gt;: "What is the IP address for this domain?"&lt;/p&gt;

&lt;p&gt;DNS works like a phone book — you give it a name, it gives you a number. There are different types of DNS records:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A Record&lt;/strong&gt; → points a domain directly to an IP address&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CNAME Record&lt;/strong&gt; → points a domain to another domain (an alias)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In our example, the subdomain &lt;code&gt;backend-demo&lt;/code&gt; has an A record pointing to one specific IP address.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 — Reaching the Server (and the Firewall)
&lt;/h3&gt;

&lt;p&gt;That IP address belongs to a real machine — in this case, an &lt;strong&gt;AWS EC2 instance&lt;/strong&gt;. But the request doesn't reach the server directly. First, it must pass through a &lt;strong&gt;firewall&lt;/strong&gt;, called a &lt;strong&gt;Security Group&lt;/strong&gt; on AWS.&lt;/p&gt;

&lt;p&gt;The Security Group decides which ports are allowed to receive traffic from the internet. A typical setup allows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Custom port (e.g. 22)&lt;/td&gt;
&lt;td&gt;SSH access for developers to manage the server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;443&lt;/td&gt;
&lt;td&gt;HTTPS traffic (secure)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;HTTP traffic (not secure)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; if port 80 and 443 are not open, AWS blocks the request immediately. It never even reaches your server code.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Inside the Server: Reverse Proxy + Node Server
&lt;/h2&gt;

&lt;p&gt;Once the request passes the firewall, it enters the EC2 machine. But it doesn't hit your Node.js code directly. First, it meets a &lt;strong&gt;reverse proxy&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a reverse proxy?
&lt;/h3&gt;

&lt;p&gt;A reverse proxy is a server that sits in front of your real application servers. Its job is to manage redirects and configuration from one central place, instead of configuring every service separately.&lt;/p&gt;

&lt;p&gt;In this example, the tool used is &lt;strong&gt;Nginx&lt;/strong&gt;. A simplified Nginx config looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;backend-demo.senus.xyz&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;301&lt;/span&gt; &lt;span class="s"&gt;https://&lt;/span&gt;&lt;span class="nv"&gt;$host$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;# redirect HTTP -&amp;gt; HTTPS&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;backend-demo.senus.xyz&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# SSL certificate handled automatically by certbot&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://localhost:3001&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;# forward to the real Node server&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nginx does two important things here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Redirects any HTTP (port 80) traffic to HTTPS (port 443) for security&lt;/li&gt;
&lt;li&gt;Forwards (&lt;code&gt;proxy_pass&lt;/code&gt;) all matching requests to &lt;code&gt;localhost:3001&lt;/code&gt;, where the actual Node.js app is running&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Who is running on port 3001?
&lt;/h3&gt;

&lt;p&gt;That's your real backend code. On the server, a process manager called &lt;strong&gt;pm2&lt;/strong&gt; keeps it alive 24/7 (so if it crashes, it restarts automatically). Running &lt;code&gt;pm2 list&lt;/code&gt; on the EC2 instance might show two processes: one for the frontend, one for the backend.&lt;/p&gt;

&lt;p&gt;You can even test this from inside the server itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl localhost:3001/users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns the exact same response the browser gets — because it &lt;em&gt;is&lt;/em&gt; the same server, just accessed locally instead of through the internet. This is the same idea as running &lt;code&gt;localhost:3000&lt;/code&gt; on your own laptop while learning — just now it happens inside a cloud machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Why Do We Even Need a Backend?
&lt;/h2&gt;

&lt;p&gt;Let's use a real example: &lt;strong&gt;Instagram likes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You scroll your feed, see your friend's photo, and tap the like button. A second later, your friend gets a notification on their phone.&lt;/p&gt;

&lt;p&gt;What actually happened in between?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F46rhn45glm75hd6p1exd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F46rhn45glm75hd6p1exd.png" alt=" " width="800" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step by step:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your app sends a request to the server&lt;/li&gt;
&lt;li&gt;The server parses the request and figures out who you are&lt;/li&gt;
&lt;li&gt;The server &lt;strong&gt;persists&lt;/strong&gt; (permanently saves) this action in a database&lt;/li&gt;
&lt;li&gt;The server finds the post owner and triggers a notification to their phone&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Why can't your phone talk to your friend's phone directly?
&lt;/h3&gt;

&lt;p&gt;Because your app only knows &lt;em&gt;your&lt;/em&gt; data — your feed, your settings, your session. Your friend's app only knows &lt;em&gt;their&lt;/em&gt; data. Neither app has the full picture.&lt;/p&gt;

&lt;p&gt;We need one &lt;strong&gt;centralized computer&lt;/strong&gt; that holds information about &lt;em&gt;everyone&lt;/em&gt;, so it can connect people together (likes, comments, notifications, messages...).&lt;/p&gt;

&lt;p&gt;If you had to describe a backend's job in one word, it would be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Data.&lt;/strong&gt; Fetching data, receiving data, persisting data, and handling any action related to data.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. What Actually Happens on the Frontend?
&lt;/h2&gt;

&lt;p&gt;Good question: if the backend does all this heavy lifting, why not just do everything in the frontend and skip the extra hop?&lt;/p&gt;

&lt;p&gt;To answer that, let's look at what happens when your browser loads a frontend app (say, built with Next.js).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fshv9rtx3vbpvyfokp8lz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fshv9rtx3vbpvyfokp8lz.png" alt=" " width="280" height="810"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The browser first fetches the &lt;strong&gt;HTML&lt;/strong&gt; file&lt;/li&gt;
&lt;li&gt;Then it fetches everything else it needs: &lt;strong&gt;CSS, JavaScript, images, fonts&lt;/strong&gt; — each as a separate request&lt;/li&gt;
&lt;li&gt;Once CSS arrives, the browser &lt;strong&gt;paints&lt;/strong&gt; the page (colors, layout, fonts — the visual look)&lt;/li&gt;
&lt;li&gt;Once JavaScript arrives, the browser &lt;strong&gt;hydrates&lt;/strong&gt; the page — this means it attaches event listeners so buttons actually respond when clicked&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The key difference
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Frontend&lt;/th&gt;
&lt;th&gt;Backend&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Where code runs&lt;/td&gt;
&lt;td&gt;On the &lt;strong&gt;user's device&lt;/strong&gt; (their browser is the runtime)&lt;/td&gt;
&lt;td&gt;On the &lt;strong&gt;server&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What is sent&lt;/td&gt;
&lt;td&gt;The actual code (JS, CSS, HTML)&lt;/td&gt;
&lt;td&gt;Only the &lt;strong&gt;result&lt;/strong&gt; (e.g. JSON data)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The frontend ships you the code and your browser executes it. The backend executes the code itself and only ships you the answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Why Can't We Just Put Backend Logic in the Frontend?
&lt;/h2&gt;

&lt;p&gt;Since frontend code runs on a computer (the user's device), why not just connect the frontend directly to the database and skip the backend? There are &lt;strong&gt;four major reasons&lt;/strong&gt; why this is impossible and dangerous:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Security &amp;amp; Sandbox Environments
&lt;/h3&gt;

&lt;p&gt;Browsers run JavaScript in a &lt;strong&gt;Sandbox&lt;/strong&gt;. This is a strict security measure that isolates the browser from the user's Operating System. If browsers weren't sandboxed, any malicious website you visit could execute a script to read your local hard drive, steal personal files, and send them to a hacker. Because of the sandbox, frontend code &lt;strong&gt;cannot&lt;/strong&gt; access the local file system, read environment variables, or manage low-level OS processes—things a backend requires to function.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. CORS (Cross-Origin Resource Sharing)
&lt;/h3&gt;

&lt;p&gt;Browsers enforce a strict security policy called CORS. It prevents JavaScript running on &lt;code&gt;Domain A&lt;/code&gt; from making API requests to &lt;code&gt;Domain B&lt;/code&gt; unless &lt;code&gt;Domain B&lt;/code&gt; explicitly allows it via specific HTTP headers. A backend needs to freely communicate with dozens of external APIs (payment gateways, email services, third-party data). The browser's CORS policy would block most of these communications.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Databases and Connection Pools
&lt;/h3&gt;

&lt;p&gt;To talk to a database (like PostgreSQL or MongoDB), you need &lt;strong&gt;Native Database Drivers&lt;/strong&gt;. These drivers maintain persistent socket connections and read binary data—things browsers cannot do.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Connection Pool:&lt;/strong&gt; A backend server maintains a "pool" of open, reusable connections to the database. If 10,000 users visit your site, the backend handles them using a pool of maybe 50 database connections. &lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Disaster Scenario:&lt;/strong&gt; If you connected the frontend directly to the database, all 10,000 users would open 10,000 direct, simultaneous connections. The database would immediately run out of memory and crash.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Computing Power (Scalability)
&lt;/h3&gt;

&lt;p&gt;Frontend code runs on the user's hardware. Your users might be on a high-end gaming PC, or they might be on a 7-year-old budget smartphone with 2GB of RAM. You cannot run heavy business logic, data processing, or encryption on the client side without causing severe lag or crashing their browser. A backend server runs in a controlled cloud environment where you can easily scale up CPU and RAM to handle heavy computational loads.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Putting It All Together
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvinbep5do4jehuckvwig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvinbep5do4jehuckvwig.png" alt=" " width="759" height="898"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A backend, in short, is not just "a computer that listens." It's a whole chain: DNS resolves a name to an address, a firewall guards the door, a reverse proxy routes traffic internally, and finally your actual application code runs — safely, centrally, and with full access to databases and other services that a browser could never have.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary &amp;amp; Interview Prep
&lt;/h2&gt;

&lt;p&gt;If you are preparing for an exam or a technical interview, make sure you can confidently answer these core questions derived from the backend lifecycle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: What is the traditional definition of a server, and why is it called that?&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; A server is a computer continuously listening on open ports for incoming network requests. It is called a "server" because it &lt;em&gt;serves&lt;/em&gt; content (files, data, HTML) to clients.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: What is the difference between an A Record and a CNAME Record in DNS?&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; An A Record maps a domain name directly to an IPv4 address. A CNAME maps a domain name to another domain name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: What happens if you don't open Port 80 or 443 in your AWS Security Group?&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; The AWS firewall will immediately drop/block incoming web traffic, and the request will never reach your EC2 instance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: What is a Reverse Proxy and why do we use Nginx?&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; A reverse proxy sits in front of backend servers to route traffic, handle SSL/TLS termination, and manage redirects centrally, shielding the internal application servers from direct internet exposure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Why can't a mobile app send a notification directly to another user's phone without a backend?&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; Apps are customized for individual users and do not hold the global state of the application. A centralized backend is required to persist data, map user relationships, and trigger cross-device notifications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: What does "Hydration" mean in frontend development?&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; Hydration is the process where the browser downloads JavaScript and attaches event listeners to static server-rendered HTML, making the page fully interactive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Why is a Connection Pool necessary in backend architecture?&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; Opening and closing database connections for every single user request is computationally expensive and would crash the database under heavy load. A connection pool maintains a set of reusable, persistent connections to efficiently handle thousands of concurrent requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Why do browsers use a Sandbox environment?&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; To protect the user. It isolates web scripts from the local operating system, preventing malicious websites from accessing the file system or sensitive local data.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>backend</category>
      <category>softwareengineering</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
