<?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: Abdelhakim mohamed </title>
    <description>The latest articles on Forem by Abdelhakim mohamed  (@hakimmohamed).</description>
    <link>https://forem.com/hakimmohamed</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%2F1451389%2F3b4d0848-78f8-46af-94c5-43a112bc2d0c.jpg</url>
      <title>Forem: Abdelhakim mohamed </title>
      <link>https://forem.com/hakimmohamed</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hakimmohamed"/>
    <language>en</language>
    <item>
      <title>How I Built a Multilingual Food Database Using a Local LLM on an AMD GPU</title>
      <dc:creator>Abdelhakim mohamed </dc:creator>
      <pubDate>Thu, 22 Jan 2026 23:14:09 +0000</pubDate>
      <link>https://forem.com/hakimmohamed/how-i-built-a-multilingual-food-database-using-a-local-llm-on-an-amd-gpu-1f0k</link>
      <guid>https://forem.com/hakimmohamed/how-i-built-a-multilingual-food-database-using-a-local-llm-on-an-amd-gpu-1f0k</guid>
      <description>&lt;p&gt;Two weeks ago, I launched my first app &lt;a href="https://apps.apple.com/us/app/calorie-counter-nutix-ai/id6754726109" rel="noopener noreferrer"&gt;Nutix Ai&lt;/a&gt;, a calorie tracking app focused on simplicity. It's now at 200 downloads, which feels great for a first launch.&lt;/p&gt;

&lt;p&gt;Today I want to share one specific part of the journey: building a food database that supports multiple languages (English, Arabic, Spanish) — not just English like most nutrition apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Multilingual?
&lt;/h2&gt;

&lt;p&gt;Most calorie tracking apps have English-only databases, or their translations feel like afterthoughts. I wanted native speakers to actually be able to search for foods in their language from day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;Simple setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local LLM running on my &lt;strong&gt;AMD 9070XT&lt;/strong&gt; (yes, not NVIDIA — and it worked great)&lt;/li&gt;
&lt;li&gt;Base food data in English&lt;/li&gt;
&lt;li&gt;LLM translates each entry to Arabic and Spanish&lt;/li&gt;
&lt;li&gt;Output stored in my database&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Model Hunt (The Painful Part)
&lt;/h2&gt;

&lt;p&gt;Finding the right model took longer than I expected.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Speed&lt;/th&gt;
&lt;th&gt;Translation Quality (especially Arabic)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DeepSeek 7B&lt;/td&gt;
&lt;td&gt;Slow&lt;/td&gt;
&lt;td&gt;Terrible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DeepSeek 8B&lt;/td&gt;
&lt;td&gt;Slow&lt;/td&gt;
&lt;td&gt;Terrible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DeepSeek 14B&lt;/td&gt;
&lt;td&gt;Very slow&lt;/td&gt;
&lt;td&gt;Still bad&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Llama variants&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Poor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;QWEN&lt;/td&gt;
&lt;td&gt;Had high hopes&lt;/td&gt;
&lt;td&gt;Performed worse than expected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gemma3 7B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~200 tok/s&lt;/td&gt;
&lt;td&gt;Good (1-5% error rate)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gemma3 12B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~80 tok/s&lt;/td&gt;
&lt;td&gt;Great&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Gemma3 was the winner. The 7B was fast but had occasional errors. The 12B took about 2 seconds per food item but was much more reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;~6,000 foods translated into 3 languages in 4 hours, all generated locally on consumer hardware.&lt;/p&gt;

&lt;h2&gt;
  
  
  Known Issues &amp;amp; What's Next
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Database size&lt;/strong&gt; — 6K foods is a start, but I want to expand to 12+ languages and more regional foods&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search&lt;/strong&gt; — The food search still needs work. Fuzzy matching across multiple languages is tricky&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Looking for Suggestions
&lt;/h2&gt;

&lt;p&gt;If you have ideas for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Good sources of food/nutrition data&lt;/li&gt;
&lt;li&gt;Improving multilingual search&lt;/li&gt;
&lt;li&gt;Other languages I should prioritize&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop them in the comments — I'd genuinely appreciate it.&lt;/p&gt;




