<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Building a Profile API (HNG 13)]]></title><description><![CDATA[Building a Profile API (HNG 13)]]></description><link>https://hng-13-profile-api.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 08 Nov 2026 08:10:43 GMT</lastBuildDate><atom:link href="https://hng-13-profile-api.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Building a Profile API with MVC Architecture: My HNG13 Internship Journey]]></title><description><![CDATA[As part of my HNG13 Backend Internship, I was tasked with building a RESTful API that returns profile information along with a dynamic cat fact. While this…]]></description><link>https://hng-13-profile-api.hashnode.dev/building-a-profile-api-with-mvc-architecture-my-hng13-internship-journey</link><guid isPermaLink="true">https://hng-13-profile-api.hashnode.dev/building-a-profile-api-with-mvc-architecture-my-hng13-internship-journey</guid><dc:creator><![CDATA[Osuolale Abdullahi]]></dc:creator><pubDate>Thu, 16 Oct 2025 21:42:38 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>As part of my HNG13 Backend Internship, I was tasked with building a RESTful API that returns profile information along with a dynamic cat fact. While this might sound straightforward, the real challenge was to implement it using the <strong>Model-View-Controller (MVC)</strong> architectural pattern—a design pattern that's fundamental to building scalable, maintainable web applications.</p>
<p>In this post, I'll walk you through my entire development process, the challenges I faced, architectural decisions I made, and most importantly, what this experience taught me about professional backend development.</p>
<h2 id="heading-the-task-requirements"><strong>🎯 The Task Requirements</strong></h2>
<p>The requirements were clear but deceptively simple:</p>
<ol>
<li><p>Create a <code>/me</code> endpoint that returns my profile information</p>
</li>
<li><p>Include a <strong>dynamic timestamp</strong> (updates with each request)</p>
</li>
<li><p>Fetch and display a <strong>random cat fact</strong> from an external API</p>
</li>
<li><p>Implement the solution using <strong>MVC architecture</strong></p>
</li>
<li><p>Handle errors gracefully with proper fallback mechanisms</p>
</li>
</ol>
<p><strong>Expected Response Format:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"status"</span>: <span class="hljs-string">"success"</span>,
  <span class="hljs-attr">"user"</span>: {
    <span class="hljs-attr">"email"</span>: <span class="hljs-string">"osuolaleabdullahi@gmail.com"</span>,
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Jelili Abdullahi A."</span>,
    <span class="hljs-attr">"stack"</span>: <span class="hljs-string">"Node.js/Express"</span>
  },
  <span class="hljs-attr">"timestamp"</span>: <span class="hljs-string">"2025-10-16T17:57:25.242Z"</span>,
  <span class="hljs-attr">"fact"</span>: <span class="hljs-string">"Cats spend 70% of their lives sleeping!"</span>
}
</code></pre>
<h2 id="heading-understanding-mvc-architecture"><strong>🤔 Understanding MVC Architecture</strong></h2>
<p>Before diving into code, I spent time understanding what MVC actually means in the context of a Node.js/Express API. Here's what I learned:</p>
<h3 id="heading-model"><strong>Model 🗄️</strong></h3>
<ul>
<li><p>Represents the data structure and business logic</p>
</li>
<li><p>In my case: <code>User.js</code> defines the user data structure and methods to retrieve user information</p>
</li>
<li><p>Handles data validation and manipulation</p>
</li>
</ul>
<h3 id="heading-view"><strong>View 📱</strong></h3>
<ul>
<li><p>In REST APIs, the "view" is the JSON response format</p>
</li>
<li><p>Controls how data is presented to the client</p>
</li>
<li><p>Handled in the controller layer</p>
</li>
</ul>
<h3 id="heading-controller"><strong>Controller 🎛️</strong></h3>
<ul>
<li><p>Acts as the middleman between models and the client</p>
</li>
<li><p>Processes incoming HTTP requests</p>
</li>
<li><p>Calls services/models to get data</p>
</li>
<li><p>Formats and sends responses</p>
</li>
</ul>
<h2 id="heading-project-architecture"><strong>🏗️ Project Architecture</strong></h2>
<p>I organized my project into a clean, modular structure:</p>
<pre><code class="lang-plaintext">hng13-profile-task-0/
│
├── index.js                    # Application entry point
├── config/                     # Configuration files
│   └── constants.js           # API URLs, timeouts, fallback messages
├── models/                     # Data models
│   └── User.js                # User model with business logic
├── controllers/                # Request handlers
│   └── profileController.js   # Profile endpoint controller
├── routes/                     # Route definitions
│   └── profileRoutes.js       # Profile routes
├── services/                   # Business logic &amp; external APIs
│   └── catFactService.js      # Cat Facts API integration
└── middlewares/                # Custom middlewares
    └── errorHandler.js        # Error handling middleware
