<?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>Forem: Favor Charles Owuor</title>
    <description>The latest articles on Forem by Favor Charles Owuor (@fcharles).</description>
    <link>https://forem.com/fcharles</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%2F3718960%2F45a605d6-431f-4c09-a25b-97266a22a9c7.jpg</url>
      <title>Forem: Favor Charles Owuor</title>
      <link>https://forem.com/fcharles</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/fcharles"/>
    <language>en</language>
    <item>
      <title>Understanding Back-End Project Structures in Go: A Guide to Separate Concerns</title>
      <dc:creator>Favor Charles Owuor</dc:creator>
      <pubDate>Wed, 11 Mar 2026 10:11:18 +0000</pubDate>
      <link>https://forem.com/fcharles/understanding-back-end-project-structures-in-go-a-guide-to-separate-concerns-9ef</link>
      <guid>https://forem.com/fcharles/understanding-back-end-project-structures-in-go-a-guide-to-separate-concerns-9ef</guid>
      <description>&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%2Fi9l0mov05wqmk6sucwbj.jpg" 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%2Fi9l0mov05wqmk6sucwbj.jpg" alt="image" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
&lt;small&gt;Code on laptop with hands typing in the dark Free Photo&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;When I first started writing Go to make a back-end API, I did what most people do — threw everything into one file. The handler, the business logic, the database calls, all of it crammed together. It worked, until it didn't. The moment I tried to refactor or write tests, three things broke. Sound familiar?&lt;/p&gt;

&lt;p&gt;The fix isn't complicated, but it does require a bit of upfront thinking about how you organize your code. In this article I'll walk through a project structure that I learned recently. Companies like Uber and Netflix use similar patterns to manage large systems. It allows for scaling while remaining resilient to failures.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Bother Separating Concerns?
&lt;/h2&gt;

&lt;p&gt;Most developers have all written messy code at some point. But once things are separated, the breathing room allows for testing, changes and reuse.&lt;/p&gt;

&lt;p&gt;The idea behind separation of concerns is simple: each part of your code should have one job and one job only. When your handler is doing database queries and business logic, changes and tests can get tedious&lt;/p&gt;
&lt;h2&gt;
  
  
  The Four Layers
&lt;/h2&gt;

&lt;p&gt;For this project we use four layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model&lt;/strong&gt; — the data structure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repository&lt;/strong&gt; — database access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service&lt;/strong&gt; — business logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handler&lt;/strong&gt; — HTTP request handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The payoff is that the same core logic runs with different routers (standard &lt;code&gt;net/http&lt;/code&gt;, Gin, or Chi) and different databases (SQLite or MongoDB) without touching the middle layers at all.&lt;/p&gt;


&lt;h3&gt;
  
  
  1. Model
&lt;/h3&gt;

&lt;p&gt;This is just the shape of your data. No HTTP, no database — just a structure, or skeleton.&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;type&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;        &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Title&lt;/span&gt;     &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Completed&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything else in the app revolves around this.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Repository
&lt;/h3&gt;

&lt;p&gt;The repository is the only layer that talks to the database. Everything above it just calls repository methods.&lt;/p&gt;

&lt;p&gt;You define an interface first:&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;type&lt;/span&gt; &lt;span class="n"&gt;TodoRepository&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;
    &lt;span class="n"&gt;GetByID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;GetAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;
    &lt;span class="n"&gt;Delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&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;error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you implement it for each database. Want to switch from SQLite to MongoDB? Write a new implementation, swap it in — nothing else changes.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Service
&lt;/h3&gt;

&lt;p&gt;This is where your actual business logic lives. The service interact with whatever database being used, and it has nothing to do with HTTP. It just takes inputs, does something meaningful with them, and returns a result.&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;type&lt;/span&gt; &lt;span class="n"&gt;TodoService&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Repo&lt;/span&gt; &lt;span class="n"&gt;TodoRepository&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;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;TodoService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Todo&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;uuid&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Completed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;CreatedAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;(),&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="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&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;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice it only knows about the repository interface. That's the point.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Handler
&lt;/h3&gt;

