<?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: maybeAguy?</title>
    <description>The latest articles on DEV Community by maybeAguy? (@silver_oof_).</description>
    <link>https://dev.to/silver_oof_</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%2F4161081%2Fa03db81e-0eed-4d7c-9133-ed27f014dc98.png</url>
      <title>DEV Community: maybeAguy?</title>
      <link>https://dev.to/silver_oof_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/silver_oof_"/>
    <language>en</language>
    <item>
      <title>Starting a cs project - Week 0</title>
      <dc:creator>maybeAguy?</dc:creator>
      <pubDate>Sun, 04 Oct 2026 07:09:22 +0000</pubDate>
      <link>https://dev.to/silver_oof_/starting-a-cs-project-week-0-5cfh</link>
      <guid>https://dev.to/silver_oof_/starting-a-cs-project-week-0-5cfh</guid>
      <description>&lt;p&gt;Hey everyone,&lt;br&gt;
After seeing my 5hr screen time on YouTube and Reddit, I realized that apparently you don’t get paid for that. Tragic.&lt;/p&gt;

&lt;p&gt;So, riding this sudden burst of motivation, I’m back to remake a project my friends and I made at a hackathon, except this time with a more… complex stack.&lt;/p&gt;

&lt;p&gt;The project is called ZeroApi. It’s inspired by tools like MockAPI, and the idea is pretty simple: the user sends us some JSON data, and we generate a mock API from it.&lt;/p&gt;

&lt;p&gt;That’s it. That’s the grand plan.&lt;/p&gt;

&lt;p&gt;Let’s start.&lt;br&gt;
For this week, the goal is React + TypeScript for the frontend and Go for the backend. I’m intentionally leaving PostgreSQL for later because we don’t actually need a database for the first version.&lt;br&gt;
After that, we’ll containerize everything with Docker. The immediate goal is simply to have a frontend talking to a Go API that actually runs.&lt;br&gt;
The structure I personally use is: root → api folder for go , and web folder for react.&lt;/p&gt;
&lt;h1&gt;
  
  
  Let’s start with Go
&lt;/h1&gt;

&lt;p&gt;Now, Go is a pretty great language . But compared to frameworks like Django and Springboot, it lacks a framework that matured with prebuilt features.&lt;br&gt;
Under this knowledge, i chose net/http library which means i have to write a lot more things than normal, because apparently I hate myself.&lt;br&gt;
So, for making a server in go, right now we need :&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;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
&lt;span class="s"&gt;"log"&lt;/span&gt;
&lt;span class="s"&gt;"net/http"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;encoding/json&lt;/code&gt; will let us encode Go values as JSON.&lt;br&gt;
&lt;code&gt;log&lt;/code&gt; gives us the standard library's logging functionality.&lt;br&gt;
And &lt;code&gt;net/http&lt;/code&gt; is the important one here: it provides the HTTP client/server functionality we need.&lt;br&gt;
Following this, inside &lt;code&gt;main&lt;/code&gt;, we create a &lt;code&gt;ServeMux&lt;/code&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="n"&gt;mux&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;NewServeMux&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;ServeMux&lt;/code&gt; is an HTTP request multiplexer. In simpler terms, it’s responsible for looking at an incoming request and deciding which handler should deal with it based on the request's URL pattern.&lt;br&gt;
Think of it roughly as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Incoming request
↓
ServeMux
↓
Which pattern matches?
↓
Call that handler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can register our first route:&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="n"&gt;mux&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&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;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;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;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&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="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Hello from Go!"&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;p&gt;Yes, this is how it looks in go. don’t worry, I too hate how ugly it look. But.&lt;br&gt;
Let's break it down. One by one.&lt;br&gt;
&lt;code&gt;mux.HandleFunc(...)&lt;/code&gt; → It registers a handler function for a URL pattern.&lt;br&gt;
The &lt;code&gt;"/{$}"&lt;/code&gt; pattern means we want the root path &lt;code&gt;/&lt;/code&gt; specifically. if we don’t do that {$} the issue was that all the requests which starts with / ended up giving a 200 status or 300  → 200 status, which is ugly.&lt;br&gt;
The second argument is an anonymous function. This function will be called whenever a matching request comes in.&lt;br&gt;
It receives two arguments:&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="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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;r&lt;/code&gt; represents the incoming HTTP request.&lt;br&gt;
It contains things such as the request method, URL, headers, query parameters, and so on.&lt;br&gt;
&lt;code&gt;w&lt;/code&gt; is what we use to construct the HTTP response that we're sending back to the client.&lt;br&gt;
So when we do:&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="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;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're setting a &lt;strong&gt;response header&lt;/strong&gt; telling the client that the response body contains JSON.&lt;br&gt;
Then:&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="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="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;takes our Go value:&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;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Hello from Go!"&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;and encodes it as JSON directly into the response writer.&lt;br&gt;
So the client eventually receives something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello from Go!"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important thing to understand here is that &lt;code&gt;w&lt;/code&gt; is the thing we're writing the HTTP response to.&lt;br&gt;
So this is how we make a server. YAY.&lt;br&gt;
Unfortunately, Not yay.&lt;br&gt;
We've defined what should happen when someone requests &lt;code&gt;/&lt;/code&gt;, but we haven't actually started a server yet.&lt;br&gt;
A route by itself doesn't make our application listen for network connections.&lt;br&gt;
That's where this comes in:&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="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":8080"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mux&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This starts an HTTP server listening on port &lt;code&gt;8080&lt;/code&gt;.&lt;br&gt;
The &lt;code&gt;":8080"&lt;/code&gt; part tells it which address/port to listen on.&lt;br&gt;
The &lt;code&gt;mux&lt;/code&gt; tells the server which handler should process incoming requests.&lt;br&gt;
So now the flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
↓
GET /
↓
localhost:8080
↓
HTTP server
↓
ServeMux
↓
"/{$}" matches
↓
Our handler runs
↓
JSON response
↓
Browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's enough to get a very basic Go API running.&lt;br&gt;
You can start it with something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;assuming you're running it from your Go module directory. or if you have divide work into folders you can do&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run folderName/fileName.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, there is one issue still. if you have noticed, you don’t actually see the message “your server is running in localhost:8080” in your terminal.&lt;br&gt;
Yes, we have to print it ourselves. But, don’t worry, instead of using print, we’ll use log function for that because it will print that AND give use more functionalities.&lt;br&gt;
&lt;code&gt;log&lt;/code&gt; is useful because &lt;code&gt;ListenAndServe&lt;/code&gt; returns an error if the server stops unexpectedly, so a common pattern is:&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="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&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;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":8080"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mux&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the logger will print the error and terminate the program if &lt;code&gt;ListenAndServe&lt;/code&gt; returns one.&lt;br&gt;
Yes, we’ll implement logs as well. But in next post, which would work as a helper post which would work on making this code more complete. Till then, learn what we did and search some basic things such as : what is NewServerMux()? What are the http request methods? and some basics of golang.&lt;/p&gt;
&lt;h1&gt;
  
  
  Now, we do react