&lt;p&gt;You can check out the app here: &lt;a href="https://apps.apple.com/us/app/calorie-counter-nutix-ai/id6754726109" rel="noopener noreferrer"&gt;Nutix on the App Store&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>database</category>
      <category>llm</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Built a nutrition app with React Native + Expo SDK 54 that actually feels native on iOS 👀</title>
      <dc:creator>Abdelhakim mohamed </dc:creator>
      <pubDate>Thu, 04 Dec 2025 01:34:03 +0000</pubDate>
      <link>https://forem.com/hakimmohamed/built-a-nutrition-app-with-react-native-expo-sdk-54-that-actually-feels-native-on-ios-g7c</link>
      <guid>https://forem.com/hakimmohamed/built-a-nutrition-app-with-react-native-expo-sdk-54-that-actually-feels-native-on-ios-g7c</guid>
      <description>&lt;p&gt;Opening beta to the first 1000 users for free&lt;br&gt;
Would love your feedback — what feels off? What could be better?&lt;br&gt;
&lt;a href="https://testflight.apple.com/join/ZVUxTEAt" rel="noopener noreferrer"&gt;https://testflight.apple.com/join/ZVUxTEAt&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ios</category>
      <category>reactnative</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>DDoS Protection: How to Monitor, Detect, and Defend Against Attacks</title>
      <dc:creator>Abdelhakim mohamed </dc:creator>
      <pubDate>Sat, 07 Jun 2025 01:09:13 +0000</pubDate>
      <link>https://forem.com/hakimmohamed/ddos-protection-how-to-monitor-detect-and-defend-against-attacks-5aji</link>
      <guid>https://forem.com/hakimmohamed/ddos-protection-how-to-monitor-detect-and-defend-against-attacks-5aji</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;The Midnight Server Meltdown: What To Do When Your Backend Goes Silent&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine this: it’s a peaceful night, maybe you’re winding down, enjoying a movie, or catching up on some sleep. Suddenly, your phone rings it's your client or your boss. Their voice is urgent:&lt;/p&gt;

&lt;p&gt;“The server is down. Customers can’t access anything. Everything’s super slow!”&lt;/p&gt;

&lt;p&gt;Your heart races. You scramble to your desk, half awake but fully alert now. You SSH into the server or open your monitoring dashboard nothing seems obviously broken. You check the logs they’re there, but not helpful. You hit a few endpoints they respond… eventually. What used to take 200ms is now crawling at 10 seconds or, even worse, timing out.&lt;/p&gt;

&lt;p&gt;At this point, panic is knocking on your door.&lt;/p&gt;

&lt;p&gt;You start digging deeper. CPU usage is spiking, memory is being eaten up, and your server is getting hammered with requests. But they aren’t normal requests they’re overwhelming, coming from a swarm of IPs. That’s when it hits you:&lt;/p&gt;

&lt;p&gt;You're under a DDoS attack. Someone, somewhere, decided to bring your server to its knees.&lt;/p&gt;

&lt;p&gt;Now the real question is what do you do to prevent this from happening again?&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%2Fxfugalkaicbgzoycbqfv.gif" 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%2Fxfugalkaicbgzoycbqfv.gif" alt="Image description" width="540" height="400"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;Set Up Rate Limiting&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Limit how many requests each IP can make per second using Nginx. This helps slow down bots and flood attempts before they hurt your server.&lt;/p&gt;