&lt;p&gt;Handlers sit at the edge of the application and deal with HTTP. They decode requests, call the service, and write responses.&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;TodoHandler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Create&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="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"title"`&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;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;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;todo&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="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Title&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="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="n"&gt;err&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="m"&gt;500&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;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;todo&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;Because handlers only talk to the service (not the database), you can write different handlers for different routers — standard &lt;code&gt;net/http&lt;/code&gt;, Gin, Chi — and they all call the exact same service methods underneath.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It All Fits Together
&lt;/h2&gt;

&lt;p&gt;Here's the flow when a request comes in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP Request → Handler → Service → Repository → Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And back:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database → Repository → Service → Handler → HTTP Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer only knows about the one directly below it. The handler doesn't know about the database. The service doesn't know about HTTP. The repository doesn't know about business logic. No bleed-through.&lt;/p&gt;

&lt;p&gt;In practice, wiring it all together in &lt;code&gt;main.go&lt;/code&gt; looks like this:&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;repo&lt;/span&gt;    &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSQLiteRepo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTodoService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewStdHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;router&lt;/span&gt;  &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewStdRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want MongoDB instead? Change one line:&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;repo&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewMongoRepo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want Gin instead of &lt;code&gt;net/http&lt;/code&gt;? Change one line:&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;handler&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewGinHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;router&lt;/span&gt;  &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewGinRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The service layer doesn't move. The repository interface doesn't move. Only the edges change.&lt;/p&gt;

&lt;p&gt;This is the resulting file structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── cmd
│   └── main.go
├── internal
│   └── handlers
│   └── models
│   └── repository
│   └── services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;This structure might feel like extra work upfront compared to dumping everything in one file and it is. This is true only for small projects. But the moment you need to write a test, switch a database, or hand the project to someone else, you'll be glad you did it.&lt;/p&gt;

&lt;p&gt;I built the full working example of this with a &lt;a href="https://github.com/f18charles/go-todolist.git" rel="noopener noreferrer"&gt;Todo List API&lt;/a&gt; — complete with SQLite and MongoDB repositories, and handlers for &lt;code&gt;net/http&lt;/code&gt;, Gin, and Chi. Take a look if you want to see all the pieces in place.&lt;/p&gt;

&lt;p&gt;Start with this structure even on small projects. It's a habit that pays off fast.&lt;/p&gt;

</description>
      <category>go</category>
      <category>backend</category>
      <category>backenddevelopment</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>A Compiled Review</title>
      <dc:creator>Favor Charles Owuor</dc:creator>
      <pubDate>Tue, 17 Feb 2026 20:50:03 +0000</pubDate>
      <link>https://forem.com/fcharles/a-compiled-review-28kl</link>
      <guid>https://forem.com/fcharles/a-compiled-review-28kl</guid>
      <description>&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%2Fimages.pexels.com%2Fphotos%2F965345%2Fpexels-photo-965345.jpeg" 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%2Fimages.pexels.com%2Fphotos%2F965345%2Fpexels-photo-965345.jpeg" alt="compiled languages" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a new developer using Go, I often wondered how different other compiled languages really are. I was advised to learn Go first because of its simplicity and speed. But what about the others? What are they and what can they offer.&lt;/p&gt;

&lt;p&gt;There are many compiled languages, both popular and obscure. In this article, we focus on just four: C, C++, Rust, and Go. Let’s examine what each brings to the table.&lt;/p&gt;




&lt;h2&gt;
  
  
  Origins and Boom Years
&lt;/h2&gt;

&lt;p&gt;C appeared in 1972, created by Dennis Ritchie at Bell Labs. It was developed to overcome limitations in B and BCPL and to build the Unix operating system. C provided low level memory access while maintaining structured programming concepts, which made it ideal for operating systems and critical performance software.&lt;/p&gt;

&lt;p&gt;C++ was introduced in 1985 by Bjarne Stroustrup. It expanded C with object oriented programming features. The language gained strong popularity in the late 1990s and early 2000s during the rise of large scale software systems and game development.&lt;/p&gt;

&lt;p&gt;Go was released by Google in 2009. It was influenced by C but designed to reduce complexity. It gained traction in the mid 2010s alongside cloud computing and microservices architecture due to its fast compilation and built in concurrency support.&lt;/p&gt;

&lt;p&gt;Rust reached its stable release in 2015 from Mozilla, created by Graydon Hoare. It grew rapidly in the 2020s because of its strict memory safety model and strong performance guarantees. Many companies adopted it to reduce bugs related to memory errors.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Choose One and Leave the Other
&lt;/h2&gt;

