<?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: Sourabh Mandal</title>
    <description>The latest articles on DEV Community by Sourabh Mandal (@bitsofmandal-yt).</description>
    <link>https://dev.to/bitsofmandal-yt</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F253068%2Fec83e4cc-3dce-49e4-a987-2452b4ed8a1d.png</url>
      <title>DEV Community: Sourabh Mandal</title>
      <link>https://dev.to/bitsofmandal-yt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bitsofmandal-yt"/>
    <language>en</language>
    <item>
      <title>Dont Forget to Package Go App the right way in Docker</title>
      <dc:creator>Sourabh Mandal</dc:creator>
      <pubDate>Fri, 16 May 2025 14:02:28 +0000</pubDate>
      <link>https://dev.to/bitsofmandal-yt/how-to-properly-package-a-golang-app-inside-a-docker-container-5of</link>
      <guid>https://dev.to/bitsofmandal-yt/how-to-properly-package-a-golang-app-inside-a-docker-container-5of</guid>
      <description>&lt;p&gt;Packaging applications with Docker is standard practice today — but for production-ready Go apps, image size, startup time, and security matter. In this post, we’ll walk through how to containerize a Go application, then progressively optimize the image size from &lt;strong&gt;45MB to just 4MB&lt;/strong&gt; using tried-and-tested techniques.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Why Containerize Golang Apps?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Go produces statically linked binaries&lt;/strong&gt; — ideal for minimal containers.&lt;/li&gt;