</code></pre>
<p>This structure ensures <strong>separation of concerns</strong>—each file has a single, well-defined responsibility.</p>
<h2 id="heading-implementation-journey"><strong>💻 Implementation Journey</strong></h2>
<h3 id="heading-step-1-setting-up-the-foundation"><strong>Step 1: Setting Up the Foundation</strong></h3>
<p>I started by creating the entry point (<code>index.js</code>) and establishing the basic Express server:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> app = express();

<span class="hljs-comment">// Configuration</span>
<span class="hljs-keyword">const</span> { PORT } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./config/constants"</span>);

<span class="hljs-comment">// Middlewares</span>
<span class="hljs-keyword">const</span> { errorHandler, notFoundHandler } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./middlewares/errorHandler"</span>);

<span class="hljs-comment">// Routes</span>
<span class="hljs-keyword">const</span> profileRoutes = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./routes/profileRoutes"</span>);

<span class="hljs-comment">// Apply middlewares</span>
app.use(express.json());

<span class="hljs-comment">// Mount routes</span>
app.use(<span class="hljs-string">"/"</span>, profileRoutes);

<span class="hljs-comment">// Error handling (must be last)</span>
app.use(notFoundHandler);
app.use(errorHandler);

<span class="hljs-comment">// Start server</span>
app.listen(PORT, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server is running on port <span class="hljs-subst">${PORT}</span>`</span>);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Environment: <span class="hljs-subst">${process.env.NODE_ENV || <span class="hljs-string">"development"</span>}</span>`</span>);
});
</code></pre>
<p><strong>Key Decision:</strong> I made sure error handlers are registered <strong>last</strong> in the middleware chain. This is crucial because Express processes middleware in order, and error handlers need to catch errors from all previous middleware.</p>
<h3 id="heading-step-2-creating-the-user-model"><strong>Step 2: Creating the User Model</strong></h3>
<p>The <code>User</code> model encapsulates user data and provides methods to work with it:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>{
  <span class="hljs-keyword">constructor</span>(email, name, stack) {
    <span class="hljs-built_in">this</span>.email = email;
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.stack = stack;
  }

  <span class="hljs-comment">// Get user data as plain object</span>
  toJSON() {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">email</span>: <span class="hljs-built_in">this</span>.email,
      <span class="hljs-attr">name</span>: <span class="hljs-built_in">this</span>.name,
      <span class="hljs-attr">stack</span>: <span class="hljs-built_in">this</span>.stack,
    };
  }

  <span class="hljs-comment">// Static method to get current user</span>
  <span class="hljs-keyword">static</span> getCurrentUser() {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> User(
      <span class="hljs-string">"osuolaleabdullahi@gmail.com"</span>,
      <span class="hljs-string">"Jelili Abdullahi A."</span>,
      <span class="hljs-string">"Node.js/Express"</span>
    );
  }
}