&lt;p&gt;As software systems became more complex, languages evolved to solve new problems. C provides control and performance. C++ adds abstraction to manage larger systems. Rust enforces memory safety, and Go simplifies concurrency and improves developer productivity.&lt;/p&gt;

&lt;p&gt;Each language solves a different problem. C and C++ offer flexibility but require careful management. Rust prevents many classes of bugs at compile time. Go focuses on clarity and fast builds, making it practical for distributed systems and cloud services.&lt;/p&gt;

&lt;p&gt;There is no one language that is better. There are trade offs. The best choice depends on what you as the developer want and/or need from whatever language you choose.&lt;/p&gt;




&lt;h2&gt;
  
  
  Concurrency Benchmark Across Languages
&lt;/h2&gt;

&lt;p&gt;This test computes the sum of squares of the first 100,000,000 numbers split across 4 threads or goroutines. Execution time is measured in milliseconds.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;Sum&lt;/th&gt;
&lt;th&gt;Time (ms)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;672,921,401,752,298,880&lt;/td&gt;
&lt;td&gt;113.4060&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C++&lt;/td&gt;
&lt;td&gt;672,921,401,752,298,880&lt;/td&gt;
&lt;td&gt;80.5660&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;333,333,338,333,333,350,000&lt;/td&gt;
&lt;td&gt;1171.7290&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;672,921,401,752,298,880&lt;/td&gt;
&lt;td&gt;48.8229&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/f18charles/c7659fc55323cb43b153486052a01a5a" rel="noopener noreferrer"&gt;View Code&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Test Matters
&lt;/h3&gt;

&lt;p&gt;These benchmarks show more than execution speed. They reveal how each language approaches concurrency and numerical safety under the same workload.  While C, C++, and Go completed the computation without warnings. You see the computed numbers were too big for int64 so Rust refused silent overflow and required a larger integer type i.e. int128 while the other languages used the values as is.&lt;/p&gt;




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

&lt;p&gt;Compiled languages are not interchangeable tools. Each reflects different priorities in software engineering. C and C++ reward experience and precision. Rust enforces correctness and offers strong safety guarantees. Go values simplicity and productivity.&lt;/p&gt;

&lt;p&gt;Understanding these differences allows developers to choose intentionally instead of following trends. The right language is not about which is fastest. It is about which aligns best with the problem you are solving.&lt;/p&gt;

</description>
      <category>go</category>
      <category>c</category>
      <category>cpp</category>
      <category>rust</category>
    </item>
    <item>
      <title>Building an AI Agent for Business Viability In a 24 Hour Hackathon</title>
      <dc:creator>Favor Charles Owuor</dc:creator>
      <pubDate>Thu, 05 Feb 2026 11:16:59 +0000</pubDate>
      <link>https://forem.com/fcharles/building-an-ai-agent-for-business-viability-in-a-24-hour-hackathon-5da0</link>
      <guid>https://forem.com/fcharles/building-an-ai-agent-for-business-viability-in-a-24-hour-hackathon-5da0</guid>
      <description>&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%2Fz5n18g1si3glzk2qk67g.jpg" 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%2Fz5n18g1si3glzk2qk67g.jpg" alt="hackathon" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I recently participated in a hackathon focused on building AI agents. The main rule was clear. AI could not be the product by itself. It had to support a real system.&lt;/p&gt;

&lt;p&gt;Our team had five members. We worked for just over 24 hours. The pressure was real. So was the ambition.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem We Chose
&lt;/h2&gt;

&lt;p&gt;Many people have business ideas. Very few know if those ideas make financial sense before investing money.&lt;/p&gt;

&lt;p&gt;We saw a gap. People needed a way to test ideas early, using numbers and logic, not hope and vibes.&lt;/p&gt;

&lt;p&gt;Our goal was to build a tool that helps someone answer a simple question. Is this business idea viable or not?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Idea
&lt;/h2&gt;

&lt;p&gt;We built a business viability checker called Microbiz.&lt;/p&gt;

&lt;p&gt;The user enters structured inputs. These include starting capital, pricing, expected monthly sales, operating costs, and time horizon.&lt;/p&gt;