&lt;/h1&gt;

&lt;p&gt;ok, so we have a server that’s running, good. Now the bad part(Not a bad part, i personally don’t know much of frontend, so if i make any mistake , please correct me)&lt;br&gt;
This is one of my weaker side, so i won’t be able to explain as thoroughly , but here’s what I did so far.&lt;br&gt;
I installed react with : npm create vite@latest . Then i was given some choices i chose this:&lt;br&gt;
Project name: › web&lt;br&gt;
Select a framework: › React&lt;br&gt;
Select a variant: › TypeScript&lt;br&gt;
But an alternative is  :  npm create vite@latest my-app -- --template react-ts&lt;br&gt;
After that, i deleted the following files, because those are autocreated by react and you don’t need them, and i like my page clean&lt;br&gt;
public/vite.svg&lt;br&gt;
src/assets/react.svg&lt;br&gt;
src/App.css&lt;br&gt;
src/index.css&lt;br&gt;
and then you can change the whole app.tsx to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Loading...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&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;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Docker
&lt;/h1&gt;

&lt;p&gt;Before compose, Docker needs something to build. Compose just orchestrates. So we need 4 files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root
├── docker-compose.yml
├── api
│   └── Dockerfile
└── web
├── Dockerfile
└── nginx.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;a &lt;strong&gt;Dockerfile&lt;/strong&gt; is a recipe for building an &lt;em&gt;image&lt;/em&gt; (a packaged snapshot of your app). A running instance of that image is a &lt;em&gt;container&lt;/em&gt;. Compose lets us start multiple containers with one command.&lt;/p&gt;

&lt;h1&gt;
  
  
  Go Dockerfile (&lt;code&gt;api/Dockerfile&lt;/code&gt;)
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;golang:1.25-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; go.mod ./&lt;/span&gt;
&lt;span class="c"&gt;# COPY go.sum ./ # Uncomment if you have a go.sum&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;go mod download
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;go build &lt;span class="nt"&gt;-o&lt;/span&gt; server .
&lt;span class="c"&gt;# Run stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; alpine:latest&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /app/server .&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["./server"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a &lt;strong&gt;multi-stage build&lt;/strong&gt;: one image builds the app, then we throw it away and keep only the result.&lt;br&gt;
&lt;strong&gt;Stage 1:&lt;/strong&gt; Start from an image with Go installed (&lt;code&gt;alpine&lt;/code&gt; = tiny Linux). We copy &lt;code&gt;go.mod&lt;/code&gt; and download dependencies &lt;em&gt;before&lt;/em&gt; copying the rest of the code. Docker caches each step, so if dependencies haven't changed, rebuilds skip the download. Then we compile everything into one binary called &lt;code&gt;server&lt;/code&gt;.&lt;br&gt;
&lt;strong&gt;Stage 2:&lt;/strong&gt; A fresh, tiny Alpine image with no Go and no source code. We copy only the binary from stage 1 and run it. &lt;code&gt;EXPOSE 8080&lt;/code&gt; is just documentation, it doesn't open anything by itself.&lt;/p&gt;
&lt;h1&gt;
  
  
  React Dockerfile (&lt;code&gt;web/Dockerfile&lt;/code&gt;)