<span class="hljs-built_in">module</span>.exports = User;
</code></pre>
<p><strong>Why a class?</strong> Using a class provides a clear structure and makes it easy to add validation logic, computed properties, or database integration in the future. The <code>toJSON()</code> method ensures consistent data formatting.</p>
<h3 id="heading-step-3-building-the-cat-fact-service"><strong>Step 3: Building the Cat Fact Service</strong></h3>
<p>This was one of the most interesting parts. I needed to:</p>
<ul>
<li><p>Make HTTP requests to an external API</p>
</li>
<li><p>Handle timeouts (external APIs can be slow)</p>
</li>
<li><p>Provide fallback data if the API fails</p>
</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> axios = <span class="hljs-built_in">require</span>(<span class="hljs-string">"axios"</span>);
<span class="hljs-keyword">const</span> {
  CAT_FACT_API_URL,
  API_TIMEOUT,
  FALLBACK_MESSAGES,
} = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../config/constants"</span>);

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CatFactService</span> </span>{
  <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> getCatFact() {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios.get(CAT_FACT_API_URL, {
        <span class="hljs-attr">timeout</span>: API_TIMEOUT, <span class="hljs-comment">// 5 seconds</span>
      });

      <span class="hljs-keyword">const</span> fact = response?.data?.fact;

      <span class="hljs-keyword">if</span> (!fact) {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"No fact in response"</span>);
      }

      <span class="hljs-keyword">return</span> fact;
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error fetching cat fact:"</span>, error?.message);
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.getFallbackMessage();
    }
  }

  <span class="hljs-keyword">static</span> getFallbackMessage() {
    <span class="hljs-keyword">const</span> randomMessage =
      FALLBACK_MESSAGES[<span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * FALLBACK_MESSAGES.length)];
    <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${randomMessage}</span> (Cat Facts API temporarily unavailable)`</span>;
  }
}

<span class="hljs-built_in">module</span>.exports = CatFactService;
</code></pre>
<p><strong>Key Learnings:</strong></p>
<ul>
<li><p><strong>Always set timeouts</strong> for external API calls (I used 5 seconds)</p>
</li>
<li><p><strong>Never trust external APIs</strong> to always be available</p>
</li>
<li><p><strong>Optional chaining</strong> (<code>response?.data?.fact</code>) prevents null reference errors</p>
</li>
<li><p><strong>Graceful degradation</strong> is better than complete failure</p>
</li>
</ul>
<h3 id="heading-step-4-implementing-the-controller"><strong>Step 4: Implementing the Controller</strong></h3>
<p>The controller orchestrates everything:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../models/User"</span>);
<span class="hljs-keyword">const</span> CatFactService = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../services/catFactService"</span>);

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProfileController</span> </span>{
  <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> getProfile(req, res) {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-comment">// Get user data</span>
      <span class="hljs-keyword">const</span> user = User.getCurrentUser();

      <span class="hljs-comment">// Fetch cat fact</span>
      <span class="hljs-keyword">const</span> catFact = <span class="hljs-keyword">await</span> CatFactService.getCatFact();

      <span class="hljs-keyword">const</span> response = {
        <span class="hljs-attr">status</span>: <span class="hljs-string">"success"</span>,
        <span class="hljs-attr">user</span>: user.toJSON(),
        <span class="hljs-attr">timestamp</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toISOString(), <span class="hljs-comment">// Dynamic timestamp</span>
        <span class="hljs-attr">fact</span>: catFact,
      };

      res.status(<span class="hljs-number">200</span>).json(response);
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error in getProfile:"</span>, error?.message);

      <span class="hljs-comment">// Even in case of error, return a valid response with fallback data</span>
      <span class="hljs-keyword">const</span> user = User.getCurrentUser();
      <span class="hljs-keyword">const</span> fallbackFact = CatFactService.getFallbackMessage();

      res.status(<span class="hljs-number">200</span>).json({
        <span class="hljs-attr">status</span>: <span class="hljs-string">"success"</span>,
        <span class="hljs-attr">user</span>: user.toJSON(),
        <span class="hljs-attr">timestamp</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toISOString(),
        <span class="hljs-attr">fact</span>: fallbackFact,
      });
    }
  }
}

<span class="hljs-built_in">module</span>.exports = ProfileController;
</code></pre>
<p><strong>Important Decision:</strong> I decided to <strong>always return a 200 status</strong> even if the cat fact API fails. Why? Because the core functionality (returning profile data) is working. The cat fact is a nice-to-have feature, not a critical one. This is called <strong>graceful degradation</strong>.</p>
<h3 id="heading-step-5-setting-up-routes"><strong>Step 5: Setting Up Routes</strong></h3>
<p>Simple and clean route definition:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> router = express.Router();
<span class="hljs-keyword">const</span> ProfileController = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../controllers/profileController"</span>);

<span class="hljs-comment">// GET /me - Get user profile with cat fact</span>
router.get(<span class="hljs-string">"/me"</span>, ProfileController.getProfile);

<span class="hljs-built_in">module</span>.exports = router;
</code></pre>
<h3 id="heading-step-6-configuration-management"><strong>Step 6: Configuration Management</strong></h3>
<p>I centralized all configuration in one file:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">PORT</span>: process.env.PORT || <span class="hljs-number">3000</span>,
  <span class="hljs-attr">CAT_FACT_API_URL</span>: <span class="hljs-string">"https://catfact.ninja/fact"</span>,
  <span class="hljs-attr">API_TIMEOUT</span>: <span class="hljs-number">5000</span>,
  <span class="hljs-attr">FALLBACK_MESSAGES</span>: [
    <span class="hljs-string">"Cats are amazing creatures!"</span>,
    <span class="hljs-string">"Did you know cats have been companions to humans for over 9,000 years?"</span>,
    <span class="hljs-string">"A group of cats is called a 'clowder' - isn't that purr-fect?"</span>,
    <span class="hljs-string">"Cats spend 70% of their lives sleeping - living the dream!"</span>,
    <span class="hljs-string">"Fun fact: Cats have a third eyelid called a nictitating membrane!"</span>,
  ],
};
</code></pre>
<p><strong>Why?</strong> This makes it easy to change configuration without touching the code. Want to change the timeout? Modify one number in one file. Want to add more fallback messages? Just add them to the array.</p>
<h3 id="heading-step-7-error-handling-middleware"><strong>Step 7: Error Handling Middleware</strong></h3>
<p>Proper error handling is what separates amateur code from production-ready code:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Global error handling middleware</span>
<span class="hljs-keyword">const</span> errorHandler = <span class="hljs-function">(<span class="hljs-params">err, req, res, next</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Global error handler:"</span>, err.stack);

  res.status(err.status || <span class="hljs-number">500</span>).json({
    <span class="hljs-attr">status</span>: <span class="hljs-string">"error"</span>,
    <span class="hljs-attr">message</span>: err.message || <span class="hljs-string">"Internal server error"</span>,
  });
};

<span class="hljs-comment">// 404 Not Found handler</span>
<span class="hljs-keyword">const</span> notFoundHandler = <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {
  res.status(<span class="hljs-number">404</span>).json({
    <span class="hljs-attr">status</span>: <span class="hljs-string">"error"</span>,
    <span class="hljs-attr">message</span>: <span class="hljs-string">"Route not found"</span>,
  });
};

<span class="hljs-built_in">module</span>.exports = {
  errorHandler,
  notFoundHandler,
};
</code></pre>
<h2 id="heading-testing-the-api"><strong>🧪 Testing the API</strong></h2>
<p>I tested the endpoint using curl:</p>
<pre><code class="lang-bash">curl http://localhost:3000/me
</code></pre>
<p><strong>Successful Response:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"status"</span>: <span class="hljs-string">"success"</span>,
  <span class="hljs-attr">"user"</span>: {
    <span class="hljs-attr">"email"</span>: <span class="hljs-string">"osuolaleabdullahi@gmail.com"</span>,
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Jelili Abdullahi A."</span>,
    <span class="hljs-attr">"stack"</span>: <span class="hljs-string">"Node.js/Express"</span>
  },
  <span class="hljs-attr">"timestamp"</span>: <span class="hljs-string">"2025-10-16T18:23:45.123Z"</span>,
  <span class="hljs-attr">"fact"</span>: <span class="hljs-string">"Cats can jump up to six times their length."</span>
}
</code></pre>
<p>I also tested edge cases:</p>
<ul>
<li><p>✅ What happens if the Cat Facts API is down? → Fallback message works</p>
</li>
<li><p>✅ What happens if the API takes too long? → Timeout kicks in after 5 seconds</p>
</li>
<li><p>✅ What if I hit a non-existent route? → Returns proper 404 error</p>
</li>
<li><p>✅ Does the timestamp update on each request? → Yes!</p>
</li>
<li><p>✅ Does each request get a different cat fact? → Yes!</p>
</li>
</ul>
<h2 id="heading-key-learnings"><strong>🎓 Key Learnings</strong></h2>
<p>This task taught me several valuable lessons:</p>
<h3 id="heading-1-mvc-architecture-is-about-separation-of-concerns"><strong>1. MVC Architecture is About Separation of Concerns</strong></h3>
<p>Each layer has a specific job:</p>
<ul>
<li><p><strong>Models</strong> handle data structure</p>
</li>
<li><p><strong>Controllers</strong> handle request/response logic</p>
</li>
<li><p><strong>Services</strong> handle business logic and external integrations</p>
</li>
<li><p><strong>Routes</strong> define API endpoints</p>
</li>
</ul>
<p>This separation makes code:</p>
<ul>
<li><p>Easier to test (you can test each layer independently)</p>
</li>
<li><p>Easier to maintain (bugs are easier to locate)</p>
</li>
<li><p>Easier to scale (you can add features without breaking existing code)</p>
</li>
</ul>
<h3 id="heading-2-error-handling-is-not-optional"><strong>2. Error Handling is Not Optional</strong></h3>
<p>Professional applications handle errors gracefully. Key strategies:</p>
<ul>
<li><p>Always use try-catch blocks for async operations</p>
</li>
<li><p>Set timeouts for external API calls</p>
</li>
<li><p>Provide fallback data when possible</p>
</li>
<li><p>Log errors for debugging but don't expose internal details to clients</p>
</li>
</ul>
<h3 id="heading-3-configuration-should-be-centralized"><strong>3. Configuration Should Be Centralized</strong></h3>
<p>Having all constants in one file (<code>constants.js</code>) makes the application much easier to configure and maintain.</p>
<h3 id="heading-4-design-for-failure"><strong>4. Design for Failure</strong></h3>
<p>External APIs will fail. Networks will be slow. Servers will crash. Design your application to handle these scenarios gracefully rather than failing completely.</p>
<h3 id="heading-5-code-organization-matters"><strong>5. Code Organization Matters</strong></h3>
<p>A well-organized codebase is easier to:</p>
<ul>
<li><p>Navigate</p>
</li>
<li><p>Understand</p>
</li>
<li><p>Debug</p>
</li>
<li><p>Extend</p>
</li>
<li><p>Work on as a team</p>
</li>
</ul>
<h2 id="heading-benefits-of-this-architecture"><strong>🚀 Benefits of This Architecture</strong></h2>
<h3 id="heading-maintainability"><strong>Maintainability</strong></h3>
<p>Each component is self-contained. Need to change how user data is retrieved? Modify the <code>User</code> model. Need to switch to a different cat facts API? Update the <code>CatFactService</code>.</p>
<h3 id="heading-scalability"><strong>Scalability</strong></h3>
<p>Want to add more endpoints? Create new controllers and routes. Need to add authentication? Add an auth middleware. The architecture supports growth.</p>
<h3 id="heading-testability"><strong>Testability</strong></h3>
<p>Each layer can be tested independently:</p>
<ul>
<li><p>Test the <code>User</code> model in isolation</p>
</li>
<li><p>Test the <code>CatFactService</code> with mocked HTTP calls</p>
</li>
<li><p>Test the controller with mocked services</p>
</li>
</ul>
<h3 id="heading-team-collaboration"><strong>Team Collaboration</strong></h3>
<p>Multiple developers can work on different parts simultaneously without conflicts:</p>
<ul>
<li><p>One person works on models</p>
</li>
<li><p>Another works on controllers</p>
</li>
<li><p>Another works on services</p>
</li>
</ul>
<h2 id="heading-what-i-would-do-differently"><strong>🔄 What I Would Do Differently</strong></h2>
<p>If I were to extend this project, I would:</p>
<ol>
<li><p><strong>Add a Database</strong>: Currently, user data is hardcoded. Adding MongoDB/PostgreSQL would make it dynamic.</p>
</li>
<li><p><strong>Add Validation</strong>: Use libraries like Joi or Express-validator to validate request data.</p>
</li>
<li><p><strong>Add Testing</strong>: Write unit tests with Jest and integration tests with Supertest.</p>
</li>
<li><p><strong>Add Logging</strong>: Replace <code>console.log</code> with a proper logging library like Winston or Pino.</p>
</li>
<li><p><strong>Add Environment Variables</strong>: Use dotenv to manage sensitive configuration.</p>
</li>
<li><p><strong>Add API Documentation</strong>: Use Swagger/OpenAPI to document the API.</p>
</li>
<li><p><strong>Add Rate Limiting</strong>: Prevent abuse by limiting the number of requests per IP.</p>
</li>
<li><p><strong>Add Caching</strong>: Cache cat facts to reduce external API calls.</p>
</li>
</ol>
<h2 id="heading-conclusion"><strong>🏆 Conclusion</strong></h2>
<p>This HNG13 task was more than just building a simple API—it was a lesson in professional software architecture. The MVC pattern might seem like overkill for a simple endpoint, but it demonstrates principles that scale to enterprise applications.</p>
<p><strong>Key Takeaways:</strong></p>
<ul>
<li><p>🏗️ Architecture matters—even for small projects</p>
</li>
<li><p>🛡️ Always lan for failure (timeouts, fallbacks, error handling)</p>
</li>
<li><p>📦 Separation of concerns makes code maintainable</p>
</li>
<li><p>🔧 Configuration should be centralized</p>
</li>
<li><p>✨ Clean code is easier to understand, test, and extend</p>
</li>
</ul>
<p>Building this API taught me that professional development isn't just about making things work—it's about making them work <strong>reliably</strong>, <strong>maintainably</strong>, and <strong>scalably</strong>.</p>
<p>If you're also participating in the HNG Internship or looking to hire backend developers, check out <a target="_blank" href="https://hng.tech/hire">HNG Tech</a> for talented developers like myself!</p>
<hr />
<h2 id="heading-connect-with-me"><strong>🤝 Connect With Me</strong></h2>
<ul>
<li><p><strong>Email</strong>: <a target="_blank" href="mailto:osuolaleabdullahi@gmail.com">osuolaleabdullahi@gmail.com</a></p>
</li>
<li><p><strong>Stack</strong>: Node.js/Express</p>
</li>
</ul>
<hr />
<p><em>What are your thoughts on MVC architecture? Have you used it in your projects? Share your experiences in the comments below!</em> 👇</p>
<p>#HNG13 #NodeJS #Express #MVC #BackendDevelopment #API #JavaScript #WebDevelopment #SoftwareArchitecture #Internship</p>
]]></content:encoded></item></channel></rss>