&lt;p&gt;At the core of the system is a calculation engine. It computes revenue, total costs, profit margins, and sustainability indicators over time.&lt;/p&gt;

&lt;p&gt;This part was fully deterministic. Just math and logic to get consistent results every time.&lt;/p&gt;

&lt;p&gt;We wanted users to trust the numbers first.&lt;/p&gt;

&lt;h2&gt;
  
  
  System Design and Team Roles
&lt;/h2&gt;

&lt;p&gt;We used Django for the back-end. I worked mainly on this part.&lt;/p&gt;

&lt;p&gt;My role involved handling inputs, validating data, running financial calculations, and structuring outputs. I also prepared the data so it could be consumed cleanly by the AI component.&lt;/p&gt;

&lt;p&gt;Two teammates worked on the front-end. Their focus was speed and clarity. They designed an interface that made complex inputs easier to manage under time pressure.&lt;/p&gt;

&lt;p&gt;Another teammate focused on prompt engineering. Their job was to control how the AI reasoned, what context it received, and how it communicated results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the AI Fit In
&lt;/h2&gt;

&lt;p&gt;We integrated Groq AI using an API key.&lt;/p&gt;

&lt;p&gt;The AI did not redo the calculations. It received the raw user inputs plus all internal computed values.&lt;/p&gt;

&lt;p&gt;From there, it performed higher level reasoning. It considered market conditions, pricing realism, demand signals, and feasibility based on what is currently visible online.&lt;/p&gt;

&lt;p&gt;The AI produced one output; it gave a recommendation on whether the business idea was likely viable or risky under the given assumptions. It stated reasons based on the input given&lt;/p&gt;

&lt;p&gt;The AI was meant to support decisions, not motivate or sell dreams.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Reality Check
&lt;/h2&gt;

&lt;p&gt;We underestimated the workload.&lt;/p&gt;

&lt;p&gt;Writing formulas was not the hardest part. Defining realistic assumptions was.&lt;/p&gt;

&lt;p&gt;We had to research small business behavior, cost structures, margins, and failure points. That research slowed development since none of us have any financial or business backgrounds, but skipping it would have made the system useless.&lt;/p&gt;

&lt;p&gt;Time worked against us. Features piled up faster than we could finish them. We created and broke code again and again until we got to a middle ground that wasn't perfect but works well enough.&lt;/p&gt;

&lt;p&gt;Despite working through the night, we did not complete everything we planned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pitch Day
&lt;/h2&gt;

&lt;p&gt;Before demos, all teams were called to a common area and given three minutes for an elevator pitch with slides and demos. When our turn came, we presented with nothing but words.&lt;br&gt;
It still worked in our favor since we understood the product deeply. We explained the problem clearly and answered the judges' questions without much thinking. We explained why pure AI was not enough and  how logic and AI reasoning worked together.&lt;/p&gt;

&lt;p&gt;We did not make the podium. However, the judges told us the product was useful and encouraged us to keep building it. That feedback mattered more than placement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;First, scope matters. AI agents amplify systems. They do not replace solid foundations.&lt;/p&gt;

&lt;p&gt;If your assumptions are wrong, AI makes the output confidently wrong. It's just how systems work; GIGO (Garbage In Garbage Out)&lt;/p&gt;

&lt;p&gt;Second, research is not optional. Especially when dealing with money and real people.&lt;/p&gt;

&lt;p&gt;Third, clear ownership helps under pressure. Back-end, front-end, and AI roles stayed mostly separate. That prevented chaos.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Comes Next
&lt;/h2&gt;

&lt;p&gt;This project is not finished and it most definitely won't be shelved.&lt;/p&gt;

&lt;p&gt;Our next step is reducing the amount of input required. The system should do more inference with less user effort so that even those who are green in business but would still like to start one can do it but with more knowledge.&lt;/p&gt;

&lt;p&gt;Long term, the goal is idea discovery. The system should recommend business ideas directly, starting with specific regions in Kenya. And as the scope expands maybe even worldwide. Maybe one day you may even interact with it.&lt;/p&gt;

&lt;p&gt;The hackathon may have ended, but the product will live on.&lt;/p&gt;

</description>
      <category>django</category>
      <category>ai</category>
      <category>agents</category>
      <category>hackathon</category>
    </item>
  </channel>
</rss>
