<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tentang Anak Tech Team</title>
    <description>The latest articles on DEV Community by Tentang Anak Tech Team (@tentanganak).</description>
    <link>https://dev.to/tentanganak</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%2Forganization%2Fprofile_image%2F7863%2F593bb6af-8e65-4a17-a19e-c85a7132a9bb.jpeg</url>
      <title>DEV Community: Tentang Anak Tech Team</title>
      <link>https://dev.to/tentanganak</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tentanganak"/>
    <language>en</language>
    <item>
      <title>Basic Concept &amp; Benefit of API Gateway</title>
      <dc:creator>Rizky Darmawan</dc:creator>
      <pubDate>Thu, 27 Mar 2025 04:52:06 +0000</pubDate>
      <link>https://dev.to/tentanganak/basic-concept-benefit-of-api-gateway-dmc</link>
      <guid>https://dev.to/tentanganak/basic-concept-benefit-of-api-gateway-dmc</guid>
      <description>&lt;h5&gt;
  
  
  Photo by &lt;a href="https://unsplash.com/@soymeraki?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Javier Allegue Barros&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/silhouette-of-road-signage-during-golden-hour-C7B-ExXpOIE?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;
&lt;/h5&gt;

&lt;p&gt;Api gateways are an important component in modern software architecture, especially in systems that implement microservices. Api Gateway acts as the main gateway to receive all incoming API requests. With this role, API Gateway simplifies API management and improves overall system performance and security.&lt;/p&gt;

&lt;p&gt;Using API Gateway helps build systems that are &lt;strong&gt;scalable&lt;/strong&gt; and &lt;strong&gt;easy to maintain&lt;/strong&gt;. As system complexity increases, API Gateway plays a critical role in managing effective integration and communication between various backend services and clients.&lt;/p&gt;

&lt;p&gt;In this article, we will learn &lt;strong&gt;basic concepts&lt;/strong&gt; and &lt;strong&gt;benefits&lt;/strong&gt; from using API Gateway. The hope is that this article can provide new understanding or strengthen the insights you already have.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is API Gateway ?
&lt;/h1&gt;

&lt;p&gt;An API Gateway is an API management tool that sits between a client and a collection of backend services. It acts as an intermediary, routing client requests to the appropriate backend service required to fulfill them and then returning the corresponding response Additionally, an API Gateway provides several important features such as &lt;strong&gt;load balancing, circuit breaking, logging, authentication, and caching&lt;/strong&gt;, making it a crucial component in modern API architecture.&lt;/p&gt;

&lt;p&gt;In today's fast-paced world of digital development, efficiency is everything, which is why API Gateways have become essential in modern software projects. Acting as a &lt;strong&gt;central point of control for API&lt;/strong&gt; across microservices architecture handling thousands of concurrent API calls efficiently.&lt;/p&gt;

&lt;h1&gt;
  
  
  How does API Gateway work ?
&lt;/h1&gt;

&lt;p&gt;Api Gateway work with receive request from internal and external, called "API Calls". API Gateway as software layer that manage traffic for routes them ti appropriate API and then delver the responses to the particular user or devic thath made the request.&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%2F7rliw8ixuw1ie048w7pc.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%2F7rliw8ixuw1ie048w7pc.png" alt="Image description" width="800" height="574"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This the explain API Gateway Workflow from image above:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A client (browser, mobile app, or another service) sends an API request.&lt;/li&gt;
&lt;li&gt;The API Gateway processes the request with routes the request to the correct backend service.&lt;/li&gt;
&lt;li&gt;The backend service processes the request and sends a response.&lt;/li&gt;
&lt;li&gt;The API Gateway modifies or enhances the response.&lt;/li&gt;
&lt;li&gt;Finally, the response is returned to the client.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Benefits of API Gateway
&lt;/h1&gt;

&lt;p&gt;Using an API Gateway can bring several benefits such as &lt;strong&gt;enhance performance&lt;/strong&gt;, &lt;strong&gt;improve security&lt;/strong&gt;, &lt;strong&gt;easier maintenance of multiple backend services&lt;/strong&gt;. Here are some key benefits of using an API Gateway:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Enhanced security
&lt;/h2&gt;

&lt;p&gt;An API Gateway enforce authentication and authorization policies, ensuring that only authorized users can access backend services. Additionally, it can help mitigate security threats through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rate limiting&lt;/strong&gt; to prevent API abuse and DDoS attacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IP whitelisting and blacklisting&lt;/strong&gt; to restrict access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TLS encryption&lt;/strong&gt; to secure communication between clients and services.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Better monitoring and visibility
&lt;/h2&gt;

&lt;p&gt;An API gateway can collect metrics and other data about the requests and responses, providing valuable insights into the performance and behavior of the system. This can help to identify and diagnose problems, and improve the overall reliability and resilience of the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Data Format Transformation
&lt;/h2&gt;

&lt;p&gt;An API Gateway can convert request and response or data data format (e.g., JSON to XML). Making it easier to manage data formats when needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. API Versioning and Backward Compatibility
&lt;/h2&gt;

&lt;p&gt;An API Gateway can manage multiple versions of an API, allowing developers to introduce new features or make changes without breaking existing clients. This enables a smoother transition for clients and reduces the risk of service disruptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Enhanced Error Handling
&lt;/h2&gt;

&lt;p&gt;An API Gateway can provide a consistent way to handle errors and generate error responses, improving the user experience and making it easier to diagnose and fix issues.&lt;/p&gt;

&lt;h1&gt;
  
  
  Drawbacks of Impelementation API Gateway
&lt;/h1&gt;

&lt;p&gt;In addition to having many benefits that we get when we implement API Gateway, on the other hand we also have disadvantages in using it, here are some points:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Single Point of Failure
&lt;/h2&gt;

&lt;p&gt;Since the API Gateway acts as a central access point for all API requests, it can become a single point of failure if not properly managed. If the gateway experiences downtime, it could disrupt the entire API ecosystem. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Additional Complexity
&lt;/h2&gt;

&lt;p&gt;Integrating an API Gateway introduces an additional layer of complexity to your architecture. It requires careful configuration, monitoring, and maintenance. If not managed efficiently, it can slow down development and increase operational overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Increased Latency
&lt;/h2&gt;

&lt;p&gt;An API Gateway processes incoming requests before forwarding them to the appropriate services, which can introduce latency. This delay may impact overall system performance, especially if multiple processing steps (such as authentication, logging, and rate limiting) are involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Cost
&lt;/h2&gt;

&lt;p&gt;Operating an API Gateway, particularly in high-traffic environments, can add significant costs to your infrastructure. Expenses may include hosting, licensing fees, or managed API Gateway services from cloud providers.&lt;/p&gt;

&lt;h1&gt;
  
  
  Simple Example of an API Gateway
&lt;/h1&gt;

&lt;p&gt;To implement an API Gateway, you can use a popular API Gateway such as &lt;strong&gt;Nginx&lt;/strong&gt;, &lt;strong&gt;Kong&lt;/strong&gt;, &lt;strong&gt;KrakenD&lt;/strong&gt;, and many more popular choices. However, our goal for the topic is to understand how API Gateway works. So, we can understand by simply building a simple API Gateway using golang. Let's begin.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For the complete code you can see following repository: &lt;a href="https://github.com/letenk/simply-api-gateway" rel="noopener noreferrer"&gt;Click me&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The structure Folder
&lt;/h2&gt;

&lt;p&gt;We can create a simply the API Gateway following the structure folder:&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="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;Makefile&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;api_gateway&lt;/span&gt;
&lt;span class="err"&gt;│  &lt;/span&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;
&lt;span class="err"&gt;│  &lt;/span&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;
&lt;span class="err"&gt;│  &lt;/span&gt; &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;service_cart&lt;/span&gt;
&lt;span class="err"&gt;│  &lt;/span&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;
&lt;span class="err"&gt;│  &lt;/span&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;
&lt;span class="err"&gt;│  &lt;/span&gt; &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="n"&gt;service_order&lt;/span&gt;
&lt;span class="err"&gt;│  &lt;/span&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;
&lt;span class="err"&gt;│  &lt;/span&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;
&lt;span class="err"&gt;│  &lt;/span&gt; &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;service_product&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;
    &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The rate limitter function code
&lt;/h2&gt;

&lt;p&gt;First, we can create a file with the name &lt;strong&gt;main.go&lt;/strong&gt; in the &lt;strong&gt;api_gateway&lt;/strong&gt; folder which contains:&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;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/gofiber/fiber/v2"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/gofiber/fiber/v2/middleware/limiter"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;rateLimiter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;fiber&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Handler&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;limiter&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="n"&gt;limiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Expiration&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;Second&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Max&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&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;The &lt;strong&gt;rateLimiter()&lt;/strong&gt; function is used to limit the number of requests per client. Where this rate limiter is useful for &lt;strong&gt;Preventing abuse &amp;amp; DDoS&lt;/strong&gt;, &lt;strong&gt;Controlling API traffic&lt;/strong&gt;, &lt;strong&gt;Protecting backend services from overload&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;With the configuration &lt;code&gt;Expiration: time.Second, Max: 5&lt;/code&gt;, each client can only make 5 requests per second. If this limit is reached, the client will receive error &lt;strong&gt;HTTP 429 Too Many Requests&lt;/strong&gt;. After 1 second, the limit will be reset and the client can send requests again.&lt;/p&gt;

&lt;h2&gt;
  
  
  The proxy function code
&lt;/h2&gt;

&lt;p&gt;Second, we also create a function with the name &lt;strong&gt;reverseProxy&lt;/strong&gt;:&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;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c"&gt;// ... other import libraries&lt;/span&gt;
        &lt;span class="s"&gt;"log"&lt;/span&gt;
        &lt;span class="s"&gt;"github.com/gofiber/fiber/v2/middleware/proxy"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// ... rate limitter function&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;reverseProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;fiber&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&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;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fiber&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ctx&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;url&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OriginalURL&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;proxy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Do&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&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;The &lt;strong&gt;proxy(target string)&lt;/strong&gt; function is used to forward requests (proxy requests) from clients to other backend servers specified in the target. This function returns a &lt;strong&gt;middleware handler (fiber.Handler)&lt;/strong&gt; that can be used on Fiber.&lt;/p&gt;

&lt;p&gt;We also see &lt;strong&gt;c.OriginalURL()&lt;/strong&gt; returns the path and query parameters of the original request sent by the client. For example, if the client accesses &lt;a href="http://localhost:3000/api/orders?id=10" rel="noopener noreferrer"&gt;http://localhost:3000/api/orders?id=10&lt;/a&gt;, then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;/api/orders?id=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And last we return &lt;strong&gt;proxy.Do(c, url)&lt;/strong&gt; is used to forward requests to the destination url. This url is a combination of target and c.OriginalURL(), so all incoming requests will be directed to another server with the same path. In this way, requests that enter the API Gateway will be automatically directed to the appropriate backend service without the client knowing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then main function code
&lt;/h2&gt;

&lt;p&gt;And latest file we create &lt;strong&gt;main&lt;/strong&gt; function, is a entrypoint of this application. In this case, it acts as an API Gateway. The code is 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="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c"&gt;// ... other import libraries&lt;/span&gt;
        &lt;span class="s"&gt;"github.com/gofiber/fiber/v2/middleware/logger"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fiber&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="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logger&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="c"&gt;// Implement rate limitter&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rateLimiter&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="c"&gt;// Implement proxy&lt;/span&gt;
    &lt;span class="c"&gt;// Redirect request to service product&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/product"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reverseProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:5001"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;// Redirect request to service order&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/order"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reverseProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:5002"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;// Redirect request to service cart&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/cart"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reverseProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:5003"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;":3000"&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Starting API Gateway in port %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&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;We can focus on the code part:&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="c"&gt;// Implement rate limitter&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rateLimiter&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code applies rate limiting to the entire application with Fiber's limiter middleware. This middleware is attached with &lt;strong&gt;app.Use(rateLimiter())&lt;/strong&gt;, which means it will apply to all routes. The function &lt;strong&gt;rateLimiter()&lt;/strong&gt; returns the rate limiter middleware we created earlier with &lt;strong&gt;limiter.New()&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And also for some of these code:&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="c"&gt;// Implement proxy&lt;/span&gt;
    &lt;span class="c"&gt;// Redirect request to service product&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/product"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reverseProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:5001"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;// Redirect request to service order&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/order"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reverseProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:5002"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;// Redirect request to service cart&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/cart"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reverseProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:5003"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code uses the &lt;strong&gt;reverseProxy&lt;/strong&gt; function we created earlier, which will forward the request to the appropriate service.&lt;/p&gt;

&lt;p&gt;As we know in the &lt;strong&gt;The structure Folder&lt;/strong&gt; section, we also have several service folders that will be directed according to incoming requests from clients.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For the complete code you can see following repository: &lt;a href="https://github.com/letenk/simply-api-gateway" rel="noopener noreferrer"&gt;Click me&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Let's run it
&lt;/h2&gt;

&lt;p&gt;To run it there are several ways, if Makefile is installed on your computer you only need to run the command below in the terminal on root folder project:&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="nb"&gt;make&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If not you can run it one by one by going into all folders and starting to run with the command:&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;cd&lt;/span&gt; &lt;span class="n"&gt;service_product&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;

&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;service_order&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;

&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;service_cart&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;

&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;api_gateway&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;If successful, you can see display like this:&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%2F1psq6jg2zj57oyj0w1jx.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%2F1psq6jg2zj57oyj0w1jx.png" alt="Image description" width="594" height="757"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the image above you can see several services running on their respective ports.&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;Service&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="n"&gt;Gateway&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="m"&gt;3000&lt;/span&gt;

&lt;span class="n"&gt;Service&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="m"&gt;5001&lt;/span&gt;

&lt;span class="n"&gt;Service&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="m"&gt;5002&lt;/span&gt;

&lt;span class="n"&gt;Service&lt;/span&gt; &lt;span class="n"&gt;cart&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="m"&gt;5003&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the advantage of using API Gateway, imagine you have more than 3 services and on the client we have several features that must be run simultaneously. Do we have to define the url with each specific port? of course it is very troublesome. And later one of the services must change its url address, of course it is even more troublesome to have to refactor here and there on the client side.&lt;/p&gt;

&lt;p&gt;But with API Gateway you only need to know the url on the API Gateway and define the appropriate url, let's try to access several services via the API Gateway url only. Run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl http://localhost:3000/product/1
curl http://localhost:3000/order
curl http://localhost:3000/cart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the result is you can access multiple services with just one URL.&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%2F8iidjtkylpt2i98zptoi.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%2F8iidjtkylpt2i98zptoi.png" alt="Image description" width="732" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And in the log you can see that the api gateway actually forwards the request to the service that corresponds to the address being called.&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%2Fkii6jugw66v2gow0mehi.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%2Fkii6jugw66v2gow0mehi.png" alt="Image description" width="614" height="112"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And I give a challenging task, try to make more requests than the maximum rate limiter that we have set in the &lt;strong&gt;rateLimiter&lt;/strong&gt; function until you get the error &lt;strong&gt;HTTP 429 Too Many Requests&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;API Gateway acts as the primary gateway to manage request traffic in a microservice system. With rate limiting, APIs are more secure from abuse such as DDoS. Reverse proxies allow requests to be directed to the appropriate backend service without changing the client side, increasing flexibility and ease of management. In addition, API Gateway also supports caching, logging, monitoring, and other security features such as authentication &amp;amp; authorization. With proper implementation, API Gateway can improve the security, performance, and scalability of the overall system.&lt;/p&gt;

&lt;p&gt;However, implementing API Gateway also has some drawbacks that we must be aware of such as a single point of failure, additional complexity, increased latency, and higher operational costs. Despite these drawbacks, a well-implemented API Gateway remains essential for scalable and secure microservice architectures.&lt;/p&gt;

&lt;p&gt;Hopefully this article can help to improve understanding or recall what is already known. If you have additions or corrections to the discussion above, let's discuss it in the comments column. Hopefully it helps 👋.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://konghq.com/blog/learning-center/what-is-an-api-gateway" rel="noopener noreferrer"&gt;What is an API Gateway?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.redhat.com/en/topics/api/what-does-an-api-gateway-do" rel="noopener noreferrer"&gt;What does an API gateway do?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.designgurus.io/course-play/grokking-system-design-fundamentals/doc/advantages-and-disadvantages-of-using-api-gateway" rel="noopener noreferrer"&gt;Advantages and disadvantages of using API gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@ftieben/deciphering-the-decision-should-you-use-an-api-gateway-or-not-6f371ad4ce00" rel="noopener noreferrer"&gt;Deciphering the Decision: Should You Use an API Gateway or Not?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>backend</category>
      <category>backendtips</category>
      <category>security</category>
    </item>
    <item>
      <title>Great Code Starts with Great Planning</title>
      <dc:creator>Irfan Adisukma</dc:creator>
      <pubDate>Mon, 24 Feb 2025 07:47:58 +0000</pubDate>
      <link>https://dev.to/tentanganak/great-code-starts-with-great-planning-2mlk</link>
      <guid>https://dev.to/tentanganak/great-code-starts-with-great-planning-2mlk</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%2Fwxs79on4ll0h7qz9u8tg.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%2Fwxs79on4ll0h7qz9u8tg.png" alt="Image description" width="607" height="189"&gt;&lt;/a&gt;&lt;br&gt;