&lt;li&gt;Containerized apps run reliably across different environments.&lt;/li&gt;
&lt;li&gt;Optimized containers improve deployment speed, resource usage, and security.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ What You’ll Learn
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;How to containerize a Golang app with Docker.&lt;/li&gt;
&lt;li&gt;Multi-stage builds and their benefits.&lt;/li&gt;
&lt;li&gt;Reducing image size with Go build flags.&lt;/li&gt;
&lt;li&gt;Using minimal base images (&lt;code&gt;scratch&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Compressing binaries with UPX.&lt;/li&gt;
&lt;li&gt;Real-world deployment tips and optimizations.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📖 Step 1: Basic Dockerfile
&lt;/h3&gt;

&lt;p&gt;Let’s start simple — a basic Dockerfile using the official Go image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; golang:1.24.3&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 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 ./cmd/main.go

&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;Image size: 🐳 ~45MB&lt;br&gt;
✅ Works fine for development, but not production-friendly.&lt;/p&gt;
&lt;h3&gt;
  
  
  📖 Step 2: Multi-Stage Build
&lt;/h3&gt;

&lt;p&gt;Now, let’s reduce size by separating build-time and runtime environments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&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.24.3&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;build&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 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 ./cmd/main.go

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; golang:1.24.3&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=build /app/server /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;Image size: 🐳 ~38MB&lt;br&gt;
✅ Keeps runtime image clean — no build tools.&lt;/p&gt;
&lt;h3&gt;
  
  
  📖 Step 3: Minimal Base Image (scratch)
&lt;/h3&gt;

&lt;p&gt;Use a minimal base image like scratch for further optimization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&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.24.3&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 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;&lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 go build &lt;span class="nt"&gt;-o&lt;/span&gt; server ./cmd/main.go

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; scratch&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /app/server /server&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["/server"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Image size: 🐳 ~17MB&lt;br&gt;
✅ Only includes your Go binary — nothing else.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Requires statically linked binaries (CGO_ENABLED=0).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  📖 Step 4: Go Build Flags
&lt;/h3&gt;

&lt;p&gt;Use Go build flags to strip debugging info:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go build &lt;span class="nt"&gt;-ldflags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-s -w"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; server ./cmd/main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Image size: 🐳 ~12MB&lt;br&gt;
✅ Smaller binaries, faster startup.&lt;/p&gt;
&lt;h3&gt;
  
  
  📖 Step 5: UPX Compression
&lt;/h3&gt;

&lt;p&gt;Compress your binary with UPX:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;upx &lt;span class="nt"&gt;--ultra-brute&lt;/span&gt; &lt;span class="nt"&gt;--quiet&lt;/span&gt; server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Image size: 🐳 ~4MB&lt;br&gt;
✅ Drastically reduced size, with negligible startup overhead.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Final Optimized Dockerfile
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&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.24.3-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;build&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;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--no-cache&lt;/span&gt; upx

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; go.mod go.sum ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;go mod download &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; go mod verify
&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;&lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 &lt;span class="nv"&gt;GOARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;amd64 &lt;span class="nv"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux go build &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;  &lt;span class="nt"&gt;-o&lt;/span&gt; server &lt;span class="se"&gt;\
&lt;/span&gt;  &lt;span class="nt"&gt;-ldflags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-s -w"&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;  &lt;span class="nt"&gt;-installsuffix&lt;/span&gt; cgo &lt;span class="se"&gt;\
&lt;/span&gt;  ./cmd/main.go

&lt;span class="k"&gt;RUN &lt;/span&gt;upx &lt;span class="nt"&gt;--ultra-brute&lt;/span&gt; &lt;span class="nt"&gt;--quiet&lt;/span&gt; server &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; upx &lt;span class="nt"&gt;--test&lt;/span&gt; server

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; scratch&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /app/server /server&lt;/span&gt;

&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["/server"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Final image size: 🐳 4MB&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Image Size Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Optimization Level&lt;/th&gt;
&lt;th&gt;Image Size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basic Golang + Alpine&lt;/td&gt;
&lt;td&gt;45MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+ &lt;code&gt;-ldflags="-s -w"&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;38MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+ &lt;code&gt;scratch&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;17MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+ UPX&lt;/td&gt;
&lt;td&gt;4MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;💡 Bonus Tips&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use layer caching for faster CI/CD builds.&lt;/li&gt;
&lt;li&gt;Include SSL certificates if using scratch.&lt;/li&gt;
&lt;li&gt;Gracefully handle signals for safe shutdowns.&lt;/li&gt;
&lt;li&gt;Define Docker health checks.&lt;/li&gt;
&lt;li&gt;Integrate security scanning tools.&lt;/li&gt;
&lt;li&gt;Measure container performance metrics post-deployment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📈 Real-World Impact
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Lower cloud storage and registry costs&lt;/li&gt;
&lt;li&gt;Faster container startup times&lt;/li&gt;
&lt;li&gt;Better scaling performance&lt;/li&gt;
&lt;li&gt;Improved security with minimal attack surface&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎯 Recap: 4 Key Optimization Techniques
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;✅ Multi-stage builds to separate build and runtime.&lt;/li&gt;
&lt;li&gt;✅ Go build flags (-ldflags="-s -w") for smaller binaries.&lt;/li&gt;
&lt;li&gt;✅ Using scratch for minimal base images.&lt;/li&gt;
&lt;li&gt;✅ UPX for ultra-light binary compression.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  📚 Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com" rel="noopener noreferrer"&gt;Docker Official Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies" rel="noopener noreferrer"&gt;Go Build Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://upx.github.io/" rel="noopener noreferrer"&gt;UPX Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>go</category>
      <category>devops</category>
      <category>aws</category>
    </item>
    <item>
      <title>📚 The Ultimate React Interview Preparation Guide for Senior Software Engineers (2025)</title>
      <dc:creator>Sourabh Mandal</dc:creator>
      <pubDate>Fri, 16 May 2025 13:46:51 +0000</pubDate>
      <link>https://dev.to/bitsofmandal-yt/the-ultimate-react-interview-preparation-guide-for-senior-software-engineers-2025-4k4g</link>
      <guid>https://dev.to/bitsofmandal-yt/the-ultimate-react-interview-preparation-guide-for-senior-software-engineers-2025-4k4g</guid>
      <description>&lt;p&gt;In this comprehensive guide, I’ll break down the essential React concepts every senior software engineer should master before heading into an interview. Whether you're preparing for a product company, a startup, or a remote global team, this list will ensure you're ready for deep technical discussions.&lt;/p&gt;




&lt;h2&gt;
  
  
  📖 Core React Fundamentals
&lt;/h2&gt;

&lt;p&gt;Start with rock-solid fundamentals. Even as a senior, you’ll be expected to explain these clearly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JSX&lt;/strong&gt; — How it transpiles to &lt;code&gt;React.createElement&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Virtual DOM&lt;/strong&gt; — What it is, how reconciliation and diffing work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Functional vs Class Components&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Props and PropTypes&lt;/strong&gt; for validation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local State Management&lt;/strong&gt; in components.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event Handling and Synthetic Events&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lifecycle Methods&lt;/strong&gt; (class-based) and &lt;code&gt;useEffect&lt;/code&gt; (functional).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controlled vs Uncontrolled Components&lt;/strong&gt; in forms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keys in Lists&lt;/strong&gt; and their role in reconciliation.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🟣 Advanced React Concepts
&lt;/h2&gt;

&lt;p&gt;Once fundamentals are solid, you should dive deep into modern React patterns and hooks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hooks:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useEffect&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useRef&lt;/code&gt; (for DOM access and persistent values)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useContext&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useReducer&lt;/code&gt; for complex state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useCallback&lt;/code&gt; and &lt;code&gt;useMemo&lt;/code&gt; for performance optimization&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useLayoutEffect&lt;/code&gt; vs &lt;code&gt;useEffect&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Custom Hooks (when, why, and how to write them)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Context API&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provider/Consumer pattern&lt;/li&gt;
&lt;li&gt;Prop drilling avoidance&lt;/li&gt;
&lt;li&gt;Performance implications of context value changes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Error Boundaries&lt;/strong&gt; — Handling runtime UI errors.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;React Portals&lt;/strong&gt; — Rendering outside the parent DOM tree for modals, tooltips, etc.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔶 State Management at Scale
&lt;/h2&gt;

&lt;p&gt;Senior roles require understanding both local and global state management strategies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Redux&lt;/strong&gt; (or alternatives like Zustand, Recoil, Jotai)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store, Actions, Reducers, Selectors&lt;/li&gt;
&lt;li&gt;Async operations (redux-thunk, redux-saga)&lt;/li&gt;
&lt;li&gt;Redux Toolkit for cleaner syntax and setup&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;React Query / TanStack Query&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server state management&lt;/li&gt;
&lt;li&gt;Caching, background refetching, pagination&lt;/li&gt;
&lt;li&gt;Optimistic UI updates&lt;/li&gt;
&lt;li&gt;Mutation handling patterns&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚡ Performance Optimization Techniques
&lt;/h2&gt;

&lt;p&gt;You’ll often be asked about application speed and responsiveness:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;React.memo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useCallback&lt;/code&gt; / &lt;code&gt;useMemo&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Code splitting with &lt;code&gt;React.lazy&lt;/code&gt; and &lt;code&gt;Suspense&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Dynamic imports&lt;/li&gt;
&lt;li&gt;Virtualized lists (react-window, react-virtualized)&lt;/li&gt;
&lt;li&gt;Lazy loading components and images&lt;/li&gt;
&lt;li&gt;Preventing unnecessary re-renders&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🟡 Routing Deep Dive
&lt;/h2&gt;

&lt;p&gt;React apps at scale require smart routing structures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Router basics and nested routes&lt;/li&gt;
&lt;li&gt;Programmatic navigation&lt;/li&gt;
&lt;li&gt;Route protection patterns&lt;/li&gt;
&lt;li&gt;Query strings and dynamic parameters&lt;/li&gt;
&lt;li&gt;Handling 404 routes&lt;/li&gt;
&lt;li&gt;Code-splitting routes&lt;/li&gt;
&lt;li&gt;Integrating routes with authentication workflows&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📝 Forms and Validation Patterns
&lt;/h2&gt;

&lt;p&gt;Forms can get complex — be ready to discuss:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Controlled vs Uncontrolled Forms&lt;/li&gt;
&lt;li&gt;Popular libraries: Formik, React Hook Form&lt;/li&gt;
&lt;li&gt;Validation with Yup/Zod&lt;/li&gt;
&lt;li&gt;Handling dynamic and nested fields&lt;/li&gt;
&lt;li&gt;Error handling and UX patterns&lt;/li&gt;
&lt;li&gt;Debounced validations&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧪 Testing React Applications
&lt;/h2&gt;

&lt;p&gt;Testing is non-negotiable for senior roles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unit testing with Jest&lt;/li&gt;
&lt;li&gt;Component testing with React Testing Library&lt;/li&gt;
&lt;li&gt;Snapshot testing&lt;/li&gt;
&lt;li&gt;Mocking APIs with msw (Mock Service Worker)&lt;/li&gt;
&lt;li&gt;Testing custom hooks&lt;/li&gt;
&lt;li&gt;End-to-end testing with Cypress or Playwright&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🟦 TypeScript in React (If Applicable)
&lt;/h2&gt;

&lt;p&gt;TypeScript is becoming standard in React projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Typing Props, State, Refs&lt;/li&gt;
&lt;li&gt;Typing custom hooks and Context API&lt;/li&gt;
&lt;li&gt;Utility types (&lt;code&gt;Partial&lt;/code&gt;, &lt;code&gt;Pick&lt;/code&gt;, &lt;code&gt;Omit&lt;/code&gt;, &lt;code&gt;Record&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Discriminated unions for complex state management&lt;/li&gt;
&lt;li&gt;Strongly-typed component patterns&lt;/li&gt;
&lt;li&gt;Type-safe HOCs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📊 Component Design Patterns
&lt;/h2&gt;

&lt;p&gt;Senior engineers must structure reusable and scalable components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Presentational vs Container components&lt;/li&gt;
&lt;li&gt;Compound component pattern&lt;/li&gt;
&lt;li&gt;Higher-Order Components (HOCs)&lt;/li&gt;
&lt;li&gt;Render Props&lt;/li&gt;
&lt;li&gt;Function as child components&lt;/li&gt;
&lt;li&gt;Hooks-based composition patterns&lt;/li&gt;
&lt;li&gt;Controlled and Uncontrolled components&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ App Architecture and Scalability
&lt;/h2&gt;

&lt;p&gt;Be prepared to talk about app organization and scaling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Component folder structuring&lt;/li&gt;
&lt;li&gt;Modular codebases&lt;/li&gt;
&lt;li&gt;Code splitting strategies&lt;/li&gt;
&lt;li&gt;Feature-based folder structures&lt;/li&gt;
&lt;li&gt;Micro frontends (Module Federation)&lt;/li&gt;
&lt;li&gt;Shared UI libraries (with Storybook integration)&lt;/li&gt;
&lt;li&gt;Multi-tenant SaaS application patterns&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔒 Security Best Practices
&lt;/h2&gt;

&lt;p&gt;Front-end security awareness is essential:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Preventing XSS in React apps&lt;/li&gt;
&lt;li&gt;Sanitizing dynamic HTML (&lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt; caveats)&lt;/li&gt;
&lt;li&gt;Securely handling API tokens and secrets&lt;/li&gt;
&lt;li&gt;Avoiding insecure localStorage usage&lt;/li&gt;
&lt;li&gt;Safe authentication flows (JWT, OAuth)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌐 Server-Side Rendering (SSR) and Static Generation
&lt;/h2&gt;

&lt;p&gt;Modern React projects often involve Next.js or SSR strategies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSR vs CSR vs SSG&lt;/li&gt;
&lt;li&gt;Next.js &lt;code&gt;getServerSideProps&lt;/code&gt;, &lt;code&gt;getStaticProps&lt;/code&gt;, ISR&lt;/li&gt;
&lt;li&gt;SEO benefits of SSR&lt;/li&gt;
&lt;li&gt;Lazy loading server-rendered pages&lt;/li&gt;
&lt;li&gt;API routes in Next.js&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Deployment and Build Optimization
&lt;/h2&gt;

&lt;p&gt;Performance tuning and build pipeline awareness:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Webpack concepts (tree shaking, code splitting)&lt;/li&gt;
&lt;li&gt;Modern bundlers: Vite, Parcel, ESBuild&lt;/li&gt;
&lt;li&gt;Environment variables and API endpoint management&lt;/li&gt;
&lt;li&gt;Bundle analysis tools (webpack-bundle-analyzer)&lt;/li&gt;
&lt;li&gt;Lighthouse audits and performance budgets&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🟢 Integration and API Management
&lt;/h2&gt;

&lt;p&gt;Seamless API communication is crucial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST vs GraphQL integration&lt;/li&gt;
&lt;li&gt;Axios and Fetch patterns&lt;/li&gt;
&lt;li&gt;API error handling strategies&lt;/li&gt;
&lt;li&gt;Token storage (HTTP-only cookies vs localStorage)&lt;/li&gt;
&lt;li&gt;Real-time communication (WebSockets, SSE)&lt;/li&gt;
&lt;li&gt;Offline-first patterns&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎨 Accessibility and Internationalization
&lt;/h2&gt;

&lt;p&gt;Inclusive apps improve user experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ARIA attributes and roles&lt;/li&gt;
&lt;li&gt;Keyboard navigation support&lt;/li&gt;
&lt;li&gt;Screen reader compatibility&lt;/li&gt;
&lt;li&gt;React i18n libraries and locale management&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ Bonus: Soft Skills and Senior Responsibilities
&lt;/h2&gt;

&lt;p&gt;Beyond code, senior roles demand leadership and mentorship:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conducting code reviews and feedback&lt;/li&gt;
&lt;li&gt;Leading architectural decisions&lt;/li&gt;
&lt;li&gt;Mentoring junior engineers&lt;/li&gt;
&lt;li&gt;Technical decision-making and trade-offs&lt;/li&gt;
&lt;li&gt;Cross-functional collaboration&lt;/li&gt;
&lt;li&gt;Debugging and troubleshooting production systems&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔍 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;React interviews for senior positions go well beyond “how does useState work.” You’ll be expected to demonstrate architectural foresight, performance optimization skills, advanced patterns, and leadership abilities.&lt;/p&gt;

&lt;p&gt;If you master the topics in this list and back them up with real-world experience, you’ll be well-positioned to ace your next senior React interview.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Was this helpful?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If you’d like, I can convert this into a &lt;strong&gt;handwritten iPad roadmap&lt;/strong&gt;, a &lt;strong&gt;mind map&lt;/strong&gt;, or a &lt;strong&gt;PDF checklist&lt;/strong&gt; too — just let me know! 🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>roadmap</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Best way to use Traefik in development mode</title>
      <dc:creator>Sourabh Mandal</dc:creator>
      <pubDate>Thu, 15 May 2025 13:04:52 +0000</pubDate>
      <link>https://dev.to/bitsofmandal-yt/best-way-to-use-traefik-in-development-mode-1cpb</link>
      <guid>https://dev.to/bitsofmandal-yt/best-way-to-use-traefik-in-development-mode-1cpb</guid>
      <description>&lt;p&gt;In the modern microservices architecture, reverse proxies play a crucial role in managing traffic and securing applications. Traefik has emerged as a popular choice due to its Docker-native integration and ease of configuration. This guide will walk you through setting up Traefik locally for development purposes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Traefik?
&lt;/h2&gt;

&lt;p&gt;Traefik is a modern HTTP reverse proxy and load balancer designed to seamlessly deploy microservices. Its standout features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic service discovery&lt;/li&gt;
&lt;li&gt;Built-in Let’s Encrypt support&lt;/li&gt;
&lt;li&gt;Real-time configuration updates&lt;/li&gt;
&lt;li&gt;Docker integration&lt;/li&gt;
&lt;li&gt;Dynamic load balancing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we begin, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker and Docker Compose installed&lt;/li&gt;
&lt;li&gt;Basic understanding of YAML configuration&lt;/li&gt;
&lt;li&gt;Admin access to modify system files&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up Traefik Locally
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;First, we need to configure our local network. Create a Docker Compose file and create a localhost_net network like shown below.
&lt;/li&gt;
&lt;/ol&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="c1"&gt;# service definition goes here&lt;/span&gt;
  &lt;span class="c1"&gt;# place for traefik service definition&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;localhost_net&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;external&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;traefik-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Please note that the network is defined as external so we have to manually create it before we run docker-compose command&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;To create a network use &lt;code&gt;docker network create localhost_net&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&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.amazonaws.com%2Fuploads%2Farticles%2Fwwoyg84etf3nd5zuplz4.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.amazonaws.com%2Fuploads%2Farticles%2Fwwoyg84etf3nd5zuplz4.png" alt=" " width="800" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a localhost network for traefik
Domain Configuration&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We’ll use two local domains to expose our application endpoints. Traefik has a builtin dashboard which can be exposed to the internet via http endpoint so we will be doing that for local development (not recomended in production setup) and our App on separate endpoint, both of these endpoints will be hosted behind traefik reverse proxy, following are the urls to setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traefik dashboard - &lt;a href="https://proxy.localhost" rel="noopener noreferrer"&gt;https://proxy.localhost&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Your application - &lt;a href="https://app.localhost" rel="noopener noreferrer"&gt;https://app.localhost&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We need to point both these urls to our local loopback address (127.0.0.1) for them to access our locally served up traefik from docker-compose file&lt;/p&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/hosts&lt;/code&gt; (mac) file in administrator mode. you can check where your host file setup are based on your OS, however configuration are same across OS.&lt;/p&gt;

&lt;p&gt;Add the following 2 lines at the end of your host file&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Fqlk735p37zqjfjrxdn14.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.amazonaws.com%2Fuploads%2Farticles%2Fqlk735p37zqjfjrxdn14.png" alt=" " width="520" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the Traefik service to your Docker Compose file. Please note that we have mounted a configuration file for traefik instead of defining all configurations in single docker-compose file. We will define these configuration later in the article:
&lt;/li&gt;
&lt;/ol&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;traefik&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;traefik:v3.1.6&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--configFile=/config/traefik.yml"&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="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;443:443"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&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;./traefik_data:/etc/traefik"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./config/configuration.yml:/config/traefik.yml:ro"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock:ro"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./localhost.crt:/certs/localhost.crt:ro"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./localhost.key:/certs/localhost.key:ro"&lt;/span&gt;
    &lt;span class="na"&gt;labels&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;traefik.enable=true"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.traefik.rule=Host(`proxy.localhost`)"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.traefik.entrypoints=websecure"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.services.traefik.loadbalancer.server.port=8080"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;localhost_net&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;localhost_net&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;external&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;traefik_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Generate local SSL certificates using OpenSSL at the root of your project:&lt;br&gt;
&lt;code&gt;openssl req -x509 -nodes -days 365 -newkey rsa:2048 \&lt;br&gt;
-keyout localhost.key -out localhost.crt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will generate 2 files &lt;code&gt;localhost.crt&lt;/code&gt; and &lt;code&gt;localhost.key&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Traefik Configuration file
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;config/configuration.yml&lt;/code&gt; with the following settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;global&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;checkNewVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;sendAnonymousUsage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="na"&gt;serversTransport&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;insecureSkipVerify&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;entryPoints&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Redirect HTTP to HTTPS&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;address&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"&lt;/span&gt;
    &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;redirections&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;entryPoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;websecure&lt;/span&gt;
          &lt;span class="na"&gt;scheme&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https&lt;/span&gt;

  &lt;span class="c1"&gt;# HTTPS endpoint&lt;/span&gt;
  &lt;span class="na"&gt;websecure&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:443"&lt;/span&gt;
    &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;tls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;domains&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;localhost"&lt;/span&gt;
            &lt;span class="na"&gt;sans&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;*.localhost"&lt;/span&gt;

&lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;providersThrottleDuration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2s&lt;/span&gt;

  &lt;span class="c1"&gt;# Docker provider for services running inside Docker&lt;/span&gt;
  &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost_net&lt;/span&gt; &lt;span class="c1"&gt;# Ensure this matches your Docker network name&lt;/span&gt;
    &lt;span class="na"&gt;exposedByDefault&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="c1"&gt;# Enable Traefik UI&lt;/span&gt;
&lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;dashboard&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;insecure&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="c1"&gt;# Log level: INFO|DEBUG|ERROR&lt;/span&gt;
&lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;INFO&lt;/span&gt;

&lt;span class="c1"&gt;# Manual TLS (self-signed certificate setup)&lt;/span&gt;
&lt;span class="na"&gt;tls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;certificates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;certFile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/certs/localhost.crt"&lt;/span&gt;
      &lt;span class="na"&gt;keyFile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/certs/localhost.key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s deploy a sample NGINX application behind Traefik:&lt;br&gt;
&lt;/p&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;traefik&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;traefik:v3.1.6&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--configFile=/config/traefik.yml"&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="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;443:443"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&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;./traefik_data:/etc/traefik"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./config/configuration.yml:/config/traefik.yml:ro"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock:ro"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./localhost.crt:/certs/localhost.crt:ro"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./localhost.key:/certs/localhost.key:ro"&lt;/span&gt;
    &lt;span class="na"&gt;labels&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;traefik.enable=true"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.traefik.rule=Host(`proxy.localhost`)"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.traefik.entrypoints=websecure"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.services.traefik.loadbalancer.server.port=8080"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;localhost_net&lt;/span&gt;

  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
    &lt;span class="na"&gt;labels&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;traefik.enable=true"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.app.rule=Host(`app.localhost`)"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.app.entrypoints=websecure"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.services.app.loadbalancer.server.port=80"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;localhost_net&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;localhost_net&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;external&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;traefik_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advanced Configuration Options
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Middleware Configuration
&lt;/h4&gt;

&lt;p&gt;Traefik supports various middleware options for enhanced functionality:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Example of adding basic auth middleware&lt;/span&gt;
&lt;span class="na"&gt;labels&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;traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xyz123"&lt;/span&gt;
   &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.routers.app.middlewares=auth@docker"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Rate Limiting
&lt;/h4&gt;

&lt;p&gt;Protect your services with rate limiting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;labels&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;traefik.http.middlewares.ratelimit.ratelimit.average=100"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;traefik.http.middlewares.ratelimit.ratelimit.burst=50"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Health Checks
&lt;/h4&gt;

&lt;p&gt;Configure health checks for your services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="s"&gt;traefik.http.services.app.loadbalancer.healthcheck.path=/health&lt;/span&gt;
   &lt;span class="s"&gt;traefik.http.services.app.loadbalancer.healthcheck.interval=10s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Security Considerations
&lt;/h2&gt;

&lt;p&gt;When setting up Traefik locally, consider these security best practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSL/TLS Configuration: Always use HTTPS, even locally&lt;/li&gt;
&lt;li&gt;Access Control: Secure the Traefik dashboard&lt;/li&gt;
&lt;li&gt;Docker Socket: Be cautious with Docker socket mounting&lt;/li&gt;
&lt;li&gt;Network Isolation: Use separate networks for different environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Troubleshooting Common Issues
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Certificate Issues
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Ensure certificates are properly mounted&lt;/li&gt;
&lt;li&gt;Check certificate permissions&lt;/li&gt;
&lt;li&gt;Verify domain names match certificates&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Network Problems
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Confirm Docker network exists&lt;/li&gt;
&lt;li&gt;Check host file configurations&lt;/li&gt;
&lt;li&gt;Verify port mappings&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Service Discovery Issues
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Ensure labels are correctly configured&lt;/li&gt;
&lt;li&gt;Check Docker network connectivity&lt;/li&gt;
&lt;li&gt;Verify service ports&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Setting up Traefik locally provides a powerful development environment that mirrors production configurations. This setup allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test microservices architecture locally&lt;/li&gt;
&lt;li&gt;Develop with HTTPS enabled&lt;/li&gt;
&lt;li&gt;Experiment with various Traefik features&lt;/li&gt;
&lt;li&gt;Prepare for production deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember to check Traefik’s official documentation for the latest features and best practices as you build upon this basic setup.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>go</category>
      <category>tutorial</category>
      <category>devops</category>
    </item>
    <item>
      <title>You Don't Need GORM, there is a better alternative</title>
      <dc:creator>Sourabh Mandal</dc:creator>
      <pubDate>Tue, 13 May 2025 19:57:22 +0000</pubDate>
      <link>https://dev.to/bitsofmandal-yt/you-dont-need-gorm-there-is-a-better-alternative-12j2</link>
      <guid>https://dev.to/bitsofmandal-yt/you-dont-need-gorm-there-is-a-better-alternative-12j2</guid>
      <description>&lt;p&gt;If you are still using GORM, Let me tell you there is a better alternative. Over the past few weeks I have been exploring the best way possible to communicate with my database.&lt;br&gt;
So I turned to benchmark results and take the most performant one off the shelf. But the problem was all of them had mixed views. Gorm was winning for how easy it is to bootstrap and supports multiple databases and where as sqlx and sqlc are were some of the popular libraries know for its speed.&lt;/p&gt;

&lt;p&gt;Hi, I am software engineer and been working with GoLang for 3 years. If you are still here and Enjoy the art of building and experimenting with Code. Please consider subscribing &lt;a href="https://www.youtube.com/@bitsofmandal" rel="noopener noreferrer"&gt;YouTube Channel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When building Go applications with PostgreSQL, GORM is often the &lt;strong&gt;go-to ORM&lt;/strong&gt; because of its simplicity and developer-friendly API. However I had fare share of nightmares using ORMs especially with Postgres. This versatile database supports more essential Data-Types that are not natively supported in GORM.&lt;/p&gt;

&lt;p&gt;Of course you can implement custom type, but doesnt that defeat the whole purpose of Using GORM for simplicity.&lt;/p&gt;

&lt;p&gt;What is the best ORM?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flexibility over Queries and SQL&lt;/li&gt;
&lt;li&gt;Easy Schema Migrations&lt;/li&gt;
&lt;li&gt;Safety from SQL Injections&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Inherent problem with every ORMs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Complex unoptimised queries for simple requests&lt;/li&gt;
&lt;li&gt;Less flexibility for optimization&lt;/li&gt;
&lt;li&gt;Hard to execute rollbacks and transactions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why SQLc + pgx/v5 + atlas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Less boilerplate&lt;/li&gt;
&lt;li&gt;Type safety&lt;/li&gt;
&lt;li&gt;Idiomatic Go Code&lt;/li&gt;
&lt;li&gt;Easier to understand and maintain&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Build Your Own ORM like Legos
&lt;/h2&gt;

&lt;p&gt;Here is what worked for me&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2F112500efdtyjvaaokas2.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.amazonaws.com%2Fuploads%2Farticles%2F112500efdtyjvaaokas2.png" alt="Image description" width="800" height="570"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📌 What is This Database Stack?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pgx:&lt;/strong&gt; A performant PostgreSQL driver and toolkit for Go. Think of it as the standard library database/sql on steroids.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sqlc:&lt;/strong&gt; Generates type-safe Go code from your SQL queries at compile time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Atlas:&lt;/strong&gt; Modern database schema management tool, similar to Flyway or Liquibase, with clean DSL and migration workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Benefits Over GORM
&lt;/h2&gt;

&lt;h4&gt;
  
  
  1️⃣ Type Safety and Compile-Time Validation
&lt;/h4&gt;

&lt;p&gt;GORM: Relies on runtime reflection. Mistyped column names or queries can slip into production.&lt;/p&gt;

&lt;p&gt;sqlc: Parses your SQL and generates Go code with exact struct types. If your query or schema changes, your code won’t compile until fixed. Safer, cleaner, no surprises.&lt;/p&gt;

&lt;h4&gt;
  
  
  2️⃣ Better Performance
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;pgx is faster than database/sql+GORM because:&lt;/li&gt;
&lt;li&gt;No reflection overhead.&lt;/li&gt;
&lt;li&gt;Direct native support for PostgreSQL types.&lt;/li&gt;
&lt;li&gt;Optimized connection pooling.&lt;/li&gt;
&lt;li&gt;Support for advanced features like COPY, notifications, and batch queries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Benchmarks consistently show pgx outperforming GORM by 30-50% in high-throughput systems.&lt;/p&gt;

&lt;h4&gt;
  
  
  3️⃣ Clear, Explicit SQL Control
&lt;/h4&gt;

&lt;p&gt;GORM abstracts away SQL, which is fine until you need complex queries, CTEs, window functions, or JSONB operations.&lt;/p&gt;

&lt;p&gt;sqlc lets you write native SQL — as expressive as you need — and still benefit from type-safe Go code generation.&lt;/p&gt;

&lt;p&gt;You control the query plan, indices, and joins — not the ORM.&lt;/p&gt;

&lt;h4&gt;
  
  
  4️⃣ Schema Migrations Done Right with Atlas
&lt;/h4&gt;

&lt;p&gt;GORM Migrations: Rudimentary. Often rely on auto-migrate at runtime (risky in production).&lt;/p&gt;

&lt;p&gt;Atlas: DSL or declarative SQL migrations. Tracks schema state, detects diffs, and generates migration scripts safely.&lt;/p&gt;

&lt;h4&gt;
  
  
  5️⃣ Simpler Debugging and Maintenance
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;No hidden ORM-generated queries.&lt;/li&gt;
&lt;li&gt;You can log, EXPLAIN ANALYZE, or optimize your SQL directly.&lt;/li&gt;
&lt;li&gt;Easier for any PostgreSQL DBA or Go dev to audit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✅ When to Pick GORM Instead
&lt;/h2&gt;

&lt;p&gt;To be fair — GORM still makes sense for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quick prototypes.&lt;/li&gt;
&lt;li&gt;Small internal tools.&lt;/li&gt;
&lt;li&gt;Teams unfamiliar with raw SQL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for high-performance systems, analytics-heavy apps, or codebases where correctness and maintainability matter, pgx + sqlc + Atlas is superior.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Go’s superpower is simplicity and performance — and your database layer should reflect that. GORM trades safety and speed for convenience, but tools like pgx, sqlc, and Atlas give you the best of both worlds: developer ergonomics and production reliability.&lt;/p&gt;

&lt;p&gt;If you care about type safety, performance, and clean database management in Go, it’s worth making this switch.&lt;/p&gt;

</description>
      <category>go</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>learning</category>
    </item>
    <item>
      <title>Build a File Upload API in Golang</title>
      <dc:creator>Sourabh Mandal</dc:creator>
      <pubDate>Sun, 04 May 2025 18:56:20 +0000</pubDate>
      <link>https://dev.to/bitsofmandal-yt/build-a-file-upload-api-in-golang-18oi</link>
      <guid>https://dev.to/bitsofmandal-yt/build-a-file-upload-api-in-golang-18oi</guid>
      <description>&lt;p&gt;Just look around you, we are all surrounded by apps that upload files in one form or another - Facebook, Gmail, Github and even the videos I have uploaded on YouTube is an implementation of some file upload API.&lt;/p&gt;

&lt;p&gt;In fact, I can confidently say that File Upload is Second most implemented feature after the login Page. Still, its hardly the case that many of us can implement this, the right way. So lets fix that.&lt;/p&gt;

&lt;h2&gt;
  
  
  File Uploaded with Local Storage
&lt;/h2&gt;

&lt;p&gt;Lets start with a basic implementation. Trust me its so simple, like a kindergarten syllabus.&lt;/p&gt;

&lt;p&gt;Here we create an API Handler which takes in a file (multipart/form-data) from request, processes the file and save it in the server codebase.&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.amazonaws.com%2Fuploads%2Farticles%2F75332pce677ezyf9tw4y.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.amazonaws.com%2Fuploads%2Farticles%2F75332pce677ezyf9tw4y.png" alt="Simple file upload API" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The above example works, but the problem is, it just works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let’s take it to the NEXT LEVEL and make this API a bit more resilient to client request. Well If you code this example, You my friend will soon be HACKED!!! And this is something not many teach you not even ChatGPT.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This code is more insecure than hard-coded secrets in GitHub repository.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Think about it -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What if I send text data instead of a file?&lt;/li&gt;
&lt;li&gt;What if the file I am sending, is more than 50 GB?&lt;/li&gt;
&lt;li&gt;What if I upload a PDF file when the server is expecting an image file?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s go by an example, suppose you are building user profile picture API. Almost every app has this API be it Github, YouTube, Facebook, Instagram, you name it. Here in this series, we will build a similar API.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Improve this API?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Check the header Content-Type has multipart/form-data&lt;/li&gt;
&lt;li&gt;Set maximum and minimum limits for file size to be uploaded&lt;/li&gt;
&lt;li&gt;Properly sanitise the filename before saving&lt;/li&gt;
&lt;li&gt;Avoid file name clashes, with unique file names&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;First we improve the mime type detector, well what’s wrong with MIME detector. Even though, it works fine we can add some simple optimisation using Maps for O(1) lookups&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.amazonaws.com%2Fuploads%2Farticles%2F2gagetgybwah1nripj9f.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.amazonaws.com%2Fuploads%2Farticles%2F2gagetgybwah1nripj9f.png" alt="Improve Mime Detector" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next We will tackle checking the header section. We are checking the request header &lt;em&gt;(Content-Type)&lt;/em&gt; then the file header for relevant information.&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.amazonaws.com%2Fuploads%2Farticles%2Fsluyk1tti4tl6tn5lgwu.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.amazonaws.com%2Fuploads%2Farticles%2Fsluyk1tti4tl6tn5lgwu.png" alt="Content Type Validation" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since our profile picture API only needs to upload images, we check for accepted file-types only&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.amazonaws.com%2Fuploads%2Farticles%2Felg2o7cb85k2gyeq3e13.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.amazonaws.com%2Fuploads%2Farticles%2Felg2o7cb85k2gyeq3e13.png" alt="Acceptable file type check" width="800" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, we improve the file name, by adding a UUID for uniqueness and replace space with underscores.&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.amazonaws.com%2Fuploads%2Farticles%2Fpsfih2yf1svtlqdl9fg7.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.amazonaws.com%2Fuploads%2Farticles%2Fpsfih2yf1svtlqdl9fg7.png" alt="Unique File Names" width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next post we will further improve this API and move towards more scalable, production ready API with S3 Integration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/sourabhmandal/go-file-upload-api" rel="noopener noreferrer"&gt;Full Code on Github&lt;/a&gt; for your reference&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>go</category>
      <category>opensource</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