&lt;/h1&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:20-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build
&lt;span class="c"&gt;# Serve stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; nginx:alpine&lt;/span&gt;
&lt;span class="c"&gt;# Vite outputs to /dist, Create React App outputs to /build&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /app/dist /usr/share/nginx/html&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; nginx.conf /etc/nginx/conf.d/default.conf&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Same idea. Stage 1 installs dependencies and runs &lt;code&gt;npm run build&lt;/code&gt;, which turns our TypeScript/React into plain static files in &lt;code&gt;dist&lt;/code&gt;. Once built, we don't need Node anymore, so stage 2 uses &lt;strong&gt;nginx&lt;/strong&gt; (a web server) to serve those files, with our own config.&lt;/p&gt;
&lt;h1&gt;
  
  
  nginx.conf (&lt;code&gt;web/nginx.conf&lt;/code&gt;)
&lt;/h1&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="c1"&gt;# Serve React app&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;root&lt;/span&gt; &lt;span class="n"&gt;/usr/share/nginx/html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt; &lt;span class="s"&gt;index.htm&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="n"&gt;/index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# Proxy API requests to the Go backend&lt;/span&gt;
&lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/api/&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://backend:8080/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&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;p&gt;This is the glue. Think of it like our &lt;code&gt;ServeMux&lt;/code&gt;, but for the whole app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
↓
nginx (port 80)
↓
Path starts with /api/ ?
↓              ↓
No             Yes
↓              ↓
React files    Go backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;location /&lt;/code&gt; serves the React app. The &lt;code&gt;try_files&lt;/code&gt; line falls back to &lt;code&gt;index.html&lt;/code&gt; if a file doesn't exist, which matters once we add routing.&lt;br&gt;
&lt;code&gt;location /api/&lt;/code&gt; forwards to Go. Notice the hostname &lt;code&gt;backend&lt;/code&gt;: Docker Compose puts all containers on one network and they can reach each other &lt;strong&gt;by service name&lt;/strong&gt;. The trailing &lt;code&gt;/&lt;/code&gt; in &lt;code&gt;proxy_pass&lt;/code&gt; strips &lt;code&gt;/api/&lt;/code&gt;, so &lt;code&gt;/api/&lt;/code&gt; from the browser becomes &lt;code&gt;/&lt;/code&gt; in Go. That's why our &lt;code&gt;fetch('/api/')&lt;/code&gt; hits the &lt;code&gt;"/{$}"&lt;/code&gt; route.&lt;/p&gt;

&lt;h1&gt;
  
  
  docker-compose.yml (in the root)
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./api&lt;/span&gt;
&lt;span class="c1"&gt;# No ports needed, nginx reaches it internally&lt;/span&gt;
&lt;span class="na"&gt;frontend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./web&lt;/span&gt;
&lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80:80"&lt;/span&gt; &lt;span class="c1"&gt;# your machine : container&lt;/span&gt;
&lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;backend&lt;/span&gt; &lt;span class="c1"&gt;# starts backend first&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One service per folder. The backend has &lt;strong&gt;no &lt;code&gt;ports&lt;/code&gt;&lt;/strong&gt; on purpose: only nginx is public, and the API is only reachable through &lt;code&gt;/api/&lt;/code&gt;. &lt;code&gt;depends_on&lt;/code&gt; starts the backend first, but it only waits for the container to &lt;em&gt;start&lt;/em&gt;, not to be ready. Fine for now, but we'll need healthchecks once PostgreSQL shows up.&lt;/p&gt;

&lt;h1&gt;
  
  
  Run it
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;--build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://localhost&lt;/code&gt; and you should see "Hello from Go!". That means React loaded, called &lt;code&gt;/api/&lt;/code&gt;, nginx forwarded it, and Go answered.&lt;br&gt;
Yes, that was a lot of config for one line of text. But the setup is done, and from here we build features.&lt;br&gt;
So…thats all for now, I hope you all come in this journey with me. As I am learning things myself as I move forward, So I am open to criticism and suggestions as we move.&lt;br&gt;
If I got anything wrong (especially frontend or nginx), please correct me in the comments.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