Image Source: &lt;a href="https://www.growmy.tech/post/examples-of-finding-a-niche-in-software-development-industry" rel="noopener noreferrer"&gt;GrowMy.tech&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every developer dreams of writing clean, efficient, and impactful code. But what many overlook is the critical step that comes before the first line of code is even written: planning. Without a clear roadmap, projects can quickly spiral into chaos, leading to wasted time, frustration, and subpar results. Taking the time to carefully plan your approach not only sets a solid foundation but also makes the coding process smoother and more productive. In this article, we'll explore why planning is the cornerstone of successful development and how it can elevate your coding projects to new heights.&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%2Ftfcog7roixbb2ctp8ibf.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%2Ftfcog7roixbb2ctp8ibf.jpg" alt="Image description" width="600" height="600"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Journey of a Beginner Developer
&lt;/h2&gt;

&lt;p&gt;The internet is full of technical tutorials and advice on how to code effectively. But let’s take a step back and look at the bigger picture. No matter how many mistakes you make or how often things don’t go as planned, persistence is key. The journey of a developer comes with challenges, but it’s also incredibly rewarding. Stay committed, keep learning, and trust that your efforts will pay off over time. The code you write today has the potential to make a real impact.&lt;/p&gt;

&lt;p&gt;It’s normal to feel discouraged sometimes, even the most experienced ones, has faced similar struggles. If you're feeling stuck, remember that it's just part of the learning process. Even I come across difficult topics that feel overwhelming at times, but with consistent effort, improvement always follows. Keep going, you’re making progress every day.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Beginner Stage
&lt;/h2&gt;

&lt;p&gt;As a beginner, it often feels like you're on an emotional rollercoaster. Some days, you’re unstoppable, completely focused on coding, excited about your progress, and confident that you’ve found your passion. On other days, the challenges feel too difficult. &lt;br&gt;
A tricky concept or a bug that’s hard to fix might make you question your path, thinking, “Is this really what I want to do for the rest of my life?” It’s frustrating, and it’s easy to feel like the struggle is holding you back.&lt;/p&gt;
&lt;h3&gt;
  
  
  Navigating the Highs and Lows
&lt;/h3&gt;

&lt;p&gt;This stage is tough, but it’s also crucial. It’s a phase where you’ll inevitably make mistakes and lots of them. There are many reasons for this. Perhaps you’re rushing to land your first job in tech, or maybe you’ve taken on low budget projects just to make ends meet. These pressures can lead to poor decisions, overly optimistic timelines, and code that isn’t as clean or efficient as you’d like. But here’s the truth, this is normal. Every seasoned developer you admire has been through this phase. It’s a rite of passage that helps you grow. You may feel like you’re just stumbling along, but every misstep teaches you something valuable. If you keep pushing forward, you’ll find your rhythm and reach the next level of your journey.&lt;/p&gt;

&lt;p&gt;I can confidently tell you this, it’s all worth it. The struggles, the late nights, and even the failed projects they all contribute to your development as a programmer. So, keep coding. Keep learning. The only way to improve is to persevere.&lt;/p&gt;
&lt;h3&gt;
  
  
  Finding Strength in the Beginner Stage
&lt;/h3&gt;

&lt;p&gt;While this stage might feel overwhelming, it’s also one of the most transformative phases of your journey. It’s here that you develop qualities that will serve you for the rest of your career. Among the most important are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Willpower: The determination to keep going, even when the odds feel stacked against you.&lt;/li&gt;
&lt;li&gt;Curiosity: An insatiable hunger to learn more and explore uncharted territories in programming.&lt;/li&gt;
&lt;li&gt;Ambition: The drive to push past your limits and achieve your goals.&lt;/li&gt;
&lt;li&gt;Resilience: The courage to embrace failures and use them as stepping stones toward success.
Humility: The willingness to accept feedback, no matter how critical, and use it to improve.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These traits are your superpowers during this stage. Use them to fuel your growth. Let your ambition and curiosity guide you to new knowledge. Push yourself to take on challenges that seem just beyond your reach. And when you stumble, remember that mistakes are simply opportunities to learn.&lt;/p&gt;

&lt;p&gt;At this stage, it’s also important to focus on the bigger picture. Yes, you and I have goals whether that’s building better apps, landing a dream job, or contributing to impactful projects. But our purpose as developers goes beyond personal achievements. With every line of code, we have the opportunity to add value to the world. By solving problems, simplifying processes, and sharing our knowledge, we can create meaningful change.&lt;/p&gt;
&lt;h3&gt;
  
  
  Plan First, Code Later
&lt;/h3&gt;

&lt;p&gt;A great real world example of the "Plan First, Code Later" approach is how Instagram was initially developed.&lt;/p&gt;

&lt;p&gt;In 2010, Instagram (then called "Burbn") was just an idea in the minds of its founders, Kevin Systrom and Mike Krieger. Instead of jumping straight into coding, they followed a structured planning approach before writing a single line of code.&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%2F5iv87w8x8k5qky8fed6b.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%2F5iv87w8x8k5qky8fed6b.jpg" alt="Image description" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Case Study: Instagram's Early Development
&lt;/h4&gt;

&lt;p&gt;Background&lt;br&gt;
In 2010, Instagram (then called "Burbn") was just an idea in the minds of its founders, Kevin Systrom and Mike Krieger. Instead of jumping straight into coding, they followed a structured planning approach before writing a single line of code.&lt;/p&gt;

&lt;p&gt;Step 1: Analyzing Product Requirements&lt;br&gt;
Initially, Burbn was a location based check-in app with a photo sharing feature. After conducting market research and analyzing user feedback, the team realized that users were mainly interested in the photo-sharing feature rather than the check-ins.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lesson: Instead of coding an unnecessary check-in system, they refined their product requirements and pivoted towards a dedicated photo sharing app.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Step 2: System Architecture &amp;amp; Scalability Planning&lt;br&gt;
Before coding, the team planned how the backend should handle millions of photos and user interactions. They chose AWS for hosting and used Django as their backend framework for rapid development while ensuring scalability.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lesson: Without proper planning, they could have picked a technology stack that wouldn't scale effectively.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Step 3: UX/UI Planning Before Development&lt;br&gt;
They designed a simple and intuitive user interface before writing any code. They focused on a minimalist approach, reducing clutter and unnecessary features, leading to an easy to use app.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lesson: By planning the UI/UX beforehand, they avoided the need for major redesigns after coding.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Outcome&lt;/strong&gt;&lt;br&gt;
Because of their careful planning and iterative approach, Instagram launched with a lightweight, focused, and scalable system. Within two months, it gained 1 million users, proving the power of planning before coding.&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%2Fgdbcfam59frvbszvjojh.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%2Fgdbcfam59frvbszvjojh.png" alt="Image description" width="566" height="560"&gt;&lt;/a&gt;&lt;br&gt;
Source: &lt;a href="https://strategizeyourcareer.com/p/ask-first-code-later" rel="noopener noreferrer"&gt;strategizeyourcareer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In programming, clarity in requirements, design, and implementation plays a crucial role in minimizing the number of fixes or bugs. Let's break this down:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Clarify Early → Fewer Fixes Later&lt;br&gt;
When requirements are well defined, developers know exactly what to build. This prevents misunderstandings and unnecessary revisions.&lt;br&gt;
A clear design ensures that architectural decisions are sound from the start, reducing structural issues later.&lt;br&gt;
Writing clean and well documented code makes debugging and future maintenance easier, reducing the chances of introducing new bugs when fixing existing ones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lack of Clarity → More Fixes Needed&lt;br&gt;
If requirements are vague, developers might make incorrect assumptions, leading to features that don’t match expectations.&lt;br&gt;
A poorly designed system can cause scalability and maintainability problems, requiring constant refactoring.&lt;br&gt;
Ambiguous or unstructured code can lead to hard to find bugs, increasing debugging time and causing more regressions. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As a beginner, you’ve likely experienced the highs and lows of learning to code. The excitement of progress mixed with the frustration of setbacks is part of the process. But here’s something that can make this stage more manageable: developing a strong foundation in planning before you dive into coding.&lt;/p&gt;

&lt;p&gt;Let's take an example of "Plan First, Code Later" in a real coding scenario using Flutter&lt;/p&gt;
&lt;h4&gt;
  
  
  Before Planning (Jumping Straight into Code)
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class UserListScreen extends StatefulWidget {
  @override
  _UserListScreenState createState() =&amp;gt; _UserListScreenState();
}

class _UserListScreenState extends State&amp;lt;UserListScreen&amp;gt; {
  List&amp;lt;dynamic&amp;gt; users = [];

  @override
  void initState() {
    super.initState();
    fetchUsers();
  }

