<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Syed Zubyl N | Software Developer - Backend</title>
    <subtitle>Syed Zubyl N — Software Developer focused on Java, Spring Boot, backend development, REST APIs, databases, Flutter and production-oriented applications.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://syedzubyl.space/tags/backend/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://syedzubyl.space"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-06-12T00:00:00+00:00</updated>
    <id>https://syedzubyl.space/tags/backend/atom.xml</id>
    <entry xml:lang="en">
        <title>Understanding Java Backend Development by Building Real Projects</title>
        <published>2026-06-12T00:00:00+00:00</published>
        <updated>2026-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Syed Zubyl N
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://syedzubyl.space/blog/understanding-java-backend-development/"/>
        <id>https://syedzubyl.space/blog/understanding-java-backend-development/</id>
        
        <content type="html" xml:base="https://syedzubyl.space/blog/understanding-java-backend-development/">&lt;h3 id=&quot;the-problem&quot;&gt;The Problem&lt;&#x2F;h3&gt;
&lt;p&gt;Learning Java syntax is easy. Understanding how to build a production-grade backend system is hard. Many tutorials stop at creating a simple &lt;code&gt;HelloWorldController&lt;&#x2F;code&gt;, leaving developers confused about how to structure a large application, manage dependencies, and handle complex business logic.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;context&quot;&gt;Context&lt;&#x2F;h3&gt;
&lt;p&gt;When I started diving deep into Java and Spring Boot, I wanted to move past theoretical examples and understand the actual mechanics of a production backend. How do services communicate? How do we handle transactions? Where does business logic actually live?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-i-tried&quot;&gt;What I Tried&lt;&#x2F;h3&gt;
&lt;p&gt;I initially tried to learn by reading textbooks on Design Patterns and Object-Oriented Programming (OOP) in isolation. I studied Singleton, Factory, and Strategy patterns.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-failed&quot;&gt;What Failed&lt;&#x2F;h3&gt;
&lt;p&gt;While I understood the patterns conceptually, I had no idea when or why to use them in a real web server. The abstractions felt unnecessary. Writing an interface for a simple database query seemed like over-engineering when I could just write the logic directly in the controller.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-worked-technical-explanation&quot;&gt;What Worked &amp;amp; Technical Explanation&lt;&#x2F;h3&gt;
&lt;p&gt;The “aha” moment came when I stopped reading isolated examples and built a real REST API managing complex data relationships.&lt;&#x2F;p&gt;
&lt;p&gt;Suddenly, the concepts clicked:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;1. Dependency Injection (DI)&lt;&#x2F;strong&gt;
I finally understood why Spring’s &lt;code&gt;@Autowired&lt;&#x2F;code&gt; (or constructor injection) is brilliant. Instead of a Service instantiating a specific Database class (tight coupling), the framework injects it. This meant I could swap my production database repository for a Mock repository during testing without changing a single line of business logic.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;2. Interfaces and Implementations&lt;&#x2F;strong&gt;
I used an interface &lt;code&gt;PaymentProcessor&lt;&#x2F;code&gt;. In development, I injected a &lt;code&gt;MockPaymentProcessor&lt;&#x2F;code&gt;. In production, I injected a &lt;code&gt;StripePaymentProcessor&lt;&#x2F;code&gt;. The controller didn’t care; it just called &lt;code&gt;paymentProcessor.charge()&lt;&#x2F;code&gt;. This is OOP in actual practice.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;3. Exception Handling&lt;&#x2F;strong&gt;
Instead of scattering &lt;code&gt;try-catch&lt;&#x2F;code&gt; blocks everywhere, I utilized Spring’s &lt;code&gt;@ControllerAdvice&lt;&#x2F;code&gt;. I threw custom exceptions (&lt;code&gt;UserNotFoundException&lt;&#x2F;code&gt;) deep in the service layer, and a global handler automatically translated them into formatted &lt;code&gt;404 Not Found&lt;&#x2F;code&gt; JSON responses.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h3&gt;
&lt;p&gt;You cannot learn enterprise architecture by writing isolated Java classes. You learn it by encountering the pain of tightly coupled code in a growing project, and then discovering how frameworks like Spring Boot use DI and interfaces to solve that exact pain.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-i-would-do-differently&quot;&gt;What I Would Do Differently&lt;&#x2F;h3&gt;
&lt;p&gt;I would have focused on Test-Driven Development (TDD) from day one. Writing unit tests forces you to use Dependency Injection and interfaces properly. If a class is hard to test, it’s usually because it’s poorly architected. Testing is the ultimate feedback loop for good Java design.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Designing a Production-Oriented Application from Mobile UI to Database</title>
        <published>2026-05-02T00:00:00+00:00</published>
        <updated>2026-05-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Syed Zubyl N
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://syedzubyl.space/blog/system-design-mobile-to-database/"/>
        <id>https://syedzubyl.space/blog/system-design-mobile-to-database/</id>
        
        <content type="html" xml:base="https://syedzubyl.space/blog/system-design-mobile-to-database/">&lt;h3 id=&quot;the-problem&quot;&gt;The Problem&lt;&#x2F;h3&gt;