&lt;p&gt;If your using Nginx consider adding this inside &lt;code&gt;nginx.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http {
  limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

  server {
    listen 80;

    location /api/ {
      limit_req zone=mylimit burst=20 nodelay;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;10r/s&lt;/strong&gt; Limits each IP address to a maximum of 10 requests per second.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;zone=mylimit:10m&lt;/strong&gt; Creates a shared memory zone named &lt;code&gt;mylimit&lt;/code&gt; that can track up to approximately 160,000 unique IP addresses with 10MB of memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;burst=20&lt;/strong&gt; Allows short traffic spikes by permitting up to 20 excess requests to queue temporarily before triggering rate limiting.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;Monitor Abusive IPs&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Keep an eye on which IPs are getting rate-limited. If the same ones show up repeatedly, it’s a red flag something is trying to break in or overwhelm your system.&lt;/p&gt;

&lt;p&gt;Add the following to your &lt;code&gt;nginx.conf&lt;/code&gt; to enable logging:&lt;br&gt;
This ensures that NGINX logs blocked or rate-limited requests along with the client’s IP address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http {
  limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
  log_format rate_limited '$remote_addr - $request - $status - $http_user_agent';

  map $status $log_rate_limit {
    503     1;
    default 0;
  }

  access_log /var/log/nginx/ratelimited.log rate_limited if=$log_rate_limit;

  server {
    listen 80;

    location /api/ {
      limit_req zone=mylimit burst=20 nodelay;
    }
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;&lt;em&gt;Automatically Ban Suspicious IPs&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Use tools like fail2ban to detect patterns of abuse and block the source IP for a set period. This adds another layer of defense beyond just rate limiting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt install fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/etc/fail2ban/jail.conf&lt;/code&gt;: Default config&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/etc/fail2ban/jail.d/&lt;/code&gt;: Your custom jail files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/etc/fail2ban/filter.d/&lt;/code&gt;: Contains filters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s say we want to block any IP that gets rate-limited too often (&lt;code&gt;503&lt;/code&gt; status in your Nginx log).&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Create a custom jail
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;/etc/fail2ban/jail.d/nginx-limit.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[nginx-limit]&lt;/span&gt;
&lt;span class="py"&gt;enabled&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;http,https&lt;/span&gt;
&lt;span class="py"&gt;filter&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;nginx-limit&lt;/span&gt;
&lt;span class="py"&gt;logpath&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;/var/log/nginx/ratelimited.log&lt;/span&gt;
&lt;span class="py"&gt;maxretry&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;10&lt;/span&gt;
&lt;span class="py"&gt;findtime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;60&lt;/span&gt;
&lt;span class="py"&gt;bantime&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;600&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Ban IPs that match the filter 10 times in 60 seconds&lt;/li&gt;
&lt;li&gt;Ban them for 10 minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Create the filter file&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;/etc/fail2ban/filter.d/nginx-limit.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Definition]&lt;/span&gt;
&lt;span class="py"&gt;failregex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;^&amp;lt;HOST&amp;gt; - .+ - 503 - .*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This regex matches lines like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;192.168.1.5 - /api/endpoint - 503 - curl/7.58.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It extracts the &lt;code&gt;&amp;lt;HOST&amp;gt;&lt;/code&gt; (IP address) and counts the hits.&lt;/p&gt;

&lt;p&gt;Start or Restart Fail2Ban&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check Status and Banned IPs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;fail2ban-client status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check specific jail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;fail2ban-client status nginx-limit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unban a specific IP (if needed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;fail2ban-client &lt;span class="nb"&gt;set &lt;/span&gt;nginx-limit unbanip 192.168.1.5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Use reCAPTCHA to Stop Bots Cold&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Especially for sensitive actions like login or guest access, adding Google reCAPTCHA can stop automated scripts in their tracks, without bothering real users much.&lt;/p&gt;

&lt;p&gt;Thanks for reading my article 🙌&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%2Fywk9tph8tmm6trwldt0v.gif" 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%2Fywk9tph8tmm6trwldt0v.gif" alt="Image description" width="350" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Understanding Express Routes, Controllers, and Services</title>
      <dc:creator>Abdelhakim mohamed </dc:creator>
      <pubDate>Sat, 28 Sep 2024 21:51:42 +0000</pubDate>
      <link>https://forem.com/hakimmohamed/understanding-express-routes-controllers-and-services-a-beginners-guide-nodejs-tutorial-part-12-2cd4</link>
      <guid>https://forem.com/hakimmohamed/understanding-express-routes-controllers-and-services-a-beginners-guide-nodejs-tutorial-part-12-2cd4</guid>
      <description>&lt;h4&gt;
  
  
  Introduction
&lt;/h4&gt;

&lt;p&gt;If you're new to Express.js or Node.js, you might have heard about "routes," "controllers," and "services." At first, these terms sound technical, but trust me understanding them can really transform how you build your apps. Not only will your code look cleaner, but it'll also make your life easier as your app grows. In this guide, we'll break down what each of these components does and why separating them is a game-changer for any Express project.&lt;/p&gt;

&lt;p&gt;Let's start by setting up a basic Express app and organizing everything like a pro!&lt;/p&gt;

&lt;h4&gt;
  
  
  Setting Up Your Project
&lt;/h4&gt;

&lt;p&gt;First things first let’s create a new Node.js project. Fire up your terminal and follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Initialize your project&lt;/strong&gt; by running:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install Express&lt;/strong&gt; to get the magic going:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   npm &lt;span class="nb"&gt;install &lt;/span&gt;express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now, let’s structure our project to keep things clean. Here’s how your folder setup should look:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-express-app
│
├── src
│   ├── controllers
│   ├── routes
│   ├── services
│
├── app.js
└── package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fcmbce10i2adtwdwe7m65.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%2Fcmbce10i2adtwdwe7m65.png" alt="Image description" width="440" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll walk through what goes into each of these folders. Don't worry if this looks like a lot; it's easier than it seems!.&lt;/p&gt;




&lt;h4&gt;
  
  
  Routes: The Traffic Cops of Your App
&lt;/h4&gt;

&lt;p&gt;Think of routes as traffic cops—they decide where each request should go. They don’t do much heavy lifting themselves but delegate the real work to controllers.&lt;/p&gt;

&lt;p&gt;Here’s how you can create a basic route for user-related requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/routes/userRoutes.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../controllers/userController&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Define routes&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userController&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAllUsers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userController&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, when someone hits &lt;code&gt;/users&lt;/code&gt; with a GET request, our app calls the &lt;code&gt;getAllUsers&lt;/code&gt; function from the controller. Pretty neat, right?&lt;/p&gt;




&lt;h4&gt;
  
  
  Controllers: The Brains of the Operation
&lt;/h4&gt;

&lt;p&gt;Now, controllers are where the logic happens. They take what the routes send their way and handle all the complex stuff like fetching data or saving a new user.&lt;/p&gt;

&lt;p&gt;Let’s build a simple controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/controllers/userController.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../services/userService&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAllUsers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchUsers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&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="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&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="nx"&gt;newUser&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;Here, the controller is getting data from a service (which we'll talk about next) and sending a response back. Think of the controller as the middleman between routes and services—it doesn't handle data directly but knows who to ask.&lt;/p&gt;




&lt;h4&gt;
  
  
  Services: The Real Workers
&lt;/h4&gt;

&lt;p&gt;Services handle the real business logic, like interacting with a database or managing data. This keeps your controllers nice and clean.&lt;/p&gt;

&lt;p&gt;Check out this basic service that manages a list of users:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/services/userService.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetchUsers&lt;/span&gt; &lt;span class="o"&gt;=&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&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="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;user&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;Here, we’re storing users in an array (for simplicity). Services help keep your controllers lightweight and focused on handling requests instead of worrying about the data itself.&lt;/p&gt;




&lt;h4&gt;
  
  
  Bringing It All Together in &lt;code&gt;app.js&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Once you have your routes, controllers, and services set up, you need to wire everything together in your main application file (&lt;code&gt;app.js&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userRoutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/routes/userRoutes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&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="nx"&gt;userRoutes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server running on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;In this file, we tell Express to use our &lt;code&gt;userRoutes&lt;/code&gt; for any requests that start with &lt;code&gt;/api&lt;/code&gt;. This makes it easy to organize all your routes under one common base path.&lt;/p&gt;




&lt;h4&gt;
  
  
  How Your Final Directory Should Look
&lt;/h4&gt;

&lt;p&gt;Once you've set up everything, your directory structure should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-express-app
│
├── src
│   ├── controllers
│   │   └── userController.js
│   ├── routes
│   │   └── userRoutes.js
│   ├── services
│   │   └── userService.js
│
├── app.js
└── package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  Wrapping Up
&lt;/h4&gt;

&lt;p&gt;By splitting your app into routes, controllers, and services, you've just taken the first step towards writing better, cleaner code! Not only does this make your project easier to manage now, but it also saves you headaches as your app gets more complex. Plus, your future self (and your teammates) will thank you!&lt;/p&gt;

&lt;p&gt;Happy Coding😊&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