  Future&amp;lt;void&amp;gt; fetchUsers() async {
    final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
    if (response.statusCode == 200) {
      setState(() {
        users = json.decode(response.body);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Users')),
      body: users.isEmpty
          ? Center(child: CircularProgressIndicator())
          : ListView.builder(
              itemCount: users.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(users[index]['name']),
                  subtitle: Text(users[index]['email']),
                );
              },
            ),
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Problems with This Approach&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Mixes UI and Business Logic: The fetchUsers() function is inside the UI, making it hard to test and maintain.&lt;/li&gt;
&lt;li&gt;Tight Coupling: If the API changes, we must modify the UI code as well.&lt;/li&gt;
&lt;li&gt;No Error Handling: What if the API fails? There’s no proper error message.&lt;/li&gt;
&lt;li&gt;Not Scalable: If we add caching or other data sources (like a database), we will need major rewrites.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  After Planning (More Effective &amp;amp; Maintainable Code)
&lt;/h4&gt;

&lt;p&gt;Step 1: Define a Model (User.dart)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User {
  final int id;
  final String name;
  final String email;

  User({required this.id, required this.name, required this.email});

  factory User.fromJson(Map&amp;lt;String, dynamic&amp;gt; json) {
    return User(
      id: json['id'],
      name: json['name'],
      email: json['email'],
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Separate Data Layer (UserService.dart)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'dart:convert';
import 'package:http/http.dart' as http;
import 'user.dart';

class UserService {
  Future&amp;lt;List&amp;lt;User&amp;gt;&amp;gt; fetchUsers() async {
    final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));

    if (response.statusCode == 200) {
      List&amp;lt;dynamic&amp;gt; data = json.decode(response.body);
      return data.map((json) =&amp;gt; User.fromJson(json)).toList();
    } else {
      throw Exception('Failed to load users');
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 3: Use State Management (UserProvider.dart)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:flutter/material.dart';
import 'user_service.dart';
import 'user.dart';

class UserProvider extends ChangeNotifier {
  final UserService _userService = UserService();
  List&amp;lt;User&amp;gt; _users = [];
  bool _isLoading = true;
  String? _error;

  List&amp;lt;User&amp;gt; get users =&amp;gt; _users;
  bool get isLoading =&amp;gt; _isLoading;
  String? get error =&amp;gt; _error;

  UserProvider() {
    fetchUsers();
  }

  Future&amp;lt;void&amp;gt; fetchUsers() async {
    try {
      _isLoading = true;
      notifyListeners();

      _users = await _userService.fetchUsers();
      _error = null;
    } catch (e) {
      _error = e.toString();
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 4: UI with Separation of Concerns (UserListScreen.dart)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'user_provider.dart';

class UserListScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Users')),
      body: Consumer&amp;lt;UserProvider&amp;gt;(
        builder: (context, userProvider, child) {
          if (userProvider.isLoading) {
            return Center(child: CircularProgressIndicator());
          }

          if (userProvider.error != null) {
            return Center(child: Text('Error: ${userProvider.error}'));
          }

          return ListView.builder(
            itemCount: userProvider.users.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(userProvider.users[index].name),
                subtitle: Text(userProvider.users[index].email),
              );
            },
          );
        },
      ),
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 5: Setup in main.dart
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'user_provider.dart';
import 'user_list_screen.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) =&amp;gt; UserProvider()),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: UserListScreen(),
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Benefits of This Planned Approach&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Separation of Concerns – Business logic, API calls, and UI are separate.&lt;/li&gt;
&lt;li&gt;Scalability – Easy to add caching, local storage, or database.&lt;/li&gt;
&lt;li&gt;Better Error Handling – Provides clear error messages.&lt;/li&gt;
&lt;li&gt;Easier Testing – Can unit test the UserService without involving UI.&lt;/li&gt;
&lt;li&gt;Less Boilerplate in UI – The UI is now focused only on presentation.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;When starting a new project or feature, it’s tempting to jump straight into coding because it feels productive. However, skipping the planning phase often leads to inefficiencies, unnecessary mistakes, and wasted effort. Taking the time to plan ensures a smoother development process and helps create cleaner, more maintainable code.&lt;/p&gt;

&lt;p&gt;Planning doesn’t always mean lengthy documentation. For small tasks, it might be as simple as confirming requirements: “You want the button text changed to blue, right?” For larger projects, it involves defining specifications, gathering feedback, and securing approval. Without this step, you risk solving the wrong problem or overlooking key considerations.&lt;/p&gt;

&lt;p&gt;Writing code too soon can also make it harder to communicate ideas, especially with non technical colleagues. Conversations, diagrams, and brainstorming sessions are often faster ways to clarify concepts than jumping into code. While coding can sometimes help explore a problem, any early code should be treated as a rough draft rather than a final solution.&lt;/p&gt;

&lt;p&gt;Even informal planning breaking down a task into steps or considering potential challenges can help avoid issues later. By thinking ahead, you can refine your approach before writing code, ultimately saving time and reducing frustration.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Good planning doesn’t slow you down; it helps you move faster by preventing costly mistakes and ensuring you build the right solution from the start.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thank you for reading this article! I hope it helps you understand the importance of planning before coding and how it can lead to better, more efficient development. Happy coding! 🚀&lt;/p&gt;




&lt;p&gt;References:&lt;br&gt;
&lt;a href="https://letterstoanewdeveloper.com/2020/10/19/plan-first-then-code/" rel="noopener noreferrer"&gt;letterstoanewdeveloper&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/pulse/design-first-code-later-michael-rothrock/" rel="noopener noreferrer"&gt;Michael Rothrock&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.theatlantic.com/technology/archive/2014/07/instagram-used-to-be-called-brbn/373815/" rel="noopener noreferrer"&gt;Instagram Was First Called 'Burbn'&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
    </item>
    <item>
      <title>Connection Pool in Backend Development: Basic Concept, Benefits, and Implementation</title>
      <dc:creator>Rizky Darmawan</dc:creator>
      <pubDate>Thu, 06 Feb 2025 02:43:38 +0000</pubDate>
      <link>https://dev.to/tentanganak/connection-pool-in-backend-development-basic-concept-benefits-and-implementation-4bh0</link>
      <guid>https://dev.to/tentanganak/connection-pool-in-backend-development-basic-concept-benefits-and-implementation-4bh0</guid>
      <description>&lt;h5&gt;
  
  
  Photo by &lt;a href="https://unsplash.com/@buying_thyme?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Christine Tutunjian&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/assorted-color-balloons-7oLuQ0ZEQ9A?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;
&lt;/h5&gt;

&lt;p&gt;Connection Pooling is a mechanism that creates and manages a pool of database connections that can be used by applications. This concept is important in managing connections to the database with the aim of optimizing resource use and improving the performance of applications that frequently interact with the database.&lt;/p&gt;

&lt;p&gt;Instead of creating a new connection every time it is needed (which is expensive in terms of time and resources), connection pools allow applications to borrow/use existing connections and return them to the pool when they are finished using them. That's why it's called &lt;strong&gt;connection pool&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why connection pool is important ?
&lt;/h2&gt;

&lt;p&gt;The important question is why is connection polling important? why not just make 1 connection to be used alternately. Let's discuss 1 by 1 why connection pooling is important.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better performance
&lt;/h3&gt;

&lt;p&gt;Opening a new connection to the database can take time because it goes through several processes such as authentication, network settings and so on. With a connection pool, applications can avoid this process because connections are already available if needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resource savings
&lt;/h3&gt;

&lt;p&gt;Without a pool, if the application gets 100 requests, the application will create 100 new connections. This can burden the database server which is always busy carrying out the initialization process. The connection pool can limit the number of connections used simultaneously, this keeps the database server load stable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;p&gt;Connection pooling helps applications manage load well when the application scales up. With good connection pooling settings, we can handle a large number of requests coming at the same time and ensure the application remains responsive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Load configuration
&lt;/h3&gt;

&lt;p&gt;The connection pool can be configured with a maximum number of connections according to needs. So it can prevent applications from flooding connections to the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Works ?
&lt;/h2&gt;

&lt;p&gt;Now that we understand why connection pooling is important to use, we will now discuss how connection polling works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pool Initialization
&lt;/h3&gt;

&lt;p&gt;The first time an application is run, it makes a certain number of connections to the database (for example, 10 connections). This number is called &lt;strong&gt;Pool size&lt;/strong&gt;. This connection will be idling waiting to be used.&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%2F7u7gb5oktn39jso9udvo.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%2F7u7gb5oktn39jso9udvo.png" alt="Image description" width="800" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Connection usage
&lt;/h3&gt;

&lt;p&gt;When the application needs a connection to the database it no longer creates a new connection, instead it requests a connection from the pool. If a connection is available in the pool, it will be assigned to the application. If no connections are available, the application may have to wait until a connection is released and returns to the pool after being used by another process.&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%2F2x21w8mjh95ab3s9pq4k.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%2F2x21w8mjh95ab3s9pq4k.png" alt="Image description" width="800" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Restore connection
&lt;/h3&gt;

&lt;p&gt;Once an application has finished using a connection, it will not close the connection. Instead, the connection is returned to the pool to be used again by the next request.&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%2F6u4x5nhh1zypyds0hmjt.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%2F6u4x5nhh1zypyds0hmjt.png" alt="Image description" width="800" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The common main parameter in connection pool
&lt;/h2&gt;

&lt;p&gt;The following are some of the main parameters that are commonly used when creating a connection pool. I will try to explain in detail followed by analogies that can help us understand each context better.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pool Size
&lt;/h3&gt;

&lt;p&gt;We can determine the number of connections provided in &lt;strong&gt;Pool Size&lt;/strong&gt;. If all connections are used then when there is a request to use the connection it will queue up waiting for an available connection or it will fail if the queue is full.&lt;/p&gt;

&lt;p&gt;For example, if we set the max pool size to 10, only 10 active connections can be used by the application. If an 11th request comes, this request will wait for a connection from the pool that is already in use. The analogy is like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Imagine there is a &lt;strong&gt;parking lot,&lt;/strong&gt; if all the slots are full, a new car that wants to enter &lt;strong&gt;(connection request)&lt;/strong&gt; has to wait until another car comes out &lt;strong&gt;(idle connection).&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;If we want to accommodate more cars, we have to build more parking slots (increase &lt;strong&gt;MaxPoolSize)&lt;/strong&gt; so that we can accommodate more cars. But there are increased maintenance costs (&lt;strong&gt;server resources).&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Minimum Connections
&lt;/h3&gt;

&lt;p&gt;Minimum connection is the minimum number of connections that will be created the first time the application is run. This is a connection that will always be on standby waiting to be used, even when there are no requests. For example, if we set &lt;strong&gt;minimum pool size 5,&lt;/strong&gt; the pool will ensure there are always 5 idle connections. Even if there are no active requests, the pool will still make sure these 5 connections are open to reduce the connection opening time when a request comes in.&lt;/p&gt;

&lt;p&gt;This is useful for anticipating erratic loads, for example suddenly our application gets a lot of requests and connections are available ready to use without having to open a new connection. The analogy is like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Imagine that a restaurant has 10 chairs that are deliberately not arranged in the dining room, but are stored in the warehouse. But when there are a lot of visitors, we need extra chairs, we don't need long to buy them at the shop. But just need to go to the warehouse and pick up the 10 chairs needed for use.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Idle Connection
&lt;/h3&gt;

&lt;p&gt;Idle connections are the number of connections that are not being used but remain open in the pool, which can also be called "idle connections". This parameter is usually set by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Maximum Idle Time&lt;/strong&gt;: How long an idle connection is maintained before being closed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maximum Idle Connections&lt;/strong&gt;: The number of idle connections allowed to remain in the pool.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, if we set &lt;strong&gt;MaxIdleConnections = 5,&lt;/strong&gt; the pool will maintain a maximum of 5 idle connections. If there are more idle connections it will be closed. If there are no new requests within a certain time (for example, 10 minutes), these idle connections may be removed to save resources. The analogy is like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the supermarket there are 5 cashiers, 3 cashiers are serving buyers (active connection) and 2 cashiers are on standby in their positions without a queue of buyers (idle connection) and are ready whenever a buyer comes.&lt;/li&gt;
&lt;li&gt;Supermarkets have a rule, "If the cashier is on standby for 30 minutes without a customer, then they can go home." These 30 minutes are idle time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Timeout
&lt;/h3&gt;

&lt;p&gt;We can set the maximum time the application waits for a connection from the pool before it fails (error). This is done to prevent applications from waiting too long for available connections from the pool, if the pool is busy or full. This is useful to prevent the application from waiting too long for a connection which will cause the application to "freeze" where it is better to give an error to the user, so that it can provide information to the user to try again rather than resulting in a freeze request.&lt;/p&gt;

&lt;p&gt;For example, if we set a timeout of 5 seconds, if a request does not get a connection, after waiting for 5 seconds it will receive an error. The point to remember is that a timeout that is too short can cause the request to fail too quickly and a timeout that is too long means the request will hang for too long. The analogy is like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We are queuing to buy at a restaurant (request), but we can't wait for the queue (timeout limit). And we decided to leave the restaurant (return error).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Max lifetime
&lt;/h3&gt;

&lt;p&gt;Lifetime determines &lt;strong&gt;how long a connection can live before being reset or closed&lt;/strong&gt; by the pool, even if the connection is active. Usually used to avoid old connection problems or update configurations to ensure connections remain fresh and reliable.&lt;/p&gt;

&lt;p&gt;For example, if we set &lt;strong&gt;max lifetime&lt;/strong&gt; 20 minutes, any connection that has been used for 20 minutes will be &lt;strong&gt;closed and removed from the pool&lt;/strong&gt; and will be replaced by a new connection that will be created.&lt;/p&gt;

&lt;p&gt;This is important because sometimes some database servers have a time limit for old connections which can prevent stale connections** problems. The analogy is like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An office has 3 security officers per shift. Each officer works a maximum of 8 hours (Max Lifetime)&lt;/li&gt;
&lt;li&gt;After 8 hours, the officers must be replaced with new officers, even though the previous 5 officers are still in good condition, there are no problems and work is running smoothly. But it prevents officers from getting tired and losing concentration when checking incoming visitors (requests).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;Now we will try to implement a connection pool using Golang. Note the following code:&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="kr"&gt;package&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;database/sql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fmt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;log&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

    &lt;span class="nx"&gt;_&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;github.com/go-sql-driver/mysql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;dsn&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;username:password@tcp(127.0.0.1:3306)/dbname?parseTime=true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mysql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dsn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to open connection to database: %v&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;defer&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SetMaxOpenConns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SetMaxIdleConns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SetConnMaxLifetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Minute&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SetConnMaxIdleTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Minute&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Ping&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to ping database: %v&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Successfully connected to database!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT id, name FROM users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to run query: %v&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;defer&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to read query results: %v&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ID: %d, Name: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error after iteration: %v&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&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;We can focus on the following code snippet:&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="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SetMaxOpenConns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SetMaxIdleConns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SetConnMaxLifetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Minute&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SetConnMaxIdleTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Minute&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SetMaxOpenConns(10)&lt;/strong&gt;: Determines the maximum number of connections that can be open simultaneously.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SetMaxIdleConns(5)&lt;/strong&gt;: Determines the maximum number of idle connections maintained in the pool.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SetConnMaxLifetime(time.Minute * 10)&lt;/strong&gt;: Determines how long a connection can live before being reset or closed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SetConnMaxIdleTime(time.Minute * 5)&lt;/strong&gt;: Determines how long an idle connection can be maintained before being closed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The use of connection pooling is very important, as this can anticipate the application running smoothly when handling an erratic load of incoming requests. But the right settings must also be implemented, so that the use of connection pooling can be more optimal.&lt;/p&gt;

&lt;p&gt;If you have additions or corrections to the discussion above, let's discuss it in the comments column. Hope it helps 👋.&lt;/p&gt;

</description>
      <category>mysql</category>
      <category>backend</category>
      <category>backenddevelopment</category>
      <category>database</category>
    </item>
    <item>
      <title>Mastering ENUMs in Go</title>
      <dc:creator>Rizky Darmawan</dc:creator>
      <pubDate>Tue, 24 Dec 2024 02:41:21 +0000</pubDate>
      <link>https://dev.to/tentanganak/mastering-enums-in-go-31j2</link>
      <guid>https://dev.to/tentanganak/mastering-enums-in-go-31j2</guid>
      <description>&lt;h5&gt;
  
  
  &lt;em&gt;Image by &lt;a href="https://unsplash.com/@sloppyperfectionist" rel="noopener noreferrer"&gt;Hans-Peter Gauster&lt;/a&gt; from &lt;a href="https://unsplash.com/photos/stack-of-jigsaw-puzzle-pieces-3y1zF4hIPCg" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;
&lt;/h5&gt;

&lt;p&gt;Let's say we are building an E-commerce API that will receive several orders, each order process has several statuses such as &lt;em&gt;Pending, Processed, Shipped, Delivered, Cancelled&lt;/em&gt;. And our application receives input strings which will be stored in the database, for example the status is Processed, received Process, Processing or something else that causes data inconsistencies. Here Enum has an important role.&lt;/p&gt;

&lt;p&gt;In Golang enums unlike other languages ​​such as Java or C# which offer built-in support for enums, Go takes a different approach. In Go, enums are not a native language feature, but developers have several techniques that can be used to achieve similar functionality.&lt;/p&gt;

&lt;h1&gt;
  
  
  Understanding Enum
&lt;/h1&gt;

&lt;p&gt;In Golang, enums (short for enumerations) provide a way to represent a set of named constants. Although Go does not have built-in enum types like some other languages, developers can emulate enum-like behavior using constants or custom types. Let's discuss the purpose and syntax of enums in Go:&lt;/p&gt;

&lt;h2&gt;
  
  
  Objective
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Readability and Maintainability&lt;/strong&gt;: Enums make code more readable and easy to understand by giving meaningful names to specific values. This increases the maintainability of the code because the purpose of each constant becomes easier to understand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Type Safety&lt;/strong&gt;: Enums help enforce type safety by restricting variables to a predefined set of values. This reduces the possibility of runtime errors caused by using incorrect values.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Create Enums
&lt;/h1&gt;

&lt;p&gt;Here we will discuss step by step how to create an enum in Golang, so that it is easy to understand at each stage we will explain the meaning of the code we write.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a New Type
&lt;/h2&gt;

&lt;p&gt;The first thing we will do is create a new type for the enum we need. The method is quite easy, we only need to use the keyword &lt;em&gt;type&lt;/em&gt; and followed by the name of the type here with the name &lt;strong&gt;StatusOrder&lt;/strong&gt; and the type here we define the type &lt;strong&gt;unsigned integer&lt;/strong&gt; like this:&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="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;StatusOrder&lt;/span&gt; &lt;span class="nx"&gt;uint&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, just make it easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define constant ENUM
&lt;/h2&gt;

&lt;p&gt;With the new type that we have created, now is the time for us to define some of the order statuses that we have with constants. Where we define the type &lt;strong&gt;StatusOrder&lt;/strong&gt; which we create as the type, like this:&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="nf"&gt;const &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;Pending&lt;/span&gt; &lt;span class="nx"&gt;StatusOrder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;iota&lt;/span&gt;
    &lt;span class="nx"&gt;Processed&lt;/span&gt;
    &lt;span class="nx"&gt;Shipped&lt;/span&gt;
    &lt;span class="nx"&gt;Delivered&lt;/span&gt;
    &lt;span class="nx"&gt;Cancelled&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maybe you ask, what is the keyword &lt;code&gt;iota&lt;/code&gt;? This keyword makes GO assign a value of 0 to the first constant and then increase the value by 1 sequentially for each subsequent constant. This makes it easier for us rather than defining the values ​​manually 1 by 1. About &lt;code&gt;iota&lt;/code&gt; you can read &lt;a href="https://go.dev/wiki/Iota" rel="noopener noreferrer"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Function Strings
&lt;/h2&gt;

&lt;p&gt;The next step we will take is to create a String function that is used to represent each string value from the &lt;code&gt;StatusOrder&lt;/code&gt; enum.&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="nf"&gt;func &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="nx"&gt;StatusOrder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;Pending&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pending&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;Processed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Processed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;Shipped&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Shipped&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;Delivered&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Delivered&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;Cancelled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cancelled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unknown&lt;/span&gt;&lt;span class="dl"&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;Does the function name have to be &lt;code&gt;String&lt;/code&gt;? We'll discuss it at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Now we will carry out testing, the last code we will write is, function &lt;strong&gt;main&lt;/strong&gt; and in it we print the results using the help of the &lt;code&gt;fmt&lt;/code&gt; package. yes.&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="nx"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nl"&gt;processed&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Processed&lt;/span&gt;
    &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Order Status: %s (%d)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;processed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;processed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;pending&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Pending&lt;/span&gt;
    &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Order Status: %s (%d)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pending&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pending&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;Now the complete code can be seen &lt;a href="https://github.com/letenk/golang-enum" rel="noopener noreferrer"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, we carry out the last step and we will see the results like this:&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%2F2hufqo3gl51ngx1a7d2n.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%2F2hufqo3gl51ngx1a7d2n.png" alt="Image description" width="225" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Fmt Stringer
&lt;/h2&gt;

&lt;p&gt;The question may arise, &lt;code&gt;why is the String function also called when we call the enum constant?&lt;/code&gt;. The answer is because we use the &lt;code&gt;fmt&lt;/code&gt; package. The fmt package explicitly uses the &lt;strong&gt;fmt.Stringer&lt;/strong&gt; interface to process types that implement the String() method. So, if you don't use fmt, the String() method will not be called automatically. To explain more, you can explore in more detail &lt;a href="https://pkg.go.dev/fmt#Stringer" rel="noopener noreferrer"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Although Golang does not offer native enum types, the techniques we learn here are often used in building applications with Golang. And for the type itself, we can freely use other types, not just integer. By utilizing this technique, readability, ease of maintenance and security can be significantly improved.&lt;/p&gt;

&lt;p&gt;Maybe there are some points explained above that you feel are lacking, we can discuss them in the comments column below. Hope it helps 👋.&lt;/p&gt;

&lt;h1&gt;
  
  
  Reading References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/fmt#Stringer" rel="noopener noreferrer"&gt;fmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.dev/wiki/Iota" rel="noopener noreferrer"&gt;Go Wiki: Iota&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reliasoftware.com/blog/golang-enum" rel="noopener noreferrer"&gt;Enums in Golang: Techniques, Best Practices, &amp;amp; Use Cases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://itnext.io/mastering-enums-in-go-04bd85ffcf33" rel="noopener noreferrer"&gt;Mastering ENUMs in Go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>backend</category>
      <category>backendtips</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Avoid Boilerplate with Code Generator in Flutter</title>
      <dc:creator>Firman Maulana</dc:creator>
      <pubDate>Thu, 19 Dec 2024 03:08:49 +0000</pubDate>
      <link>https://dev.to/tentanganak/avoid-boilerplate-with-code-generator-in-flutter-nb8</link>
      <guid>https://dev.to/tentanganak/avoid-boilerplate-with-code-generator-in-flutter-nb8</guid>
      <description>&lt;p&gt;As a software developer, you may encounter situations like writing code repeatedly for standard tasks. Imagine creating an application that needs integration with various APIs, managing JSON data, or performing tests. These tasks usually involve writing a lot of boilerplate code, which is time-consuming and increases the chance of mistakes.&lt;/p&gt;

&lt;p&gt;This can be very frustrating, especially when deadlines are approaching or when you are working on a complex project with many dependencies. Instead of focusing on innovation and solving more creative problems, you get stuck in a seemingly endless routine of writing code. This wastes valuable time and reduces your enthusiasm as a developer.&lt;/p&gt;

&lt;p&gt;This is where the importance of using code generators comes in. By utilizing code generation, you can reduce your workload in application development. You can automate repetitive processes, allowing you to focus on more strategic aspects and solve project-related problems. How can you use this in Flutter projects? Let's find out!&lt;/p&gt;

&lt;p&gt;The Dart ecosystem provides developers with a variety of powerful tools, one of which is code generation techniques. Yes, that's right! As the name suggests, this tool helps programmers generate code so that we don't need to write the whole code, but only the parts we need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Generation with build_runner
&lt;/h2&gt;

&lt;p&gt;Creating applications with Flutter often involves many common tasks, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deserializing JSON&lt;/li&gt;
&lt;li&gt;Using backend APIs&lt;/li&gt;
&lt;li&gt;Managing navigation&lt;/li&gt;
&lt;li&gt;Writing tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Typically, completing these tasks involves writing repetitive code, which can be time-consuming and error-prone. However, we can reduce the amount of code we need to write manually by using build_runner to generate the required code.&lt;/p&gt;

&lt;p&gt;In simple terms, &lt;strong&gt;build_runner&lt;/strong&gt; is a tool for generating output files from input files. We can create a code generator that works with this mechanism, which allows us to read input files, usually written in Dart code, and generate the corresponding output files.&lt;/p&gt;

&lt;p&gt;Using this generator, we only need to provide a minimal configuration for the desired code. After the build process is complete, we will receive a valid Dart code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here are the steps to use build_runner:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add it as a development dependency in the &lt;strong&gt;pubspec.yaml&lt;/strong&gt; file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   dev_dependencies:
     build_runner: x.y.z
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Run the code generation command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   flutter pub run build_runner build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, build_runner will execute all the code generators added as dependencies and generate output based on the input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watch Mode and Handling Existing Files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;build_runner also has a watch mode that monitors the file system and automatically updates the output files when the input files change. If files are considered existing and not generated by build_runner, a reminder will appear to delete those files.&lt;/p&gt;

&lt;p&gt;The -d option (short for --delete-conflicting-outputs) allows build_runner to delete conflicting files before starting code generation, making the process easier.&lt;/p&gt;

&lt;p&gt;For a more detailed explanation, you can check here: build_runner &lt;a href="https://pub.dev/packages/build_runner" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;There are many packages we can use, but this time we will look at some of the most popular ones. Some of these packages work with the build_runner tool. They make app development easier, so developers can focus more on what they want to create instead of how to create it. Here are some commonly used packages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;json_serializable&lt;/strong&gt;&lt;br&gt;
This package makes it easy to turn JSON data into Dart objects and vice versa.&lt;br&gt;
By using these packages together, we can work faster and more efficiently when building Flutter apps.&lt;/p&gt;

&lt;p&gt;For example, we can create an app that shows data from a JSON file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; "id": 1,
     "user": {
       "name": "Asep Saepul",
       "avatar": "https://images.pexels.com/photos/27659838/pexels-photo-27659838/free-photo-of-portrait-of-a-man-on-a-white-background.jpeg?auto=compress&amp;amp;cs=tinysrgb&amp;amp;w=800",
       "place": "Bandung, Indonesia"
     },
     "content": {
       "isLike": false,
       "image": "https://images.pexels.com/photos/3386600/pexels-photo-3386600.jpeg?auto=compress&amp;amp;cs=tinysrgb&amp;amp;w=600",
       "likes": "1.000 likes",
       "description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor."
     }
   },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To be used further in the application and take advantage of the typed nature of Dart, this data must be transformed into an instance of a Dart class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Feed {
 final int id;
 final User user;
 Content content;


 Feed({
   required this.id,
   required this.user,
   required this.content,
 });
}


class Content {
 final String image;
 late final String likes;
 final String description;
 bool isLike;
  Content({
   required this.image,
   required this.likes,
   required this.description,
   required this.isLike,
 });
}


class User {
 final String name;
 final String avatar;
 final String place;


 User({
   required this.name,
   required this.avatar,
   required this.place,
 });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To implement JSON deserialization in the &lt;code&gt;fromJson()&lt;/code&gt; and &lt;code&gt;toJson()&lt;/code&gt; methods within a class to allow the following usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Feed {
  final int id;
  final User user;
  Content content;

  Feed({
    required this.id,
    required this.user,
    required this.content,
  });

  // Method to convert Feed object to JSON
  Map&amp;lt;String, dynamic&amp;gt; toJson() {
    return {
      'id': id,
      'user': user.toJson(),
      'content': content.toJson(),
    };
  }

  // Method to create Feed object from JSON
  factory Feed.fromJson(Map&amp;lt;String, dynamic&amp;gt; json) {
    return Feed(
      id: json['id'],
      user: User.fromJson(json['user']),
      content: Content.fromJson(json['content']),
    );
  }
}

class Content {
  final String image;
  late final String likes;
  final String description;
  bool isLike;

  Content({
    required this.image,
    required this.likes,
    required this.description,
    required this.isLike,
  });

  // Method to convert Content object to JSON
  Map&amp;lt;String, dynamic&amp;gt; toJson() {
    return {
      'image': image,
      'likes': likes,
      'description': description,
      'isLike': isLike,
    };
  }

  // Method to create Content object from JSON
  factory Content.fromJson(Map&amp;lt;String, dynamic&amp;gt; json) {
    return Content(
      image: json['image'],
      likes: json['likes'],
      description: json['description'],
      isLike: json['isLike'],
    );
  }
}

class User {
  final String name;
  final String avatar;
  final String place;

  User({
    required this.name,
    required this.avatar,
    required this.place,
  });

  // Method to convert User object to JSON
  Map&amp;lt;String, dynamic&amp;gt; toJson() {
    return {
      'name': name,
      'avatar': avatar,
      'place': place,
    };
  }

  // Method to create User object from JSON
  factory User.fromJson(Map&amp;lt;String, dynamic&amp;gt; json) {
    return User(
      name: json['name'],
      avatar: json['avatar'],
      place: json['place'],
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the static method &lt;code&gt;Feed.fromJson()&lt;/code&gt; handles the parsing logic for the various field types in Feed, such as int and the custom classes User and Content, which also have &lt;code&gt;User.fromJson()&lt;/code&gt; and &lt;code&gt;Content.fromJson()&lt;/code&gt; factories. Additionally, the example above also includes the Feed.toJson() method that performs the inverse transformation.&lt;/p&gt;

&lt;p&gt;The json_serializable package allows for the same result with much less code. It can generate methods like &lt;code&gt;Feed.fromJson()&lt;/code&gt; and &lt;code&gt;Feed.toJson()&lt;/code&gt; and provides a mechanism to perform all the formatting adjustments as in the manual implementation above.&lt;/p&gt;

&lt;p&gt;To take advantage of code generation for JSON deserialization, add the following dependency in your &lt;strong&gt;pubspec.yaml&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies:
  json_annotation: x.y.z

dev_dependencies:
  build_runner: x.y.z
  json_serializable: x.y.z
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then an example of implementation by creating a Feed class as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;part feed.g.dart';

@JsonSerializable(explicitToJson: true, includeIfNull: false)
class Feed with _$Feed {
  const factory Feed({
    required int id,
    required User user,
    required Content content,
  }) = _Feed;

  factory Feed.fromJson(Map&amp;lt;String, dynamic&amp;gt; json) =&amp;gt; _$FeedFromJson(json);

Map&amp;lt;String, dynamic&amp;gt; toJson() =&amp;gt; _$FeedToJson(this);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;@JsonSerializable()&lt;/code&gt; annotation above the Feed class indicates that this class is subject to code generation, and the declaration of the &lt;strong&gt;feed.g.dart&lt;/strong&gt; section file ensures that the generated code is in the same &lt;strong&gt;feed.dart&lt;/strong&gt;. Once the code is generated, a new feed.g.dart file is added with the private methods &lt;code&gt;_$FeedFromJson()&lt;/code&gt; and &lt;code&gt;_$FeedToJson()&lt;/code&gt;, allowing the same results as the previous manual implementation.&lt;/p&gt;

&lt;p&gt;Using code generation significantly reduces the amount of code that needs to be written compared to a manual JSON deserialization implementation. Additionally, every time the JSON format or Dart class structure is updated, a manual implementation requires changes in several places, which are easy to miss until a serialization exception is raised at runtime. With code generation, we can ensure that all necessary changes are applied automatically.&lt;/p&gt;

&lt;p&gt;This guide only shows the basic usage of the json_serializable package. Check the official documentation for more information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enhance Classes with Freezed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are several operations that developers perform on Dart class instances explicitly or implicitly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;value-based comparisons&lt;/li&gt;
&lt;li&gt;hash code calculations&lt;/li&gt;
&lt;li&gt;using string representations&lt;/li&gt;
&lt;li&gt;making copies with modifications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The implementations of some of these operations, such as the ==() operator, hashCode, and toString(), are already built into the language but do not provide the best development experience and therefore require improvement, such as the &lt;code&gt;copyWith()&lt;/code&gt; method, must be written from scratch.&lt;/p&gt;

&lt;p&gt;Let’s consider the Feed class from the example above as an example. Two instances with the same field value are not equal, and their hash values ​​are also different:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final feed1 = Feed(
        id: 1,
        user: User(
          name: 'John Dhoe',
          avatar:
              'https://images.png’,
          place: 'Bandung, Indonesia',
        ),
        content: Content(
          isLike: false,
          image:
                 'https://images.png’,
          likes: '1.000 likes',
          description:
              'Lorem ipsum dolor sit amet',
        ),
      ),
final feed2 = Feed(
        id: 1,
        user: User(
          name: 'John Dhoe',
          avatar:
              'https://images.png’,
          place: 'Bandung, Indonesia',
        ),
        content: Content(
          isLike: false,
          image:
                 'https://images.png’,
          likes: '1.000 likes',
          description:
              'Lorem ipsum dolor sit amet',
        ),
      ),
assert(feed1 == feed2);                    // false
assert(feed1.hashCode == feed2.hashCode);  // false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can cause problems when Feed instances are added to a Set, used as Map keys, or verified in tests.&lt;/p&gt;

&lt;p&gt;At the same time, the string representations of two instances with different field values ​​are the same and return an Instance of Feed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assert(feed1.toString() == feed2.toString());  // true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To enhance the Feed class, we need to provide implementations of the following methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   // Override == operator
  @override
  bool operator ==(Object other) =&amp;gt;
      identical(this, other) ||
      other is Feed &amp;amp;&amp;amp;
          runtimeType == other.runtimeType &amp;amp;&amp;amp;
          id == other.id &amp;amp;&amp;amp;
          user == other.user &amp;amp;&amp;amp;
          content == other.content;

  // Override hashCode
  @override
  int get hashCode =&amp;gt;
      id.hashCode ^ user.hashCode ^ content.hashCode;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the problem doesn't stop there, because the &lt;code&gt;user == other.user&lt;/code&gt; check will likely fail most of the time even if both collections are empty or contain the same objects. To compare collections based on their contents, it should be replaced with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const DeepCollectionEquality().equals(user, other.user)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;Freezed&lt;/strong&gt; package allows us to not worry about this situation. To take advantage of Freezed in code generation to enhance Dart classes, add this dependency in the pubspec.yaml file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies:
  freezed_annotation: x.y.z

dev_dependencies:
  build_runner: x.y.z
  freezed: x.y.z
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is an example of its implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@freezed
class Feed with _$Feed {
 const factory Feed({
   required int id,
   required User user,
   required Content content,
 }) = _Feed;


 factory Feed.fromJson(Map&amp;lt;String, dynamic&amp;gt; json) =&amp;gt; _$FeedFromJson(json);
}


@freezed
class Content with _$Content {
 const factory Content({
   required String image,
   required String likes,
   required String description,
   required bool isLike,
 }) = _Content;


 factory Content.fromJson(Map&amp;lt;String, dynamic&amp;gt; json) =&amp;gt; _$ContentFromJson(json);
}


@freezed
class User with _$User {
 const factory User({
   required String name,
   required String avatar,
   required String place,
 }) = _User;


 factory User.fromJson(Map&amp;lt;String, dynamic&amp;gt; json) =&amp;gt; _$UserFromJson(json);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;@freezed&lt;/code&gt; annotation above the Feed class indicates that it is subject to code generation, and the declaration of the '&lt;strong&gt;feed.freezed.dart&lt;/strong&gt;' file section ensures that the generated code is part of the same as &lt;strong&gt;feed.dart&lt;/strong&gt;.&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%2Fz4kdegsa1bfdmv0i1agn.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%2Fz4kdegsa1bfdmv0i1agn.png" alt="Feed Directory" width="380" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check out the Feed, Content, and User classes. You can check from the examples repository for the complete implementations. Once the code is generated, a new file &lt;strong&gt;feed.freezed.dart&lt;/strong&gt; is added with implementations of &lt;code&gt;the ==()&lt;/code&gt;, &lt;code&gt;hashCode&lt;/code&gt;, &lt;code&gt;toString()&lt;/code&gt;, and &lt;code&gt;copyWith()&lt;/code&gt; operator methods, allowing for the same results as the manual implementation above.&lt;/p&gt;

&lt;p&gt;As with JSON deserialization, using code generation to enhance Dart classes reduces the effort of creating and maintaining them, ensuring that any necessary changes are automatically applied when the class structure changes.&lt;/p&gt;

&lt;p&gt;This guide only shows the basic usage of the freezed package. It has many useful features and can also be easily combined with &lt;strong&gt;json_serializable&lt;/strong&gt;. Check the official &lt;a href="https://pub.dev/packages/freezed" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;There are still many packages that you can use for code generation, such as for RESTful API Consumption needs you can use &lt;strong&gt;Retrofit&lt;/strong&gt;, Flutter Dependency Injection with &lt;strong&gt;Injectable&lt;/strong&gt;, Documentation and Tests with &lt;strong&gt;mockito&lt;/strong&gt;, and many more. Hopefully, in the next article, we can try to learn each of these packages to compare and learn how to implement them in our projects.&lt;/p&gt;

&lt;p&gt;But for now, I think it's enough to know examples of using &lt;strong&gt;json_serializable&lt;/strong&gt; and &lt;strong&gt;freezed&lt;/strong&gt; as a first step to finding out the benefits of codegen and how we use it in a flutter project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Drawback
&lt;/h2&gt;

&lt;p&gt;Okay, we already know how many benefits we can get from code generators. But keep in mind, we often have to look at things from both sides. Yes, codegen also has disadvantages that we need to consider before using it. In my Flutter project, I found some things when using codegen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time-consuming&lt;/strong&gt;: Basic code generation can be time-consuming for complex data structures or requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Initial setup&lt;/strong&gt;: Code generation requires some initial setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slows down the build process&lt;/strong&gt;: The generated code can slow the build process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clutters the project&lt;/strong&gt;: The generated code can clutter your project with extra files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Requires team members to run the codegen step&lt;/strong&gt;: If you don't commit the generated files to git, every team member must remember to run the codegen step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Requires a custom CI build step&lt;/strong&gt;: If you don't commit the generated files to git, a custom CI build step is required to build the app.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;p&gt;A simple Flutter demo project using &lt;strong&gt;Freezed&lt;/strong&gt; package is available on &lt;a href="https://github.com/firman-ta/flutter-simplecodegen" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.🚀&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%2Fir4iim5nd6btf080g3bf.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%2Fir4iim5nd6btf080g3bf.png" alt="App Screenshots" width="800" height="782"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Code generation is a powerful tool that can make us more productive by facilitating many repetitive or typical tasks in Flutter application development.&lt;/p&gt;

&lt;p&gt;In addition, those packages not only speed up the development process but also maintain the consistency and accuracy of the generated code. By utilizing these tools, developers can streamline their workflows, improve project maintenance, and ensure that structural changes in the code are automatically updated, which is an important step in maintaining the quality and sustainability of the application in the future.&lt;/p&gt;

&lt;p&gt;However, besides the many benefits of using code generation, there are also things to consider. For example, parts of the code that have changed and impacted other parts must be re-generated, which may take more time than changing it manually. So, it is adjusted again to the needs of the project you are working on. If you have tried it, don't hesitate to share your experience in the comments; hopefully, it's useful!&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.flutter.dev/" rel="noopener noreferrer"&gt;https://docs.flutter.dev/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://pub.dev/packages/build_runner" rel="noopener noreferrer"&gt;https://pub.dev/packages/build_runner&lt;/a&gt;&lt;br&gt;
&lt;a href="https://pub.dev/packages/freezed" rel="noopener noreferrer"&gt;https://pub.dev/packages/freezed&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>softwaredevelopment</category>
      <category>mobile</category>
      <category>programming</category>
    </item>
    <item>
      <title>Profiling Memory In Go</title>
      <dc:creator>dikac</dc:creator>
      <pubDate>Tue, 17 Dec 2024 02:00:47 +0000</pubDate>
      <link>https://dev.to/tentanganak/profiling-memory-in-go-2a2</link>
      <guid>https://dev.to/tentanganak/profiling-memory-in-go-2a2</guid>
      <description>&lt;p&gt;Efficient memory management is critical in Golang applications, particularly in high-concurrency environments, long-running services, or data-intensive tasks. Profiling memory usage helps diagnose issues, optimize performance, and prevent out-of-memory (OOM) errors. This guide provides a comprehensive approach to profiling memory usage from a Go endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Memory Profiling Matters
&lt;/h2&gt;

&lt;p&gt;Memory profiling identifies inefficient memory usage, memory leaks, and excessive allocations in your application. Without proper profiling, memory issues can lead to performance degradation, higher costs, and service downtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Causes of High Memory Usage
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Memory leaks&lt;/strong&gt;: Unintended memory retention due to data structures not being cleared up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Excessive allocations&lt;/strong&gt;: Large slices, maps, or other data structures consuming significant memory.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Setting Up Memory Profiling in Go
&lt;/h2&gt;

&lt;p&gt;To profile memory usage in a Go application, you can use tools like &lt;code&gt;pprof&lt;/code&gt; for runtime profiling and &lt;code&gt;parca&lt;/code&gt; for continuous profiling. Here’s how to set up and use these tools effectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Profiling Tools
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;pprof&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
A built-in Go tool that provides profiling for memory, CPU, goroutines, and more.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/net/http/pprof" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Parca&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
A continuous profiling tool that provides real-time insights by collecting data from &lt;code&gt;pprof&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/parca-dev/parca" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stress Testing&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Generate load to simulate real-world usage and observe memory behavior under stress. For our case we use &lt;a href="https://www.soapui.org/" rel="noopener noreferrer"&gt;SoapUI&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Using &lt;code&gt;pprof&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Since &lt;code&gt;pprof&lt;/code&gt; is built-in tool, installation is not required, include the following snippet to enable &lt;code&gt;pprof&lt;/code&gt; in your application:&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;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"net/http/pprof"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&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;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":1234"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&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;This exposes &lt;code&gt;pprof&lt;/code&gt; on port &lt;code&gt;1234&lt;/code&gt;. Access profiling data by visiting &lt;code&gt;http://localhost:1234/debug/pprof/&lt;/code&gt; or using tools like &lt;code&gt;go tool pprof&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using &lt;code&gt;parca&lt;/code&gt; for Continuous Profiling
&lt;/h3&gt;

&lt;p&gt;To install &lt;code&gt;parca&lt;/code&gt; see &lt;a href="https://github.com/parca-dev/parca" rel="noopener noreferrer"&gt;https://github.com/parca-dev/parca&lt;/a&gt;, after successfully installing &lt;code&gt;parca&lt;/code&gt;, configure &lt;code&gt;parca.yaml&lt;/code&gt; &lt;code&gt;job_name.static_configs.targets&lt;/code&gt; set the same port number as &lt;code&gt;pprof&lt;/code&gt; (in this example &lt;code&gt;1234&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;then you can run command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;parca &lt;span class="nt"&gt;--config-path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"parca.yaml"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if successful you will see message similar to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;level=info name=parca ts=2024-10-30T06:19:44.5149184Z caller=factory.go:53 msg="loading bucket configuration"
level=info name=parca ts=2024-10-30T06:19:44.5159183Z caller=badger.go:54 msg="Set nextTxnTs to 0"
level=info name=parca ts=2024-10-30T06:19:44.517917Z caller=server.go:90 msg="starting server" addr=:7070
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;addr=:7070&lt;/code&gt; is where you can access &lt;code&gt;parca&lt;/code&gt; web interface, port number might be different depend on configuration&lt;/p&gt;

&lt;p&gt;if all setup successful, you can access &lt;code&gt;parca&lt;/code&gt; on web browser&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%2Fixnatctqisv5vrekkv1v.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%2Fixnatctqisv5vrekkv1v.png" alt="Image description" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a multiple &lt;code&gt;profiling type&lt;/code&gt;, for Memory usage you can use&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%2F843qfkxx0xd83ivhm0sa.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%2F843qfkxx0xd83ivhm0sa.png" alt="Image description" width="220" height="79"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;if you encounter any issue, you should consult documentation since different environment might require different solution&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pprof &lt;a href="https://pkg.go.dev/net/http/pprof" rel="noopener noreferrer"&gt;https://pkg.go.dev/net/http/pprof&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;parca &lt;a href="https://github.com/parca-dev/parca" rel="noopener noreferrer"&gt;https://github.com/parca-dev/parca&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Identifying Memory Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stress Testing
&lt;/h3&gt;

&lt;p&gt;Before profiling, simulate high traffic using stress-testing tools in our case we use &lt;a href="https://www.soapui.org/" rel="noopener noreferrer"&gt;SoapUI&lt;/a&gt;. Stress tests help replicate conditions leading to memory issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  Analyzing Memory Usage
&lt;/h3&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%2F57rlv7bou3ejbrq53l3k.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%2F57rlv7bou3ejbrq53l3k.png" alt="Image description" width="800" height="276"&gt;&lt;/a&gt;&lt;br&gt;
After completing a stress test, monitor memory usage over time using the &lt;code&gt;parca&lt;/code&gt; dashboard.&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%2F57rlv7bou3ejbrq53l3k.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%2F57rlv7bou3ejbrq53l3k.png" alt="Image description" width="800" height="276"&gt;&lt;/a&gt;&lt;br&gt;
Click on the graphs to access detailed profiles.&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%2F2l2db0qsj2f0imjdu6xj.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%2F2l2db0qsj2f0imjdu6xj.png" alt="Image description" width="800" height="405"&gt;&lt;/a&gt;&lt;br&gt;
Using the icicle graph, examine the stack and corresponding memory usage. Wider lines indicate higher &lt;strong&gt;memory&lt;/strong&gt; consumption. This visualization helps pinpoint processes consuming significant memory.&lt;/p&gt;

&lt;p&gt;In our application, a process with substantial memory usage was identified:&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%2Fcjxzp9h88c6v3qw9yqie.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%2Fcjxzp9h88c6v3qw9yqie.png" alt="Image description" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Memory Optimization
&lt;/h3&gt;

&lt;p&gt;Memory optimization is a complex topic that varies depending on the application and its environment. Here are some practical techniques:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Selective Data Loading:&lt;/strong&gt; Load only the necessary data to significantly reduce memory allocation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoiding Pointers&lt;/strong&gt;: Use value types instead of pointers to minimize heap allocations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Predefining Data Lengths&lt;/strong&gt;: Specify lengths for known-size data structures to improve memory efficiency.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Upon further investigation, we discovered that the data retrieved from the cache was excessively large. We needed to validate whether such a large dataset was truly necessary for our logic flow.&lt;/p&gt;

&lt;p&gt;In our case, it turned out that this large dataset was not required. Therefore, we optimized the process by &lt;strong&gt;selectively removing unnecessary data&lt;/strong&gt;. After re-running the tests, memory usage was reduced by approximately 50%.&lt;/p&gt;

&lt;p&gt;Previous Implementation&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%2F57rlv7bou3ejbrq53l3k.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%2F57rlv7bou3ejbrq53l3k.png" alt="Image description" width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After selectively removing unneeded data&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%2Fv8ggik8e3va6s86cce6z.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%2Fv8ggik8e3va6s86cce6z.png" alt="Image description" width="800" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With help of this method we can easily narrow down and correct memory usage, in our case &lt;strong&gt;Selective Data Loading&lt;/strong&gt; is the correct method for reducing memory usage.&lt;/p&gt;




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

&lt;p&gt;Memory profiling is a critical practice for maintaining the performance and stability of Go applications. By leveraging tools like &lt;code&gt;pprof&lt;/code&gt; and &lt;code&gt;parca&lt;/code&gt;, you can identify memory issues, optimize resource usage, and ensure your application performs reliably under various loads. Regular profiling and proactive optimization help address memory-related challenges effectively.&lt;/p&gt;

</description>
      <category>go</category>
    </item>
    <item>
      <title>Modularization in Flutter App</title>
      <dc:creator>Edo Lubis</dc:creator>
      <pubDate>Mon, 16 Dec 2024 09:07:57 +0000</pubDate>
      <link>https://dev.to/tentanganak/modularization-in-flutter-app-bb6</link>
      <guid>https://dev.to/tentanganak/modularization-in-flutter-app-bb6</guid>
      <description>&lt;p&gt;As the complexity of a project increases, so does the amount of code we write. Therefore, maintaining code quality, scalability, and readability becomes even more important. One approach often used by engineers to address these challenges is modularization. &lt;/p&gt;

&lt;p&gt;What is modularization? Simply put, modularization is the process of breaking down a problem into smaller, more specific tasks or components, so that each part has a clear and focused purpose.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7v0kvubl6qwjs2y7d93i.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%2F7v0kvubl6qwjs2y7d93i.png" alt="Modularization example" width="800" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However keep in mind, modularization doesn’t necessarily reduce the complexity of your project. The overall complexity may remain the same, but modularization makes it easier to manage and maintain.&lt;/p&gt;

&lt;p&gt;We can separate modules based on features, by layers (such as UI, model, etc.), or a combination of both, depending on our needs and preferences.&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%2Fqlanja5tr2p9s5h1y6t9.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%2Fqlanja5tr2p9s5h1y6t9.png" alt="Module based on" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When modularizing, it's important to remember that good modularization is characterized by high cohesion, low coupling and bounded context. &lt;/p&gt;

&lt;p&gt;High cohesion means that each module has a specific function and focuses on a single purpose. For example, a module responsible for user authentication should only handle tasks like verifying user credentials or managing login sessions. It should not include unrelated functions, such as processing payments or managing user preferences.&lt;/p&gt;

&lt;p&gt;Low coupling means that modules do not rely excessively on other modules, so changes in one module do not have a significant impact on other modules. For example, the user authentication module should be designed in such a way that it operates independently of other modules.&lt;/p&gt;

&lt;p&gt;Bounded context means that each module should operate within its own domain, with its own set of rules and responsibilities. It ensures that the boundaries of a module are clearly defined, preventing its domain from spilling over into others. as an analogy, imagine you are designing an amusement park with various rides. Each ride in the park has its own theme and different rules, such as the roller coaster, haunted house, or giant Ferris wheel. Each ride has clear boundaries, with features and rules that apply only within that ride.&lt;/p&gt;

&lt;p&gt;In the roller coaster, the main rule is speed and passenger safety. All design and interactions in the roller coaster are focused on providing a thrilling and safe high-speed experience.&lt;/p&gt;

&lt;p&gt;In the haunted house, the main rule is to create suspense and surprise. All design elements and interactions in the haunted house focus on creating a spooky and mysterious atmosphere.&lt;/p&gt;

&lt;p&gt;In the giant Ferris wheel, the main rule is to enjoy the view. This ride is designed to offer a calm and scenic experience, without speed or tension.&lt;/p&gt;

&lt;p&gt;Even though all these rides are part of the same amusement park, each operates within its own bounded context, with its own rules, definition and goals.&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%2Fv78growiy43ntugexlkm.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%2Fv78growiy43ntugexlkm.png" alt="a1" width="800" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.geeksforgeeks.org/software-engineering-coupling-and-cohesion/" rel="noopener noreferrer"&gt;learn more about cohession and coupling&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lets take the example of an ecommerce application where a user can Login, Browse a list of products, Add products to the cart, Make a payment and chose the shipping method. &lt;/p&gt;

&lt;p&gt;This application can be modularized as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User Module: Handles user authentication (login, signup, password reset).&lt;/li&gt;
&lt;li&gt;Product Module: Handles product list, product details, and product filtering/searching.&lt;/li&gt;
&lt;li&gt;Cart Module: Manages the shopping cart, including adding/removing items, displaying total price, and updating quantities.&lt;/li&gt;
&lt;li&gt;Payment Module: Processes payments and manages transactions.&lt;/li&gt;
&lt;li&gt;Shipping Module: Manages shipping options and delivery methods.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And make sure, each module has boundaries defined based on the principle of bounded context, which means that each domain should have its own rules and responsibilities, ensuring that it operates independently within its own scope. This approach guarantees that each module has high cohesion (meaning all related functionalities are grouped together) and low coupling (meaning minimal dependencies on other modules).&lt;/p&gt;

&lt;h2&gt;
  
  
  Modular Approach in flutter using flutter package
&lt;/h2&gt;

&lt;p&gt;In Flutter, we can adopt a modular approach using Flutter packages. For example, if we create a new application named "TradingApp," we can organize the modules based on features such as Wallet, Login, and Market.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new Flutter project.&lt;/li&gt;
&lt;li&gt;After creating the TradingApp project, create the login module by going to File → New → New Flutter Project, and select Package.&lt;/li&gt;
&lt;/ul&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%2Fy94b1ca8a9onynxyxujc.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%2Fy94b1ca8a9onynxyxujc.png" alt="a2" width="800" height="481"&gt;&lt;/a&gt;&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%2Fhnkialx1mtwrmmoyo3so.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%2Fhnkialx1mtwrmmoyo3so.png" alt="a3" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Then, create the other modules. The project structure will look like this&lt;/li&gt;
&lt;/ul&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%2F7wxqq3o08l5sjlb2x4zi.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%2F7wxqq3o08l5sjlb2x4zi.png" alt="a4" width="776" height="1016"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To enable TradingApp to use the other modules, we need to link them with import dependencies, similar to Flutter libraries.&lt;/li&gt;
&lt;/ul&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%2F03ujmzhzmj6dum0g7ppi.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%2F03ujmzhzmj6dum0g7ppi.png" alt="a5" width="800" height="646"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This way, we can use different modules within our application.&lt;/li&gt;
&lt;/ul&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%2F4g55heimiowwbiut154u.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%2F4g55heimiowwbiut154u.png" alt="a6" width="800" height="830"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can also group modules into a single folder in our project. This will make the project structure and pubspec.yaml file look like this:&lt;/li&gt;
&lt;/ul&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%2F42gv5o49k7son1greujl.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%2F42gv5o49k7son1greujl.png" alt="a7" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Or If we prefer not to keep the modules in the same repository, we can use a different approach by placing each module in separate Git repositories.&lt;/li&gt;
&lt;/ul&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%2Fuvzppr4b10q0p9977tjd.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%2Fuvzppr4b10q0p9977tjd.png" alt="a8" width="800" height="900"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclussion
&lt;/h2&gt;

&lt;p&gt;Modularization enhances software development by breaking complex projects into manageable, focused components, which improves code quality, scalability, and maintainability. This approach allows for better organization, easier updates, and reusability of code, and facilitates collaboration among team members. And, for modularization to be effective, it is crucial to ensure high cohesion within modules and maintain low coupling between them.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Flutter Image Compression: Ensuring High Quality</title>
      <dc:creator>Irfan Adisukma</dc:creator>
      <pubDate>Thu, 14 Nov 2024 06:05:58 +0000</pubDate>
      <link>https://dev.to/tentanganak/flutter-image-compression-ensuring-high-quality-25m1</link>
      <guid>https://dev.to/tentanganak/flutter-image-compression-ensuring-high-quality-25m1</guid>
      <description>&lt;p&gt;In today's digital age, we often find ourselves taking countless photos and capturing memories on our devices. As developers, we want to make sure these images are not just beautiful but also efficient when it comes to uploading them to a server. This is where image compression comes into play. &lt;/p&gt;

&lt;p&gt;In this article, we’ll explore the ins and outs of image compression for Flutter, focusing specifically on how to balance quality and performance for seamless uploads. Whether you're building a social media app or a photo-sharing platform, understanding the art of compression can greatly enhance user experience while keeping your application running smoothly. Let's dive in!&lt;/p&gt;




&lt;p&gt;Image compression is the process of reducing the file size of an image without significantly compromising its quality. It involves removing unnecessary data or utilizing algorithms to make the file smaller. This is essential for several reasons, especially when uploading images to a server.&lt;/p&gt;

&lt;p&gt;Firstly, larger image sizes can lead to longer upload times. For users with slower internet connections or limited bandwidth, this delay can result in frustration and a poor overall experience. By compressing images before uploading, developers can ensure faster transfer speeds, making the process more seamless for users.&lt;/p&gt;

&lt;p&gt;Secondly, uploading large images can strain server resources. This can lead to increased storage costs and slower response times for other users accessing the server. By utilizing image compression, developers not only enhance the user experience but also optimize server performance and efficiency.&lt;/p&gt;

&lt;p&gt;So, understanding and implementing image compression is vital for any Flutter developer looking to improve their app's performance and user satisfaction, particularly in scenarios where image uploads are a common requirement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Image Conversion
&lt;/h2&gt;

&lt;p&gt;When it comes to image compression, there are two main types: lossy compression and lossless compression. Each has its pros and cons, making them suitable for different situations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lossy Compression
&lt;/h3&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%2Fu69ylrhfblpcty8ym72d.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%2Fu69ylrhfblpcty8ym72d.jpg" alt="Source: https://news.txst.edu/research-and-innovation/2021/txst-researchers-to-explore-state-of-the-art-lossy-compression.html" width="800" height="229"&gt;&lt;/a&gt;&lt;a href="https://news.txst.edu/research-and-innovation/2021/txst-researchers-to-explore-state-of-the-art-lossy-compression.html" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it is&lt;/strong&gt;: Lossy compression reduces image size by permanently removing some of the image’s data. It focuses on discarding details that are less noticeable to the human eye, making the file significantly smaller.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact on Quality&lt;/strong&gt;: This approach often leads to a small reduction in image quality, which may or may not be visible depending on the level of compression used. Higher compression ratios (smaller file sizes) often result in more noticeable quality loss, like blurring or pixelation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Use Cases&lt;/strong&gt;: Ideal for photos or images with lots of colors and gradients, like user-uploaded images or social media photos. JPEG is a common format that uses lossy compression.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lossless Compression
&lt;/h3&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%2Fvq0rk614dfsqwqvrkazw.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%2Fvq0rk614dfsqwqvrkazw.png" alt="Source: https://cyberhoot.com/cybrary/lossless-compression/" width="800" height="450"&gt;&lt;/a&gt;&lt;a href="https://cyberhoot.com/cybrary/lossless-compression/" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it is&lt;/strong&gt;: Lossless compression reduces file size without removing any image data. It achieves smaller files by finding and compressing patterns within the image, but no data is lost, so you can fully restore the original image.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact on Quality&lt;/strong&gt;: Since no data is discarded, image quality remains intact. However, lossless compression doesn’t reduce file size as dramatically as lossy compression, especially for complex images.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Use Cases&lt;/strong&gt;: Suitable for graphics, icons, or images where high fidelity is crucial, like logos or text-heavy images. PNG and GIF formats often use lossless compression.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing Between Lossy and Lossless
&lt;/h2&gt;

&lt;p&gt;When Quality is Crucial: Use lossless compression to retain full detail, especially if users may zoom in or if the image contains text or important details.&lt;/p&gt;

&lt;p&gt;When Reducing File Size is Key: Use lossy compression when you need a smaller file size and can afford slight quality loss, especially for thumbnails or images in feed views where high resolution isn't necessary.&lt;/p&gt;

&lt;p&gt;In summary, the choice between lossy and lossless compression hinges on your specific needs: prioritize speed and smaller files with lossy compression, or opt for higher quality with lossless compression. Understanding these options will help you optimize image uploads in your Flutter app.&lt;/p&gt;




&lt;p&gt;In this article, we'll focus more on lossy compression to achieve slight quality loss and smaller file sizes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Original (974Kb)
&lt;/h3&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%2Fczc9jtrgkzpl3knvf4ag.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%2Fczc9jtrgkzpl3knvf4ag.jpg" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;a href="https://www.goodfon.com/cats/wallpaper-koshka-dom-uiut-27.html" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;br&gt;
I have this original size file with 974Kb file size.&lt;/p&gt;

&lt;p&gt;And then i do compression with 90% Quality.&lt;/p&gt;
&lt;h3&gt;
  
  
  90% Quality (318Kb)
&lt;/h3&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%2Fkx2ztfkay7cj4my80ytq.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkx2ztfkay7cj4my80ytq.jpeg" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;With 90% quality we can achieve the compression rate at approximately 67.35% from 974Kb to 318Kb.&lt;/p&gt;
&lt;h3&gt;
  
  
  50% Quality (109Kb)
&lt;/h3&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%2Fp6km1p6pij1wdo4yj2lx.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp6km1p6pij1wdo4yj2lx.jpeg" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;With 50% quality we can achieve the compression rate at approximately 88.81% from 974Kb to 109Kb.&lt;/p&gt;
&lt;h3&gt;
  
  
  10% Quality (55Kb)
&lt;/h3&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%2Fed1mwvzfhujcx6m7i0e2.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fed1mwvzfhujcx6m7i0e2.jpeg" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;With 10% quality we can achieve the compression rate at approximately 94.35% from 974Kb to 55Kb.&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%2Fifkqkedcgj9a7do3sxwa.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%2Fifkqkedcgj9a7do3sxwa.png" alt="Image description" width="800" height="200"&gt;&lt;/a&gt;Based on the quality comparisons above, you can decide which compression level works best for your needs. If image quality is a priority (for product photos or detailed images), higher quality settings (e.g., 90 or above) should be used to maintain clarity, though they result in larger file sizes.&lt;/p&gt;

&lt;p&gt;If file size is more important, such as for thumbnails or gallery images, lower quality settings (e.g., 50 or even 10) can be used to significantly reduce file size, though some visual degradation will occur. The choice depends on whether you prioritize visual fidelity or performance and size optimization.&lt;/p&gt;


&lt;h2&gt;
  
  
  Code Implementation
&lt;/h2&gt;

&lt;p&gt;Here’s an example of a function to compress an image in Flutter using the flutter_image_compress package:&lt;/p&gt;

&lt;p&gt;You only need these two packages:&lt;br&gt;
&lt;a href="https://pub.dev/packages/flutter_image_compress" rel="noopener noreferrer"&gt;Flutter Image Compress Package&lt;/a&gt;&lt;br&gt;
&lt;a href="https://pub.dev/packages/image_picker" rel="noopener noreferrer"&gt;Flutter Image Picker&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Pick Image
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:image_picker/image_picker.dart';

final ImagePicker picker = ImagePicker();
File? selectedImage;

Future&amp;lt;void&amp;gt; pickImage() async {
    final pickedFile = await picker.pickImage(source: ImageSource.gallery);
    if (pickedFile != null) {
      setState(() {
        selectedImage = File(pickedFile.path);
      });
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Compress Image
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:path/path.dart' as path;
import 'package:flutter_image_compress/flutter_image_compress.dart';

Future&amp;lt;XFile&amp;gt; compressImageFile(
    {
      required File imageFile, 
      int quality = 80, 
      CompressFormat format = CompressFormat.jpeg
    }) async {

    DateTime time = DateTime.now();
    final String targetPath = path.join(
      Directory.systemTemp.path, 'imagetemp-${format.name}-$quality-${time.second}.${format.name}'
    );

    final XFile? compressedImageFile = await FlutterImageCompress.compressAndGetFile(
      imageFile.path,
      targetPath,
      quality: quality,
      format: format
    );

    if (compressedImageFile == null){
      throw ("Image compression failed! Please try again.");
    }
    debugPrint("Compressed image saved to: ${compressedImageFile.path}");
    return compressedImageFile;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;UI Example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
    if (selectedImage != null) 
      Image.file(
        selectedImage!
      ),
    TextButton(
      onPressed: () async {
        await pickImage();
      }, 
      child: const Text("Pick Image")
    ),

    ElevatedButton(
      onPressed: () {
        if (selectedImage != null) {
          compressImageFile(
            imageFile: selectedImage!,
            quality: 10
          );
        }
      }, 
      child: const Text("Compress")
    )
  ],
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you'd like to view the code for the sample usage app above, please visit:&lt;br&gt;
&lt;a href="https://github.com/irfanadisukma/flutter-image-compression" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;References:&lt;br&gt;
&lt;a href="https://www.dhiwise.com/post/guide-to-improving-app-performance-with-flutter-resize-image" rel="noopener noreferrer"&gt;www.dhiwise.com&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.adobe.com/uk/creativecloud/photography/discover/lossy-compression.html#:~:text=By%20definition%2C%20lossy%20compression%20removes,hence%20the%20term%20'lossy'." rel="noopener noreferrer"&gt;www.adobe.com&lt;/a&gt;&lt;br&gt;
&lt;a href="https://cyberhoot.com/cybrary/lossless-compression/" rel="noopener noreferrer"&gt;cyberhoot.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>compression</category>
      <category>image</category>
    </item>
    <item>
      <title>Defensive Programming as a Backend Developer: Building Robust and Secure Systems</title>
      <dc:creator>Rizky Darmawan</dc:creator>
      <pubDate>Mon, 11 Nov 2024 03:10:17 +0000</pubDate>
      <link>https://dev.to/tentanganak/defensive-programming-as-a-backend-developer-building-robust-and-secure-systems-50kk</link>
      <guid>https://dev.to/tentanganak/defensive-programming-as-a-backend-developer-building-robust-and-secure-systems-50kk</guid>
      <description>&lt;p&gt;In backend application development, ensuring application security and stability is an absolute must. The backend is the backbone of the application, which is responsible for handling business logic, storing data, and interacting with external systems. Writing strong and reliable code is essential for all software developers. However, no matter how careful we are, bugs and unexpected situations can still occur. This is where Defensive programming comes into play.&lt;/p&gt;

&lt;p&gt;Defensive programming is a coding practice aimed at ensuring that software functions correctly even when unexpected events or invalid input occur. For a backend developer defensive programming is an important approach, which allows us to design applications that can survive bad input, system errors, and external attacks. &lt;/p&gt;

&lt;p&gt;In this article, we will discuss several points on how defensive programming can be applied to increase the resilience of backend applications and provide examples in the Golang language to illustrate how to implement it, although its implementation is not tied to just one language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate Input Data from External Sources
&lt;/h2&gt;

&lt;p&gt;External sources such as third-party API users, or databases can be entry points for various attacks, especially if the input provided is invalid or malicious. Attacks such as SQL injection, cross-site scripting (XSS), and command injection often occur due to input that is not properly filtered. We can apply the following points to overcome this:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Input Sanitation
&lt;/h3&gt;

&lt;p&gt;Any input from outside sources must be sanitized. Input sanitization is the process of ensuring that data received from users or external sources is cleaned of malicious characters before it is used in an application, especially when the data is used for SQL queries, system commands, or output to the browser. For example, if you receive string input from a form, avoid entering that input directly into a SQL query without sanitization. What you can do is use &lt;strong&gt;prepared statements&lt;/strong&gt; to prevent SQL Injection. With prepared statements, user input is not allowed to be part of the SQL command, but rather as a safe parameter. For example, we have input to check the user's &lt;em&gt;username&lt;/em&gt; and &lt;em&gt;password&lt;/em&gt; for login and our backend system, rather than directly running the following query:&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;// direct query with parameters&lt;/span&gt;
&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT * FROM users WHERE username = '%s' AND password = '%s'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;john_doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;12345&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is better to use prepared statements, where we ensure that user input is never executed as part of a SQL query. Input is considered a value, not part of a SQL command as follows:&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;// prepared statement&lt;/span&gt;
&lt;span class="nx"&gt;stmt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Prepare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT * FROM users WHERE username = ? AND password = ?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error while prepared statement: %v&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&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="nx"&gt;defer&lt;/span&gt; &lt;span class="nx"&gt;stmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// excecution prepared statement&lt;/span&gt;
&lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;john_doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;12345&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;stmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error while run query: %v&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&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="nx"&gt;defer&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Data Type Validation
&lt;/h3&gt;

&lt;p&gt;Data type validation is the process of checking and ensuring that the type of data received is as expected before further processing. This is important to prevent errors in data processing and also reduce security risks, such as SQL injection and XSS. For example, if an API expects an email format, validate that the input is indeed an email format. The following is an example of carrying out the data type validation process in Golang:&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="nx"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;input&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello@world.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

    &lt;span class="c1"&gt;// Use regex to validate email format&lt;/span&gt;
    &lt;span class="nx"&gt;re&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;regexp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MustCompile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} $`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MatchString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid email format.&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Valid email:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&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 use a regular expression to validate whether the input corresponds to the correct email format.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Whitelist &amp;amp; Blacklist
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Whitelist&lt;/strong&gt; and &lt;strong&gt;blacklist&lt;/strong&gt; are two approaches used to validate and manage user input in applications. Both have the goal of improving security and preventing exploits, but they work and are applied differently.&lt;/p&gt;

&lt;h4&gt;
  
  
  - whitelist
&lt;/h4&gt;

&lt;p&gt;Whitelisting is an approach where only certain data or characters are &lt;strong&gt;allowed&lt;/strong&gt; to be processed by the application. In the context of user input, a whitelist determines what is considered "safe" and allows only input that meets those criteria. It is often used to validate very specific data. Example of use:&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="nx"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;isValidUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// using regex to check allowed characters &lt;/span&gt;
    &lt;span class="nl"&gt;re&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;regexp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MustCompile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`^[a-zA-Z0-9_-]+$`&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;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MatchString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;input&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user_name-123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;isValidUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Valid username:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid username.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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 the example above, the use of &lt;code&gt;regex ^[a-zA-Z0-9_-]+$&lt;/code&gt; is used to limit the characters allowed in the username. Only letters, numbers, _ (underscore), and - (dash) are accepted.&lt;/p&gt;

&lt;h4&gt;
  
  
  - Blacklist
&lt;/h4&gt;

&lt;p&gt;Blacklisting is an approach where you specify certain data or characters that are &lt;strong&gt;not allowed&lt;/strong&gt;. In this case, all other inputs are considered safe, except those on the blacklist. This approach is often used when it is difficult to predict all possible safe characters. Example of use:&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="nx"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;isValidInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// List not allowed characters&lt;/span&gt;
    &lt;span class="nl"&gt;blacklist&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="nx"&gt;blacklist&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;strings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;input&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello &amp;amp; welcome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;isValidInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Valid input:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid input.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;Here, we use a blacklist to check whether the input contains unwanted characters. If present, the input is considered invalid.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Input Limit
&lt;/h3&gt;

&lt;p&gt;Input Limit is the practice of limiting the amount of data or size of input that can be accepted from users in an application. The goal is to prevent excessive use of resources, improve application performance, and protect against potential attacks, such as Denial of Service (DoS) or SQL injection. The following is an example of its implementation:&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="nx"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;validateUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="c1"&gt;// Username is too long username is too long&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// username is valid&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;input&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ThisIsAReallyLongUsername&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;validateUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Valid username:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid username: username cannot exceed 20 characters.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;Of course, some of the points above can be applied to any programming language and can be used using libraries that are widely available so that the data validation process is easier than carrying out a manual validation process like some of the examples above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Security
&lt;/h2&gt;

&lt;p&gt;Sensitive data such as personal information or credentials must always be protected, both when stored and when transferred. We can apply the following points to overcome this:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Data encryption
&lt;/h3&gt;

&lt;p&gt;Sensitive data such as passwords or credit card information should always be encrypted. Encryption involves the process of converting readable data (plaintext) into an unintelligible form (ciphertext) using an encryption algorithm and encryption key. The main purpose of encryption is to ensure that even if data falls into the wrong hands, it cannot be read without the right key to decrypt it.&lt;/p&gt;

&lt;p&gt;Use modern encryption algorithms such as &lt;strong&gt;AES&lt;/strong&gt; and avoid outdated algorithms such as &lt;strong&gt;MD5&lt;/strong&gt; or SHA1.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Use HTTPS
&lt;/h3&gt;

&lt;p&gt;Use HTTPS (Hypertext Transfer Protocol Secure) to ensure that all data transferred between the client and server is properly encrypted. HTTPS (Hypertext Transfer Protocol Secure) is a secure version of HTTP, which is a protocol used for data transfer between a browser (client) and a server. &lt;/p&gt;

&lt;p&gt;HTTPS works by adding a layer of security by using TLS (Transport Layer Security) or SSL (Secure Sockets Layer) to encrypt data sent over the network. This is especially important in backend development because it prevents third parties (such as hackers) from reading or modifying data that is being sent between the client and the server.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Tokenization &amp;amp; Masking
&lt;/h3&gt;

&lt;p&gt;In certain cases, tokenization or masking can be used to reduce the risk of a data breach. &lt;strong&gt;Tokenization&lt;/strong&gt; and &lt;strong&gt;Masking&lt;/strong&gt; are two data security techniques frequently used in backend applications to protect sensitive data.&lt;/p&gt;

&lt;p&gt;Tokenization is the process of replacing sensitive data (such as credit card numbers) with meaningless values ​​called “tokens.” The original data is stored separately and can only be linked back to the token through a system that has access to the system that manages the token. This is important because if a data leak occurs, but the leaked data is only a token and not real data, the risk of attack is greatly reduced because the token has no value outside the system context. For example, in online payments, credit card numbers can be replaced with tokens so that card data does not actually need to be stored on the server.&lt;/p&gt;

&lt;p&gt;Data masking is the process of hiding part of sensitive data so that only some parts are visible. This is often used in user interfaces or reports to prevent complete information from being exposed. How does this work? data masking protects sensitive information when displayed to users who do not need to know the full data. Even if the data displayed in the UI or logs is stolen, the masked data only shows partial information, so the risk is lower. An example that we may often see is hiding part of a credit card number in a display like this: &lt;code&gt;**** **** **** 1234&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error Management &amp;amp; Logging
&lt;/h2&gt;

&lt;p&gt;In building a system errors will always occur, but how we handle them determines whether our application can survive without causing damage or loss of data. Good logging helps track problems in production systems and detect suspicious patterns. Here are some points that we do:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Handle Errors Appropriately
&lt;/h3&gt;

&lt;p&gt;Don't just catch errors without taking action or providing information. It's best to log errors and provide a good fallback to avoid a total crash. For example, if the connection to the database fails, try retrying or switching to read-only mode temporarily.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Granular Logging
&lt;/h3&gt;

&lt;p&gt;Log critical events such as API requests, authentication failures, or database connection problems with a sufficient level of detail. However, remember to avoid recording sensitive information such as passwords in logs.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Log Splitting
&lt;/h3&gt;

&lt;p&gt;Use different log levels such as INFO, WARNING, and ERROR to separate different types of events. More granular logs make it easier for developers to diagnose problems.&lt;/p&gt;

&lt;p&gt;For a more complete discussion and examples of &lt;strong&gt;Error Management &amp;amp; Logging&lt;/strong&gt; I have written an article about this here: &lt;a href="https://dev.to/tentanganak/observability-why-logging-its-important-104b"&gt;Observability - Why logging is important&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Avoid mistakes elegantly
&lt;/h2&gt;

&lt;p&gt;Crashing is a response that occurs when the system encounters an unexpected error. However, errors can be avoided or minimized through better handling. The strategies below can help us handle errors elegantly to make the system more resilient.&lt;/p&gt;

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

&lt;p&gt;When backend applications access external services or wait for resources such as databases, it is important to use timeouts. Timeouts prevent code from being "stuck" in an indefinite waiting state, thereby maintaining application performance and avoiding deadlocks. The following is an example of implementing a timeout when accessing an external service:&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="nx"&gt;client&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;Timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Set timeout 5 detik&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://example.com/api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Request failed:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&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="nx"&gt;defer&lt;/span&gt; &lt;span class="nx"&gt;resp&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="nc"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Response received:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Status&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, we set a 5 second timeout for HTTP requests. If the service doesn't respond within 5 seconds, the app won't hang, and we can handle the error by announcing the failure.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Resource Existence Checks
&lt;/h3&gt;

&lt;p&gt;Before accessing other resources such as databases, files or APIs, always verify their existence and availability. This prevents applications from making requests to resources that may not exist, which saves time and avoids unnecessary errors. Here's an example of how we check:&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="nx"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;filePath&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./data.txt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Stat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// check status file&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IsNotExist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;File %s not found.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;File %s is available.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&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;h3&gt;
  
  
  3. Fallback
&lt;/h3&gt;

&lt;p&gt;When the system carries out certain processes, we might get an error. For example, our system sends an OTP during the authentication process. When the OTP sending process fails or gets an error, we can use a fallback mechanism or backup method, such as diverting OTP sending to our backup provider.&lt;/p&gt;

&lt;p&gt;By implementing the strategies above, we can reduce the frequency of errors that cause crashes, maintain application performance, and improve the overall user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Secure and Solid API Design
&lt;/h2&gt;

&lt;p&gt;We can see that APIs function as the backbone for applications or web that require dynamic data resources. However, because they are considered such a critical backbone, APIs are often the main target for attacks, so it is important to ensure APIs that are secure and difficult to exploit.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Authentication &amp;amp; Authorization
&lt;/h3&gt;

&lt;p&gt;Use strong authentication (such as OAuth or JWT) to ensure that only authorized users or systems can access our APIs. Implement granular access control to limit the access rights of clients who access the API that we have. This can prevent clients with malicious intent from accessing the resources we have.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Rate Limiting and Throttling
&lt;/h3&gt;

&lt;p&gt;Rate Limiting and Throttling are critical to controlling API usage and preventing misuse or overloading. The application of rate limiting is also to prevent attacks such as DDoS or excessive exploitation of the API by users or bots, and also to maintain the stability and availability of the API for all users. Rate Limiting works by regulating the volume of requests from API clients within set intervals, ensuring fair and equal access to the resources we have.&lt;/p&gt;

&lt;h2&gt;
  
  
  Efficient Use of Resources
&lt;/h2&gt;

&lt;p&gt;Backend systems often have to manage various resources such as database connections, files, or memory. Efficient resource management is critical to maintaining application stability and performance. By handling resources wisely, we can avoid problems such as "resource leaks" and system failures. The following are several strategies that can be used for efficient use of resources:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Connection Pooling
&lt;/h3&gt;

&lt;p&gt;Connection Pooling is a technique where a number of connections to a service such as a database are recycled rather than creating a new connection every time an application needs access. With connection pooling, applications do not need to create expensive new connections every time there is a request, but instead use existing connections in the "pool".&lt;/p&gt;

&lt;p&gt;Why is connection pooling important?, Every connection to a database or other service has overhead in terms of time and memory. Continuously opening and closing connections can drain system resources. By recycling existing connections, applications can respond more quickly and reduce the load on external services such as databases.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. File &amp;amp; Memory Management
&lt;/h3&gt;

&lt;p&gt;When dealing with files or memory allocation, it is important to ensure that resources are released after they have been used. If not, it could cause resource leaks which result in the application running out of memory or file handles.&lt;/p&gt;

&lt;p&gt;For example, in Golang we can use the built-in function &lt;strong&gt;defer&lt;/strong&gt; to ensure files, connections, or other resources are always released after they are finished using them. Then also check for errors (error handling) when working with resources, so that if a problem occurs, the resource can still be released correctly. &lt;/p&gt;

&lt;p&gt;Here's a little code snippet of how we use defer to turn off an operation and close it after a function has finished carrying out a process:&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="nx"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// open file process&lt;/span&gt;
    &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example.txt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error opening file:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&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="c1"&gt;// Make sure the file is closed when finishedinished&lt;/span&gt;
    &lt;span class="nx"&gt;defer&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// Process file...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using defer, we ensure that the file will be closed as soon as the function exits, whether it is successful or an error occurs. This helps prevent file handle leaks that can occur if you forget to close a file.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Asynchronous Operations
&lt;/h3&gt;

&lt;p&gt;In situations where the application performs heavy tasks or slow I/O operations (such as accessing large files, or calling external APIs), running it &lt;strong&gt;Asynchronously&lt;/strong&gt; is an efficient way to avoid blocking the application. Where applications that perform synchronous operations can be hampered while waiting for heavy tasks to complete, which will affect overall performance. So the use of asynchronous processes is sometimes important because it allows applications to continue other tasks while waiting for I/O or network tasks to complete.&lt;/p&gt;

&lt;p&gt;Let's say we have a case where we clear the Redis cache after data input. The cache deletion process can be run asynchronously so as not to slow down the main process. This means the application does not need to wait for Redis to respond before continuing to execute the next code. As a result, the application remains responsive and efficient.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;As a backend developer, defensive programming is an essential approach to ensuring that the applications we build can handle errors, invalid input, and external threats properly. By practicing the techniques above, we can ensure that the backend applications we build are more secure, stable and resilient in facing various unexpected situations. Defensive programming helps us create systems that not only function well, but are also able to survive the worst conditions.&lt;/p&gt;

&lt;p&gt;Of course, there may be many other important points that are not discussed above, you can add or provide suggestions in the comments column above.&lt;/p&gt;

&lt;p&gt;Hopefully it's useful 👋.&lt;/p&gt;

&lt;h1&gt;
  
  
  Reference
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.conquer-your-risk.com/2023/07/20/the-code-knight-mastering-the-craft-of-defensive-programming/" rel="noopener noreferrer"&gt;The Code Knight: Mastering the Craft of Defensive Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/c-sharp-programming/defensive-programming-in-c-best-practices-and-examples-f1edeb676e97" rel="noopener noreferrer"&gt;Defensive Programming in C#: Best Practices and Examples
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@arumukherjee121/the-art-of-defensive-programming-62c6f22b2758" rel="noopener noreferrer"&gt;The Art of Defensive Programming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>backend</category>
      <category>backendtips</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Master Multiple Density Image Assets in Flutter: Boost Your App’s Visuals!</title>
      <dc:creator>Vincentius Westley</dc:creator>
      <pubDate>Tue, 08 Oct 2024 03:19:39 +0000</pubDate>
      <link>https://dev.to/tentanganak/master-multiple-density-image-assets-in-flutter-boost-your-apps-visuals-1759</link>
      <guid>https://dev.to/tentanganak/master-multiple-density-image-assets-in-flutter-boost-your-apps-visuals-1759</guid>
      <description>&lt;p&gt;As the mobile landscape continues to evolve, the range of screen sizes and resolutions across devices has expanded significantly. From compact smartphones to expansive tablets, ensuring that your application’s visuals remain sharp and consistent across all these devices is crucial. This is where the concept of &lt;strong&gt;multiple density image assets&lt;/strong&gt; comes into play, especially in the context of Flutter—a popular framework for cross-platform mobile development.&lt;/p&gt;




&lt;p&gt;📄 &lt;strong&gt;Understanding Screen Density and Image Assets&lt;/strong&gt;&lt;br&gt;
Before getting into the details of Flutter it’s important to understand the basics of screen density and image assets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Screen Density (DPI)&lt;/strong&gt;: Density refers to the number of pixels within a given physical area of the screen, typically measured in dots per inch (DPI). Devices with higher screen densities have more pixels per inch, which makes their displays sharper and clearer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Image Assets&lt;/strong&gt;: These are the visual elements (like icons, buttons, and background images) used in an app. To appear sharp on screens with different densities, these assets need to be provided in multiple resolutions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why Multiple Density Image Assets Matter&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1. Enhanced Visual Quality&lt;/strong&gt;: High-resolution devices demand high-quality images to avoid appearing pixelated. By providing multiple density image assets, you ensure that your images look sharp and clear on any device, regardless of its screen density.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Optimized Performance&lt;/strong&gt;: Using the appropriate image for each screen density can significantly improve performance. Loading images that are too large for a given screen’s resolution wastes memory and processing power, leading to slower performance and higher power consumption. Multiple density assets allow Flutter to select the most suitable image, optimizing both memory usage and performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Consistent User Experience&lt;/strong&gt;: Ensuring that images look consistent across various devices is crucial for a seamless user experience. Whether your app is being used on a low-resolution screen or a high-resolution one, users should have a consistent visual experience. Multiple density image assets help achieve this by providing the right image for each screen type.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Scalability Across Devices&lt;/strong&gt;: As new devices with varying screen resolutions are released, having multiple density assets makes your app scalable and future-proof. It ensures that your app can easily adapt to new hardware without requiring significant changes or additions to your image assets.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Implementing Multiple Density Image Assets in Flutter&lt;/strong&gt;&lt;br&gt;
Flutter simplifies the process of handling multiple density image assets through its asset management system. Here’s a step-by-step guide on how to implement them effectively:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Preparing Image Assets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For each image asset, prepare multiple versions at different resolutions. Commonly, these are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;1x for baseline resolution (mdpi)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;1.5x for low-density screens (hdpi)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;2x for medium-density screens (xhdpi)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;3x for high-density screens (xxhdpi)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;4x for extra-high-density screens (xxxhdpi)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, if you have an icon named &lt;code&gt;logo.webp&lt;/code&gt; for a baseline resolution, you should also provide &lt;code&gt;logo@1.5x.webp&lt;/code&gt;, &lt;code&gt;logo@2x.webp&lt;/code&gt;, &lt;code&gt;logo@3x.webp&lt;/code&gt;, and &lt;code&gt;logo@4x.webp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;📄 - In this example, I'm using WebP for all the images because WebP offers better image compression. It's a good idea to use WebP for your images too. To learn more, visit this link.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Organizing Assets in the Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Organize these assets in your Flutter project’s assets directory. A typical structure might look 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;assets/
  - images/
      - logo.webp
      - 1.0x/
        - logo.webp
      - 1.5x/
        - logo.webp
      - 2.0x/
        - logo.webp
      - 3.0x/
        - logo.webp
      - 4.0x/
        - logo.webp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Defining Assets in pubspec.yaml&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In your &lt;code&gt;pubspec.yaml&lt;/code&gt; file, list the image assets. Flutter will automatically detect and use the appropriate resolution based on the device’s screen density:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutter:
  assets:
    - assets/images/logo.webp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Using Assets in Your Flutter Code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When you need to use these assets in your Flutter widgets, simply refer to the base asset name. Flutter’s asset resolution system will automatically select the most suitable image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Image.asset('assets/images/logo.webp');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Best Practices for Managing Multiple Density Assets&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1. Asset Compression&lt;/strong&gt;: Optimize your images for size without sacrificing quality. Tools like Respresso can help compress images while maintaining their visual fidelity and also splitting your image to all density.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Regular Updates&lt;/strong&gt;: As new devices with higher resolutions are released, ensure that your assets are updated accordingly to support these new screens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Testing on Multiple Devices&lt;/strong&gt;: Always test your app on a variety of devices and screen densities to ensure that your assets render correctly and the user experience remains consistent.&lt;/p&gt;




&lt;p&gt;⛔ &lt;strong&gt;Trade-offs of Implementing Multiple Density Image Assets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While multiple density image assets offer some benefits, they also come with certain trade-offs that developers should consider:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Increased App Size&lt;/strong&gt;&lt;br&gt;
In Flutter providing multiple versions of each image for different screen densities will inevitably increase the overall size of your app. This can be a concern for users with limited storage or slow download speeds. Large app sizes can also affect your app’s ranking and reviews, as users often prefer smaller, quicker-to-download apps.&lt;/p&gt;

&lt;p&gt;📄 - The way multiple image densities are handled differs between native apps and Flutter. In native apps, using different densities can reduce the app's download size because only the appropriate density images are downloaded for each device. However, in Flutter, all image densities are included in the app package, which means the app download size isn't reduced by splitting images based on density.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Development and Maintenance Overhead&lt;/strong&gt;&lt;br&gt;
Managing multiple versions of each image can increase the complexity of your development process. You need to ensure that all images are updated consistently across all densities, which can be time-consuming. This also requires designers and developers to work closely together to maintain image quality and consistency across different resolutions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Balancing Trade-offs&lt;/strong&gt;&lt;br&gt;
When deciding whether to implement multiple density image assets, consider the nature of your app and your target audience:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- High-End Visuals&lt;/strong&gt;: If your app relies heavily on visual quality (e.g., a graphic-rich game or a photo editing app), investing in multiple density assets is crucial despite the increased app size.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Performance Optimization&lt;/strong&gt;: For apps that prioritize performance and efficient resource use, multiple density assets can reduce CPU load and power consumption, making the app more responsive.&lt;br&gt;
**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App Size Constraints**: If your app is targeted at regions with limited internet connectivity or users who are sensitive to download sizes, you might choose to use fewer resolutions or use methods that deliver assets as needed.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;✨ &lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Implementing multiple density image assets in Flutter is a strategic choice that balances visual quality, performance, and app size. By providing the right assets for each screen density, you ensure your app looks sharp and performs well across a variety of devices. However, this comes at the cost of increased app size and development complexity.&lt;/p&gt;

&lt;p&gt;As a Flutter developer, it’s essential to evaluate your app’s specific needs and user demographics when deciding how to manage image assets. Whether you choose to implement multiple density image assets for optimal performance or streamline assets to minimize app size, the decision should align with your app’s goals and user expectations. By carefully considering these factors, you can deliver a high-quality user experience while maintaining efficient app performance.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Handle Time Zones and Sync Your Software on the server side using Go</title>
      <dc:creator>Rizky Darmawan</dc:creator>
      <pubDate>Tue, 01 Oct 2024 02:08:22 +0000</pubDate>
      <link>https://dev.to/tentanganak/how-to-handle-time-zones-and-sync-your-software-on-the-server-side-using-go-16ip</link>
      <guid>https://dev.to/tentanganak/how-to-handle-time-zones-and-sync-your-software-on-the-server-side-using-go-16ip</guid>
      <description>&lt;p&gt;When your application starts on a large scale, the increase in users will increase. What is very likely to happen is that the user's location is not only in the same area, it could be in another area that has a different time zone. So as a Backend developer, things related to handling time zone differences are very important to think about.&lt;/p&gt;

&lt;p&gt;I recently came across an issue involving time zones. Let's be honest, dealing with dates and times is one of the most complicated areas a human being has to deal with. And this was an opportunity for me to learn how to properly handle dates and times on the server side.&lt;/p&gt;

&lt;p&gt;In this article, I will share my experience on how I handle time zone differences on the server side as a Backend developer. Maybe if someone is willing to correct and provide additional input that would be valuable for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  About Time Zone
&lt;/h2&gt;

&lt;p&gt;Time zones are a standard time division system used throughout the world to organize and standardize the measurement of time. This concept emerged as a response to the need for global time coordination, especially along with developments in communications and transportation technology.&lt;/p&gt;

&lt;p&gt;The basic principle of time zones is the division of the earth into 24 zones. Each time zone is generally one hour different from the zone next to it. The main reference for time zones is Greenwich Mean Time (GMT) or Coordinated Universal Time (UTC), which is at the zero degrees longitude line that passes through Greenwich, England.&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%2F12w82kobmce87b5rm7zz.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%2F12w82kobmce87b5rm7zz.png" alt="Image description" width="800" height="431"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Illustration by &lt;a href="https://commons.wikimedia.org/wiki/User:Hellerick" rel="noopener noreferrer"&gt;Hellerick&lt;/a&gt; from &lt;a href="https://en.wikipedia.org/wiki/File:Standard_World_Time_Zones.png" rel="noopener noreferrer"&gt;Wikimedia Commons&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A small example is when the clock shows 12:00 noon in Jakarta, in New York the time shows 00:00 or midnight. This means that while Jakartans are enjoying lunch, New Yorkers are just starting their new day. From here you can certainly imagine the importance of handling time zones correctly in building an application.&lt;/p&gt;
&lt;h2&gt;
  
  
  Timezone handling on the server side
&lt;/h2&gt;

&lt;p&gt;After we have seen the explanation above, now we will go into the points that can be done when our server application receives a request from a client that accesses our API to handle its time zone.&lt;/p&gt;

&lt;p&gt;In this article, I will discuss several approaches to handling time zones on the server side. Here I will use code examples in the Golang (Go) language. Golang has a time package for working with time-related data which is considered quite complete. Here are some points that we will discuss:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to save date to DB&lt;/li&gt;
&lt;li&gt;Conversion of user's local time &lt;/li&gt;
&lt;li&gt;Testing and Validation&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  How to save date to DB
&lt;/h2&gt;

&lt;p&gt;The first thing we will discuss is which time we will save in the database, for example we have an ecommerce application that does flash sales, where our application is already on an international scale. &lt;/p&gt;

&lt;p&gt;When a user processes a purchase transaction in America or if the user is in Indonesia, the user will send their different local time to the server. The question is, will our database store time data according to the user's local time? If the answer is yes, it is likely a complicated problem when we want to retrieve the data or for example the admin wants to do data processing, which user makes the earliest transaction.&lt;/p&gt;

&lt;p&gt;To overcome this, the best practice is to store transaction times in the &lt;strong&gt;UTC&lt;/strong&gt; (Coordinated Universal Time) time zone which is the primary time standard for clocks and time settings. Here is the application of the time to UTC.&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="kr"&gt;package&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fmt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nl"&gt;now&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Local time: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;nowInUTC&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;UTC&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UTC time: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nowInUTC&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;Let's see the meaning of the code above.&lt;/p&gt;

&lt;p&gt;First, in the &lt;code&gt;now := time.Now()&lt;/code&gt; code line, this line uses the &lt;code&gt;Now()&lt;/code&gt; function from the &lt;strong&gt;time&lt;/strong&gt; package to get the current time based on the system's local time zone. The result is stored in the current variable.&lt;/p&gt;

&lt;p&gt;Then, in the &lt;code&gt;nowInUTC := now.UTC()&lt;/code&gt; line, here we convert the local time (now) to UTC time using the &lt;code&gt;UTC()&lt;/code&gt; method. The results are stored in a new variable nowInUTC and this time can be stored on the server, where it is hoped that developers can avoid ambiguity and errors that may arise due to time zone differences between servers and users in various regions with different time zones.&lt;/p&gt;

&lt;p&gt;Here are the results if we run the code above:&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%2F4qn7wuwxtycrtko6mrl2.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%2F4qn7wuwxtycrtko6mrl2.png" alt="Image description" width="524" height="52"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But this is not always the best solution that you should use. There may be some points you can keep in mind in certain use cases, one of which is is it true that our users come from different time zones? If it's not possible, perhaps storing the time in UTC will add complexity to your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Change time to user locale
&lt;/h3&gt;

&lt;p&gt;At the discussion point above, we have agreed to store user time data in one location, namely UTC. Now how users can see accurate time according to their location. An example of the discussion above is a flash sale on an e-commerce application that we have, where users also want to know information about which user made the first transaction. So at this point, converting the time we store in the database to the user's local time is another important thing that we should not ignore.&lt;/p&gt;

&lt;p&gt;The approach I take is that the server side always asks the client to send the timezone on the user side. This can be done on the request side where the client sends a header with the key &lt;code&gt;timezone&lt;/code&gt; and has the user's timezone value. For example, Indonesia has 3 time zone divisions, namely WIT(+9), WITA(+8), WIB(+7). Where each zone has a difference of 1 hour. If previously on our server we stored UTC time at 00.00, then on the WIT side it was at 09.00, then on the WITA side it was at 08.00 and WIB at 07.00.&lt;/p&gt;

&lt;p&gt;Here's an example code to handle the above case:&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="kr"&gt;package&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fmt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="nc"&gt;ParseTimezoneFromString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tz&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Location&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tz&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2006 -07:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2007 %s&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tz&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="nf"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&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;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nc"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nl"&gt;timeServerInUTC&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2024-08-04 00:00:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;nowInUTC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2006-01-02 15:04:05&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;timeServerInUTC&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UTC time: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nowInUTC&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;witLocation&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ParseTimezoneFromString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;+09:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;nowInWIT&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nowInUTC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;In&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;witLocation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WIT time: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nowInWIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;witaLocation&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ParseTimezoneFromString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;+08:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;nowInWITA&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nowInUTC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;In&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;witaLocation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WITA time: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nowInWITA&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;wibLocation&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ParseTimezoneFromString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;+07:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;nowInWIB&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nowInUTC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;In&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wibLocation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WIB time: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nowInWIB&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;&lt;em&gt;credit to &lt;a href="https://dev.to/dikac"&gt;dikac&lt;/a&gt; for create this function ParseTimezoneFromString&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's understand the meaning of the code above:&lt;/p&gt;

&lt;p&gt;First, we create a function &lt;code&gt;ParseTimezoneFromString&lt;/code&gt;, where this function is used to find the time location based on the argument &lt;code&gt;tz&lt;/code&gt; or timezone of the given user location. If the string value &lt;code&gt;tz&lt;/code&gt; is valid, we will convert the string's timezone using the &lt;code&gt;time.Parse&lt;/code&gt; function to convert the string to a time object, then extract the location (timezone) from that object. And we also handle if the string is empty or parsing fails, the function returns the local time zone of the system.&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="nx"&gt;func&lt;/span&gt; &lt;span class="nc"&gt;ParseTimezoneFromString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tz&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Location&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tz&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2006 -07:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2007 %s&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tz&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="nf"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&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;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nc"&gt;Location&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;Next we also define time data in the following string format:&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="nx"&gt;timeServerInUTC&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2024-08-04 00:00:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;nowInUTC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2006-01-02 15:04:05&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;timeServerInUTC&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&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;You can think of this as the timing data that we get from the server. And parse it into a time object.&lt;/p&gt;

&lt;p&gt;Next, we try to find the user's accurate location based on the &lt;code&gt;ParseTimezoneFromString&lt;/code&gt; function that we previously created based on the string argument that we defined. What needs to be paid attention to is that this string argument is what is meant by the value of the &lt;code&gt;timezone&lt;/code&gt; header sent by the client via the incoming request. &lt;/p&gt;

&lt;p&gt;We can use the location we get from the &lt;code&gt;ParseTimezoneFromString&lt;/code&gt; function to convert or shift the time we get from the server to the user's local time. We can do this using the &lt;code&gt;In&lt;/code&gt; function which is also included in the time package which we can see in the following code snippet:&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="nx"&gt;nowInWIT&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nowInUTC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;In&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;witLocation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;nowInWITA&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nowInUTC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;In&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;witaLocation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;nowInWIB&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nowInUTC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;In&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wibLocation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we run it, we will get the time that corresponds to the timezone location that we defined.&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%2F5hj0uau3rtv595ibtvol.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%2F5hj0uau3rtv595ibtvol.png" alt="Image description" width="373" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing and Validation
&lt;/h3&gt;

&lt;p&gt;The final point is no less important, namely testing and validation. When the development process often causes developers to make unexpected mistakes, testing and validation are always important.&lt;/p&gt;

&lt;p&gt;In the discussion of point 2 above, the &lt;code&gt;ParseTimezoneFromString&lt;/code&gt; function has been important in handling our time zones. Repeated testing and validation are important to make our applications get results that meet our expectations.&lt;/p&gt;

&lt;p&gt;For testing, it is recommended to use unit tests, where testing will be carried out on the smallest unit with several scenarios that can be added. The more scenarios there are, the less likely it is to handle these time differences.&lt;/p&gt;

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

&lt;p&gt;Handling time zones can indeed be tricky for backend developers. However, it's important to remember that every challenging task we overcome contributes to our growth and skill improvement. Properly managing time zones is not just a technical necessity, it ensures accuracy in scheduling and provides a smooth experience for our application users across different regions.&lt;/p&gt;

&lt;p&gt;The points shared in this article about storing times in UTC, converting to user local times, and implementing robust conversion functions are starting points in tackling this complex issue. However, I acknowledge that there may be shortcomings or areas for improvement in the approaches discussed. This is why additional input and suggestions from the developer community are invaluable.&lt;/p&gt;

&lt;p&gt;I sincerely hope that the insights and code examples provided in this article will be helpful to you in the future when you encounter time zone-related challenges in your projects. Remember, the goal is to create applications that work seamlessly for users, regardless of their geographical location.&lt;/p&gt;

&lt;p&gt;Let's continue this discussion in the comments section below. I'd love to hear about your experiences with handling time zones, any challenges you've faced, or alternative approaches you've found effective. Your insights could be extremely valuable to me and other readers facing similar issues.&lt;/p&gt;

&lt;p&gt;Thank you for reading, and I hope this article proves useful in your development journey. Let's keep learning and improving together! 👋&lt;/p&gt;

&lt;h1&gt;
  
  
  Reading References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Time_zone" rel="noopener noreferrer"&gt;Time zone
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.timeanddate.com/time/time-zones.html" rel="noopener noreferrer"&gt;What Is a Time Zone?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/synchronize-your-software-with-international-customers/" rel="noopener noreferrer"&gt;How to Handle Timezones and Synchronize Your Software with International Customers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/jesusantguerrero/dealing-with-timezones-in-web-development-2dgg"&gt;Dealing with timezones in web development&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://clouddevs.com/go/dates-and-times/" rel="noopener noreferrer"&gt;Working with Dates and Times in Go: Handling Timezones and Formatting&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>backend</category>
      <category>programming</category>
      <category>time</category>
    </item>
    <item>
      <title>Flutter Scrolling Techniques: Using GlobalKey and Scrollable.ensureVisible() for Precise Navigation</title>
      <dc:creator>Irfan Adisukma</dc:creator>
      <pubDate>Fri, 27 Sep 2024 09:27:02 +0000</pubDate>
      <link>https://dev.to/tentanganak/flutter-scrolling-techniques-using-globalkey-and-scrollableensurevisible-for-precise-navigation-59pf</link>
      <guid>https://dev.to/tentanganak/flutter-scrolling-techniques-using-globalkey-and-scrollableensurevisible-for-precise-navigation-59pf</guid>
      <description>&lt;p&gt;&lt;a href="https://media.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%2Fj3581ev2nsshkgqaeh5o.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fj3581ev2nsshkgqaeh5o.gif" alt="https://dribbble.com/shots/4697421-Scroll-Scroll"&gt;&lt;/a&gt;&lt;br&gt;
In Flutter development, creating smooth and intuitive user experiences often involves guiding users to specific parts of the interface. One powerful technique to achieve this is programmatically scrolling to a particular widget. Whether it’s navigating to a section in a long form, focusing on a specific item in a list, or highlighting a new message in a chat, the ability to scroll to a specific widget enhances the overall usability and interactivity of an app.&lt;/p&gt;

&lt;p&gt;Flutter provides several tools, such as &lt;strong&gt;GlobalKey&lt;/strong&gt;, and &lt;strong&gt;Scrollable.ensureVisible()&lt;/strong&gt;, that allow developers to precisely control scrolling behavior. By leveraging these tools, developers can ensure that important content is brought into view, reduce the need for excessive manual scrolling, and create more seamless navigation experiences. This not only helps in improving user engagement but also makes the application more accessible and efficient, especially for apps with complex layouts or dynamic content.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore how to effectively scroll to a specific widget in Flutter using these techniques, ensuring that your app's navigation is as smooth and user-friendly as possible.&lt;/p&gt;
&lt;h2&gt;
  
  
  Understanding the Components
&lt;/h2&gt;

&lt;p&gt;When building a Flutter app, having control over how users navigate through content is crucial for creating a smooth and engaging experience. To achieve precise scrolling behavior, three key components can be used: GlobalKey, and Scrollable.ensureVisible(). Let's dive deeper into each of these components and understand their roles.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GlobalKey&lt;/strong&gt;: In Flutter, GlobalKey is a type of key that is used to uniquely identify a widget within the entire widget tree. It enables developers to access the widget's context, state, and position, which is essential when you need to perform actions such as scrolling to a particular widget or manipulating its state. By assigning a GlobalKey to a widget, you can easily reference it later in your code to trigger actions like scrolling, focusing, or even retrieving information about its dimensions and position. And it's compatible with all Flutter versions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scrollable.ensureVisible()&lt;/strong&gt;: The Scrollable.ensureVisible() method is a utility function provided by Flutter that ensures a given widget is visible within its scrollable ancestor. When called, it automatically calculates the distance and direction to scroll in order to bring the target widget into view. This is particularly useful for creating smooth and automated scrolling effects, such as jumping to a specific section of a form, highlighting a newly added item in a list, or scrolling to a widget based on user actions (e.g., clicking a button). By combining Scrollable.ensureVisible() with GlobalKey, developers can programmatically control the visibility of widgets, enhancing navigation and user experience. This feature available and supported from Flutter 1.5.4 onwards. So make sure you are using latest version.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By understanding these two components— GlobalKey, and Scrollable.ensureVisible()—you can effectively implement advanced scrolling behaviors in your Flutter app, ensuring that users can easily navigate and interact with content in a seamless and intuitive way.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating the UI
&lt;/h2&gt;

&lt;p&gt;To demonstrate, let's create a simple UI containing a list of items.&lt;/p&gt;

&lt;p&gt;Step-by-Step Example&lt;br&gt;
Here is a basic example of setting up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ListView.builder(
 shrinkWrap: true,
 itemCount: 50,
 physics: const NeverScrollableScrollPhysics(),
 itemBuilder: (context, index) {
   return ListTile(title: Text("Item $index"));
 }
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's add GlobalKey to identify widgets&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final GlobalKey _scrollKey = GlobalKey();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assign this key to the widget within your ListView:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ListTile(
  key: _scrollKey,
  title: Text('Scroll to Me!'),
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the code should be like this with additional handling to override generated list item with the GlobalKey:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ListView.builder(
 shrinkWrap: true,
 itemCount: 50,
 physics: const NeverScrollableScrollPhysics(),
 itemBuilder: (context, index) {
   if (index == 25) {
     return ListTile(
      key: _scrollKey,
      title: Text("Scroll to Me!")
     );
   }
   return ListTile(title: Text("Item $index"));
 }
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's add ScrollC&lt;/p&gt;

&lt;p&gt;Let's add one final touch by adding Button to trigger the scroll using &lt;strong&gt;Scrollable.ensureVisible()&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void _scrollToTarget() {
  // Ensure the widget is built
  WidgetsBinding.instance.addPostFrameCallback((_) {
    final context = _scrollKey.currentContext;
    if (context != null) {
      Scrollable.ensureVisible(
        context,
        duration: const Duration(seconds: 1), 
        curve: Curves.easeInOut);
      }
   });
 }

ListView(
 children: [
  ElevatedButton(
    onPressed: () async {
      _scrollToTarget();
    },
    child: const Text('Scroll to Widget'),
  ),
  ListView.builder(
    shrinkWrap: true,
    itemCount: 50,
    physics: const NeverScrollableScrollPhysics(),
    itemBuilder: (context, index) {
      if (index == 25) {
       return ListTile(
        key: _scrollKey,
        title: Text("Scroll to Me!")
       );
      }
      return ListTile(title: Text("Item $index"));
     }
   )
  ],
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the output!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fp13197b8saqjahfsxgco.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fp13197b8saqjahfsxgco.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How Scrollable.ensureVisible works?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Scrollable.ensureVisible() method takes in the BuildContext of a widget and scrolls the nearest scrollable parent to make that widget fully visible. &lt;/p&gt;

&lt;p&gt;When Scrollable.ensureVisible() is called, Flutter calculates the position of the widget represented by the context in its scrollable ancestor.&lt;br&gt;
If the widget is already fully visible, no scrolling occurs. If not, the method scrolls the closest scrollable widget (like CustomScrollView, ListView, etc.) to bring the target widget into view.&lt;br&gt;
The scrolling animation takes place over the specified duration and follows the provided curve, resulting in a smooth scroll to the target widget.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F0dbrl94yl9l4ki9ys8vz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F0dbrl94yl9l4ki9ys8vz.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is real example of how we implement this technique on Tentang Anak App, we have a feature section that must be highlighted and we help user to find this section by tapping the button, and it will automatically scroll to the specific section.&lt;/p&gt;




&lt;h2&gt;
  
  
  Additional Tips
&lt;/h2&gt;

&lt;p&gt;When implementing scrolling to a specific widget in Flutter using  GlobalKey, and Scrollable.ensureVisible(), it's essential to consider performance and handle potential edge cases to ensure a smooth and responsive user experience. Here are some additional tips to help you optimize your implementation:&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance Considerations
&lt;/h3&gt;

&lt;p&gt;When working with large lists or complex scrollable content, performance optimization is crucial. Here are some strategies to enhance scrolling and rendering performance:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Avoid Unnecessary Rebuilds: Ensure that widgets within your ListView do not rebuild unnecessarily. Use const constructors where possible, and consider using state management solutions like Provider or Riverpod to manage the state outside of the widget tree, avoiding frequent rebuilds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Virtualization with ListView.builder and GridView.builder: If your use case involves scrolling a long list of items (e.g., 100+ items), consider using ListView.builder or GridView.builder instead of SliverList to optimize memory usage. These builders only render visible items and reuse widgets that move out of the viewport.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Throttle or Debounce User Actions: If you allow users to trigger scrolling actions frequently (e.g., tapping buttons to scroll to different items), consider throttling or debouncing these actions to prevent excessive animations and rendering.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use the automaticKeepAlive property: For complex widgets that need to maintain their state while scrolling, consider using AutomaticKeepAlive widgets to manage their lifecycles better without unnecessarily keeping off-screen widgets alive.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Handling Edge Cases
&lt;/h3&gt;

&lt;p&gt;Proper handling of edge cases ensures that your scroll functionality works reliably in all scenarios:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ensure Widget Exists in the Viewport: Before calling Scrollable.ensureVisible(), ensure that the target widget is part of the scrollable content. If the widget is dynamically added or removed (e.g., in response to user actions), you need to verify that it is indeed within the scrollable ancestor when the method is called. Failing to do so can result in exceptions or unexpected behavior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handle Already Visible Widgets: If the widget is already fully visible in the viewport, Scrollable.ensureVisible() won’t trigger any scrolling. Make sure to handle such cases gracefully to avoid redundant animations or confusing the user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handle Partially Visible Widgets: Consider scenarios where the widget is only partially visible (e.g., cut off at the top or bottom of the viewport). Scrollable.ensureVisible() will scroll to bring it fully into view, but you might want to adjust the duration or curve for smoother transitions, especially if only a small amount of scrolling is needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check for Nested Scroll Views: If you have nested scroll views, calling Scrollable.ensureVisible() may not work as expected if the target widget is inside a nested scroll view. Ensure that the method is called on the correct scrollable parent and that the widget’s context is properly obtained from the right GlobalKey.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manage Focus and Accessibility: After scrolling to a widget, you may want to give it focus (e.g., for an input field) or announce it to assistive technologies. Use FocusScope.of(context).requestFocus() or Semantics to enhance accessibility and provide visual feedback.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consider Scroll Offset Adjustments: Sometimes, you may want to scroll a bit past the widget or stop before it reaches the top or bottom of the viewport to provide some padding or context. You can use alignment or calculate offsets manually to achieve more precise positioning.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By considering these performance tips and handling edge cases, you can implement scrolling to specific widgets in a way that is both efficient and robust, ensuring a seamless and intuitive experience for your Flutter app users. This approach not only improves usability but also contributes to a polished, professional app that handles a variety of user interactions gracefully.&lt;/p&gt;




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

&lt;p&gt;Scrolling to a specific widget in Flutter can significantly enhance the user experience by ensuring that important content is always visible and easily accessible. &lt;/p&gt;

&lt;p&gt;In summary, using GlobalKey, and Scrollable.ensureVisible() together provides a powerful toolkit for creating responsive and user-friendly scrolling experiences in Flutter apps. This approach not only guides users through different sections of an app smoothly but also enhances the overall usability and accessibility, leading to a more polished and professional application.&lt;/p&gt;

&lt;p&gt;See the full code&lt;br&gt;
&lt;a href="https://github.com/irfanadisukma/auto-scroll-widget" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>flutterwidget</category>
    </item>
  </channel>
</rss>