&lt;p&gt;When transitioning from building simple prototype applications to production-oriented software, the architecture must change fundamentally. A prototype can connect a mobile UI directly to a database like Firebase, bypassing strict backend validation. A production application cannot. It requires clear separation of concerns, strict validation, and the ability to scale different components independently.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;context&quot;&gt;Context&lt;&#x2F;h3&gt;
&lt;p&gt;The goal is to design a system where a Flutter mobile client securely interacts with a Java Spring Boot backend, which in turn manages business logic and talks to a relational database (MySQL).&lt;&#x2F;p&gt;
&lt;p&gt;The flow looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Mobile Client &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ↓ (JSON over HTTPS)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;API Gateway &#x2F; Controller &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ↓ (DTOs)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Service Layer &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ↓ (Entities)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Repository Layer &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ↓ (SQL)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Database&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;what-i-tried-the-anti-pattern&quot;&gt;What I Tried (The Anti-Pattern)&lt;&#x2F;h3&gt;
&lt;p&gt;Early in my learning journey, I tried building “fat controllers.” The API controller would receive an HTTP request, open a database transaction, parse the JSON, write custom SQL queries, and return an HTTP response all in one massive function.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-failed&quot;&gt;What Failed&lt;&#x2F;h3&gt;
&lt;p&gt;This failed spectacularly as the application grew.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Testing:&lt;&#x2F;strong&gt; I couldn’t test the business logic without mocking the entire HTTP request&#x2F;response cycle.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Reusability:&lt;&#x2F;strong&gt; When a scheduled background job needed to update user records, I had to duplicate the code from the controller because the controller was tightly coupled to HTTP requests.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Security:&lt;&#x2F;strong&gt; Raw data structures were passed directly back to the client, exposing internal database IDs and password hashes.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;what-worked-technical-explanation&quot;&gt;What Worked &amp;amp; Technical Explanation&lt;&#x2F;h3&gt;
&lt;p&gt;I implemented a strict N-Tier Architecture, separating concerns at every layer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;1. The API Layer (Controllers)&lt;&#x2F;strong&gt;
Controllers only care about HTTP. They receive a request, validate the incoming JSON against a Data Transfer Object (DTO), and immediately pass the data to the Service Layer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;2. The Service Layer (Business Logic)&lt;&#x2F;strong&gt;
This is the brain of the application. It knows nothing about HTTP or SQL. It receives validated DTOs, applies business rules (e.g., “A user cannot register if they are under 18”), and coordinates with the Repository Layer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;3. The Repository Layer (Data Access)&lt;&#x2F;strong&gt;
This layer handles the actual database communication using an ORM like Hibernate or raw SQL queries. It returns Domain Entities.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;4. External Services&lt;&#x2F;strong&gt;
If the application needs to send an email or process a payment, the Service Layer calls an Interface (e.g., &lt;code&gt;EmailService&lt;&#x2F;code&gt;). The actual implementation (e.g., &lt;code&gt;SendGridEmailServiceImpl&lt;&#x2F;code&gt;) is injected.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h3&gt;
&lt;p&gt;Separation of concerns is not just theoretical computer science overhead. It is the only way to build software that can survive changing requirements. By decoupling the HTTP layer from the business logic, I can swap out the web framework. By decoupling the business logic from the database, I can swap out the ORM.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-i-would-do-differently&quot;&gt;What I Would Do Differently&lt;&#x2F;h3&gt;
&lt;p&gt;I would introduce an API Gateway pattern earlier if the system required microservices. However, for most of the production applications I build, a well-structured modular monolith using the exact architecture described above is significantly more efficient to deploy and maintain.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Debugging a 405 Method Not Allowed Error in a Mobile API</title>
        <published>2026-02-14T00:00:00+00:00</published>
        <updated>2026-02-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Syed Zubyl N
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://syedzubyl.space/blog/debugging-405-error/"/>
        <id>https://syedzubyl.space/blog/debugging-405-error/</id>
        
        <content type="html" xml:base="https://syedzubyl.space/blog/debugging-405-error/">&lt;h3 id=&quot;the-problem&quot;&gt;The Problem&lt;&#x2F;h3&gt;
&lt;p&gt;While developing a mobile application, a specific API endpoint for fetching user profile data suddenly started failing. The mobile client was receiving a &lt;code&gt;405 Method Not Allowed&lt;&#x2F;code&gt; HTTP status code, and the data refused to load.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;context&quot;&gt;Context&lt;&#x2F;h3&gt;
&lt;p&gt;The application relies on a Spring Boot backend exposing RESTful endpoints. The mobile client (built in Flutter) communicates with this API using the &lt;code&gt;http&lt;&#x2F;code&gt; package. The endpoint in question was &lt;code&gt;&#x2F;api&#x2F;v1&#x2F;users&#x2F;profile&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-i-tried&quot;&gt;What I Tried&lt;&#x2F;h3&gt;
&lt;p&gt;At first, I assumed the authentication token was invalid or the endpoint URL was misspelled.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;I checked the JWT token — it was valid.&lt;&#x2F;li&gt;
&lt;li&gt;I verified the URL string in the Dart code — it perfectly matched the backend controller.&lt;&#x2F;li&gt;
&lt;li&gt;I checked the server logs, expecting to see a &lt;code&gt;NullPointerException&lt;&#x2F;code&gt; or a &lt;code&gt;400 Bad Request&lt;&#x2F;code&gt;. Instead, Spring Security was just quietly rejecting the request at the filter level.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;what-failed&quot;&gt;What Failed&lt;&#x2F;h3&gt;
&lt;p&gt;I spent an hour looking at the backend logic, assuming the database query was failing or the routing was broken. None of this was the issue because the request wasn’t even reaching my controller method.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-worked-technical-explanation&quot;&gt;What Worked &amp;amp; Technical Explanation&lt;&#x2F;h3&gt;
&lt;p&gt;The breakthrough came when I bypassed the mobile app entirely and used Postman to test the endpoint.&lt;&#x2F;p&gt;
&lt;p&gt;When I sent a &lt;code&gt;GET&lt;&#x2F;code&gt; request in Postman: &lt;strong&gt;200 OK.&lt;&#x2F;strong&gt;
When I looked closely at my Flutter network layer:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;dart&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;&#x2F; The bug&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;final&lt;&#x2F;span&gt;&lt;span&gt; response &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;= await&lt;&#x2F;span&gt;&lt;span&gt; http.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;post&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;  Uri&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;parse&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;#39;https:&#x2F;&#x2F;api.example.com&#x2F;api&#x2F;v1&#x2F;users&#x2F;profile&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  headers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;#39;Authorization&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;#39;Bearer $&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The issue was glaringly simple: I was using &lt;code&gt;http.post&lt;&#x2F;code&gt; for an endpoint that the backend explicitly defined as a &lt;code&gt;@GetMapping&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;code&gt;405 Method Not Allowed&lt;&#x2F;code&gt; means exactly what it says: the server exists, the route exists, but the HTTP verb (GET, POST, PUT, DELETE) you used is not supported for that specific route. It is fundamentally different from a &lt;code&gt;404 Not Found&lt;&#x2F;code&gt; (route doesn’t exist) or a &lt;code&gt;400 Bad Request&lt;&#x2F;code&gt; (payload is wrong).&lt;&#x2F;p&gt;
&lt;p&gt;I corrected the mobile client to use &lt;code&gt;http.get&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;dart&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;&#x2F; The fix&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;final&lt;&#x2F;span&gt;&lt;span&gt; response &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;= await&lt;&#x2F;span&gt;&lt;span&gt; http.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;  Uri&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;parse&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;#39;https:&#x2F;&#x2F;api.example.com&#x2F;api&#x2F;v1&#x2F;users&#x2F;profile&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  headers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;#39;Authorization&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt; &amp;#39;Bearer $&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Read the HTTP Status Code literally.&lt;&#x2F;strong&gt; Don’t assume a 405 is a generic crash. It has a highly specific meaning defined by the HTTP protocol.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Isolate the client from the server.&lt;&#x2F;strong&gt; When an API fails in a mobile app, test the exact same request in &lt;code&gt;curl&lt;&#x2F;code&gt; or Postman immediately. This tells you instantly if the bug is in the client code (Flutter) or the server code (Spring Boot).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;what-i-would-do-differently&quot;&gt;What I Would Do Differently&lt;&#x2F;h3&gt;
&lt;p&gt;I will implement a centralized API client class in Flutter with strict typed methods (&lt;code&gt;fetchProfile()&lt;&#x2F;code&gt;, &lt;code&gt;updateProfile()&lt;&#x2F;code&gt;) rather than writing raw &lt;code&gt;http.get&lt;&#x2F;code&gt; or &lt;code&gt;http.post&lt;&#x2F;code&gt; calls scattered throughout the UI code. This reduces the surface area for simple typo bugs like using the wrong HTTP verb.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
