<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Laëtitia Christelle Ouelle</title>
    <description>The latest articles on Forem by Laëtitia Christelle Ouelle (@ouelle).</description>
    <link>https://forem.com/ouelle</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1135005%2F50474680-1031-4186-814c-bd0746e19cdf.jpeg</url>
      <title>Forem: Laëtitia Christelle Ouelle</title>
      <link>https://forem.com/ouelle</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ouelle"/>
    <language>en</language>
    <item>
      <title>Content Delivery Networks (CDNs)</title>
      <dc:creator>Laëtitia Christelle Ouelle</dc:creator>
      <pubDate>Wed, 20 Sep 2023 13:43:03 +0000</pubDate>
      <link>https://forem.com/ouelle/content-delivery-networks-cdns-23cc</link>
      <guid>https://forem.com/ouelle/content-delivery-networks-cdns-23cc</guid>
      <description>&lt;p&gt;Hello folk! Today we’re going to talk about CDN witch is a part of our global topic “Web Api Performance” and i hope that you guys are ready!&lt;/p&gt;

&lt;p&gt;Let’s go 🚀 …&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UYj48VsA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shu41p41nw0e7ick0a5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UYj48VsA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shu41p41nw0e7ick0a5p.png" alt="CDN" width="799" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a CND ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In web API performance, a CDN stands for “Content Delivery Network.” A CDN is a network of distributed servers strategically placed in multiple data centers around the world.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What is it used for ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The primary purpose of a CDN is to deliver web content, including APIs, to users more efficiently by reducing latency and improving availability and scalability. CDN caches contents next to the final users so that it can send resources quickly to them.&lt;/p&gt;

&lt;p&gt;Resources like&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Static Content&lt;/em&gt;: HTML pages, Javascript files, css styles, images, videos.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dynamic Content&lt;/em&gt;: While CDNs are primarily known for caching static content, some CDNs offer features for caching dynamic content as well. This includes dynamically generated web pages, API responses, and database-driven content.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Software Updates&lt;/em&gt;: CDNs are used to distribute software updates and patches. Companies often use CDNs to deliver software updates to their users, ensuring faster and more reliable downloads.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Streaming Media&lt;/em&gt;: Many CDNs support the delivery of streaming media content, such as video and audio streams. Content can be distributed globally to reduce latency for viewers.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Large Files&lt;/em&gt;: CDNs are also useful for distributing large files, such as software installation files, documents, and datasets. They can efficiently handle the transfer of large files to users, again reducing the load on your origin server.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;CDNs vs Web Hosting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes when defining CDNs, they can be confused with web hosting. So we added this section to explain the difference and make it clear to you.&lt;/p&gt;

&lt;p&gt;Web hosting is primarily used to store and serve website files, databases, and web applications from a centralized server, while CDN is to enhance the delivery speed, availability, and scalability of web content.&lt;/p&gt;

&lt;p&gt;When it’s about content delivery, DNs distribute cached content globally, making use of edge servers to serve content from locations closer to end-users, while Web hosting serves content from a central server, which may not be optimized for global content delivery. Without a CDN, users farther from the hosting server may experience slower load times.&lt;/p&gt;

&lt;p&gt;Finally a website can use a Content Delivery Network (CDN) to improve its performance, reliability, and content delivery. By using a CDN, a website can provide a better user experience by reducing latency, improving load times, and enhancing content delivery to users around the world.&lt;/p&gt;

&lt;p&gt;But CDNs are independent services that work in conjunction with websites, but they don’t require a specific website to function.&lt;/p&gt;




&lt;p&gt;*&lt;em&gt;How do they work ?&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Different CDNs use different process and technologies for driving user requests to the closest POPs..&lt;/p&gt;

&lt;p&gt;— Let’s take a break! &lt;strong&gt;What is a PoP&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;PoP stands for &lt;strong&gt;P&lt;/strong&gt;oint of &lt;strong&gt;P&lt;/strong&gt;resence and is one of the multiple servers deployed by a CDN at multiple locations all over the world.&lt;/p&gt;

&lt;p&gt;Now we continue with the explanation of how a CDN works 👇🏾&lt;/p&gt;

&lt;p&gt;There is a lot of technologies that CDNs use but two common technologies are : &lt;strong&gt;DNS-Based Routing&lt;/strong&gt; and &lt;strong&gt;AnyCast&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DNS-Based Routing&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;In DNS-Based Routing, each Point of Presence (PoP) has it’s own IP address so when the user request for a specific content to a CDN, this one (The CDN) returns the IP address of the PoP closest to the user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AnyCast&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Things go differently with the anycast process, because in this case all PoPs have the same IP address and when a user request arrives on the anycast network, the network redirects the request to the nearest PoP to the requester .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Using a Content Delivery Network (CDN) offers several key advantages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Improved Performance&lt;/em&gt;&lt;/strong&gt;: CDNs reduce latency by caching and delivering content from edge servers geographically closer to users, resulting in faster load times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Scalability&lt;/em&gt;&lt;/strong&gt;: CDNs efficiently handle traffic spikes, ensuring your website or application remains responsive even during high-demand periods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Global Reach&lt;/em&gt;&lt;/strong&gt;: CDNs have a worldwide presence, making your content accessible and fast for users across the globe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Caching&lt;/em&gt;&lt;/strong&gt;: They cache static and dynamic content, reducing the load on your origin server and minimizing server costs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Security&lt;/em&gt;&lt;/strong&gt;: CDNs often provide security features like DDoS protection and web application firewalls, enhancing your website’s protection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Cost Efficiency&lt;/em&gt;&lt;/strong&gt;: CDNs can lower bandwidth and server costs while improving performance and reliability.&lt;/p&gt;

&lt;p&gt;In conclusion, CDNs enhance content delivery, performance and scalability for websites and applications, ensuring a faster, more reliable, and cost-effective user experience.&lt;/p&gt;

&lt;p&gt;Follow me there :&lt;/p&gt;

&lt;p&gt;linkedin.com/in/laetitia-christelle-ouelle-89373121b/&lt;/p&gt;

&lt;p&gt;twitter.com/OuelleLaetitia&lt;/p&gt;

&lt;p&gt;dev.to/ouelle&lt;/p&gt;

&lt;p&gt;Happy coding ! 😏&lt;/p&gt;

</description>
      <category>cdn</category>
      <category>api</category>
      <category>systemdesign</category>
      <category>network</category>
    </item>
    <item>
      <title>Caching Strategies</title>
      <dc:creator>Laëtitia Christelle Ouelle</dc:creator>
      <pubDate>Wed, 30 Aug 2023 14:49:04 +0000</pubDate>
      <link>https://forem.com/ouelle/caching-strategies-56eb</link>
      <guid>https://forem.com/ouelle/caching-strategies-56eb</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xhVWXaw2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/90uenez0u5m1d5zq44ju.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xhVWXaw2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/90uenez0u5m1d5zq44ju.png" alt="Caching Strategie" width="606" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Caching strategies are essential techniques employed to enhance the performance and responsiveness of web applications by mitigating the need for recurrently fetching identical data or resources. Two prevalent caching approaches encompass &lt;strong&gt;client-side caching&lt;/strong&gt; and &lt;strong&gt;server-side caching&lt;/strong&gt;:&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Client-Side Caching&lt;/strong&gt;: Client-side caching entails preserving responses or assets on the user’s device, typically within the web browser’s cache. This facilitates subsequent requests for the same resources to be instantly served from the cache, mitigating the necessity for renewed retrieval from the server. Here’s a deeper dive into client-side caching:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTP Cache-Control&lt;/strong&gt;: Client-side caching is governed by HTTP headers like Cache-Control and Expires, which specify the duration of resource caching and the criteria for considering it fresh.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Decreased Latency: Cached resources load expeditiously as they are fetched locally.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lightened Server Load: Caching alleviates the server by curtailing requests for identical resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhanced User Experience: Speedier load times contribute to a smoother user experience.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Instances of Client-Side Caching&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Browser Cache: Web browsers automatically cache resources like images, stylesheets, and scripts, and caching behavior can be regulated using HTTP headers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service Workers: Progressive web apps (PWAs) leverage service workers to cache assets and provide offline capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Server-Side Caching&lt;/strong&gt;: Server-side caching involves the retention of often-requested data or entire responses on the server or an intermediary server (e.g., a proxy or CDN). This approach curtails the time and resources necessary for generating responses, substantially enhancing application performance. Here’s an exploration of server-side caching:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caching Mechanisms&lt;/strong&gt;: Various mechanisms are employed for server-side caching, including in-memory caching, distributed caching, reverse proxy caching, and content delivery networks (CDNs).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cache Invalidation&lt;/strong&gt;: To ensure the continued accuracy of cached data, strategies for cache invalidation are imperative. Data should be refreshed or invalidated when it becomes outdated or when alterations occur in the source data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expedited Response Times&lt;/strong&gt;: Cached responses are dispensed swiftly, diminishing user wait times for data to load.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lighter Server Burden&lt;/strong&gt;: Caching reduces the application server’s load by curtailing the necessity to regenerate identical responses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability&lt;/strong&gt;: Caching facilitates the more efficient scalability of applications by disseminating the load across cached responses.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Instances of Server-Side Caching&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;In-Memory Caches&lt;/strong&gt;: Tools such as Redis and Memcached are commonly employed to cache frequently accessed data in memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reverse Proxy Caches&lt;/strong&gt;: Servers like Nginx and Varnish can be configured as reverse proxies with integrated caching capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Content Delivery Networks (CDNs)&lt;/strong&gt;: CDNs cache static assets, such as images and scripts, across numerous global locations for accelerated delivery to end-users.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Caching represents a potent strategy for optimizing web applications and APIs, curbing latency, and heightening overall performance. Nonetheless, effective cache management is requisite to ensure that cached data remains current and precise, balancing the interplay between performance enhancement and data accuracy.&lt;/p&gt;

&lt;p&gt;Follow me there :&lt;/p&gt;

&lt;p&gt;linkedin.com/in/laetitia-christelle-ouelle-89373121b/&lt;/p&gt;

&lt;p&gt;twitter.com/OuelleLaetitia&lt;/p&gt;

&lt;p&gt;dev.to/ouelle&lt;/p&gt;

&lt;p&gt;Happy coding ! 😏&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Server-Side Performance:</title>
      <dc:creator>Laëtitia Christelle Ouelle</dc:creator>
      <pubDate>Sat, 26 Aug 2023 12:21:48 +0000</pubDate>
      <link>https://forem.com/ouelle/3-server-side-performance-k9k</link>
      <guid>https://forem.com/ouelle/3-server-side-performance-k9k</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zOPk8waW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x6kqtis5621sefxcz8hx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zOPk8waW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x6kqtis5621sefxcz8hx.png" alt="server-side performance" width="600" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We mainly discuss about some kind of “good practices” to build a reliable, scalable and performant API. But this may prove to be insufficient when it comes to APIS that have intensives tasks.&lt;/p&gt;

&lt;p&gt;It does not mean that applying methods i gave in the previous series of articles around “Web API performance” are now out to date because they might be insufficient. But it’s also a good thing to combine and apply methods based on what your API needs to perform.&lt;/p&gt;

&lt;p&gt;So we’re going to talk about server-side performance.&lt;/p&gt;

&lt;p&gt;Server-side performance refers to the efficiency and responsiveness of a server in processing requests and delivering responses in a web application or service. It is a critical aspect of web development, as a well-optimized server can significantly impact the overall user experience.&lt;/p&gt;

&lt;p&gt;I thought it best to articulate the Server-side performance topic around 3 concepts that I find important: &lt;em&gt;Load Balancing, Scaling and Concurrency &amp;amp; Threading&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Load Balancing&lt;/strong&gt; : &lt;em&gt;This concept may be new to you, but it is substantial.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bBJVy8xP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/44vf2swt6zrm0jky86md.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bBJVy8xP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/44vf2swt6zrm0jky86md.png" alt="Load Balancing" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;— Definition:&lt;/p&gt;

&lt;p&gt;Load balancing is a networking technique or process used to distribute incoming network traffic or computing workload across multiple servers, resources, or devices.&lt;/p&gt;

&lt;p&gt;The primary purpose of load balancing is to ensure that no single resource becomes overwhelmed with traffic or workload, thereby optimizing the performance, reliability, and availability of a network or application.&lt;/p&gt;

&lt;p&gt;In order to prevent the server or an instance from being overloaded with requests, load balancers distribute incoming requests so that each of them is correctly executed in time.&lt;/p&gt;

&lt;p&gt;Here’s how it works: A load balancer performs its role based on a selected load balancing algorithm. This algorithm defines how our requests will be sent through our servers or instances.&lt;/p&gt;

&lt;p&gt;There are various load balancing algorithms, each with its own characteristics and use cases. Here are some common load balancing algorithms:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Round Robin&lt;/strong&gt;: This is one of the simplest load balancing algorithms. It distributes traffic evenly to each server in a circular manner. Each incoming request is routed to the next server in the list. Round robin is easy to implement but may not take server load into account, potentially sending traffic to an overloaded server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yYwHLNyE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eq0ok80lp31o1ry9xfk4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yYwHLNyE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eq0ok80lp31o1ry9xfk4.png" alt="Round-Robin" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;— Pros:&lt;/p&gt;

&lt;p&gt;If all the available servers have the same capacity then :&lt;/p&gt;

&lt;p&gt;Each server has exactly the same requests workload&lt;br&gt;
Routed requests are approximately executed in the same time&lt;br&gt;
The response speed is boosted&lt;br&gt;
Clients receive their responses in time and we have a good user-friendly apps&lt;/p&gt;

&lt;p&gt;— Cons:&lt;/p&gt;

&lt;p&gt;Distributing request in the round robin fashion may cause server overload because let’s suppose that our “Server 1” is 5 times less powerful that our “server 2”, the “server 1” due to his low capacity will not have enough time to complete the first request in time but will receive new requests witch will be queued. The result will be either a long response time or a down server.&lt;/p&gt;

&lt;p&gt;So here we need a Round Robin Algorithm that take into account the capacities of each server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weighted Round Robin&lt;/strong&gt;: Weighted round robin assigns each server a weight, indicating its capacity or performance. Servers with higher weights receive more traffic than those with lower weights. This allows for proportional distribution of traffic based on server capabilities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9qC4HGaa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6prmi6gaqll4c1ngyz42.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9qC4HGaa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6prmi6gaqll4c1ngyz42.png" alt="Weighted Round Robin" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;— Pros&lt;/p&gt;

&lt;p&gt;Same advantages as Round Robin&lt;br&gt;
So basically it’s a Round Robin that takes server capabilities into account.&lt;/p&gt;

&lt;p&gt;— Cons&lt;/p&gt;

&lt;p&gt;Both Round Robin algorithm don’t take in to account the number of connections that servers must maintain for a certain period when the load balancer distributes requests.&lt;/p&gt;

&lt;p&gt;This means that multiple connections can accumulate on a server in the cluster. This causes a server overload, even if it has fewer connections than the others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Least Connections&lt;/strong&gt;: This algorithm directs traffic to the server with the fewest active connections or sessions. It is effective at distributing traffic based on server load, ensuring that connections are evenly spread across the servers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yOrhHxic--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/in2b11itznpyij6sba28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yOrhHxic--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/in2b11itznpyij6sba28.png" alt="Least Connections" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above shows that “server 1" has 3 actives connections, “server 3” has 4. So the algorithm send the “Request a” to the “server 3” with has 0 active connection, and here we go again, the operation restarts. So now “server 1” has 3 actives connections, “server 2" has 4 and “server 3” has 1, so the “Request b” goes to the “server 3". The same operation restarts and send the “Request c” to the server 3.&lt;/p&gt;

&lt;p&gt;— Pros :&lt;/p&gt;

&lt;p&gt;One of the primary advantages of the “Least Connections” algorithm is that it distributes incoming traffic to servers with the fewest active connections. This ensures a relatively even distribution of traffic, preventing any single server from becoming overloaded while others remain underutilized.&lt;/p&gt;

&lt;p&gt;— Cons:&lt;/p&gt;

&lt;p&gt;The “Least Connections” algorithm is typically stateless. It does not consider server load based on factors like CPU usage, memory usage, or application-specific metrics. It only looks at the number of active connections, which might not be a comprehensive measure of server load in all scenarios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weighted Least Connections&lt;/strong&gt;: Similar to weighted round robin, this algorithm considers server weights but also takes into account the number of active connections. Servers with both lower weights and fewer connections receive priority.&lt;/p&gt;

&lt;p&gt;Other Algorithm:&lt;/p&gt;

&lt;p&gt;IP Hash&lt;br&gt;
Least Response Time&lt;br&gt;
Random&lt;br&gt;
Least BandwidthChained Failover&lt;br&gt;
Dynamic Algorithms:_&lt;br&gt;
(A part 2 will be entirely dedicated to them)&lt;/p&gt;

&lt;p&gt;The selection of an appropriate load balancing algorithm is contingent upon the precise demands and intricacies inherent in the application at hand, as well as the existing infrastructure’s configuration.&lt;/p&gt;

&lt;p&gt;Within this context, it becomes evident that certain applications derive notable advantages from employing a straightforward round-robin methodology, which systematically distributes incoming traffic to designated servers in a sequential manner.&lt;/p&gt;

&lt;p&gt;However, in contrast, there exist scenarios where the requisites of the application dictate the utilization of more advanced and refined load balancing algorithms, ones that exhibit the capacity to meticulously assess and account for the health and performance metrics of individual servers.&lt;/p&gt;

&lt;p&gt;It is imperative to recognize that the world of load balancing is not confined to predetermined algorithms, as some load balancers extend the flexibility of tailoring custom algorithms or intricate configurations, thereby affording the capacity to address idiosyncratic and distinct operational needs with precision and efficacy.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Scaling&lt;/strong&gt; : _Be prepared to scale your server resources both vertically and horizontally as traffic and demand increase.&lt;br&gt;
_&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wV06XTk3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nefm6v5hr8bsxd0m8nx5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wV06XTk3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nefm6v5hr8bsxd0m8nx5.png" alt="Scaling" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is scaling ?&lt;/p&gt;

&lt;p&gt;Scaling in computing and technology involves adjusting system capacity and capabilities to accommodate evolving workloads, playing a pivotal role in developing and maintaining applications, networks, and infrastructure to satisfy user and data requirements.&lt;/p&gt;

&lt;p&gt;There are two primary types of scaling: vertical &amp;amp; horizontal scaling&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Vertical Scaling *&lt;/em&gt; (&lt;em&gt;Scaling Up&lt;/em&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Vertical scaling involves increasing the resources of a single server or node to handle a higher workload.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This typically means upgrading the server’s CPU, memory (RAM), storage, or other hardware components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vertical scaling can be limited by the maximum capacity of a single server and can be costlier as more powerful hardware is often more expensive.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Horizontal Scaling&lt;/strong&gt; (&lt;em&gt;Scaling Out&lt;/em&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Horizontal scaling involves adding more servers or nodes to a system to distribute the workload.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each new server is identical to the existing ones and shares the processing load.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizontal scaling is more scalable and cost-effective for handling high traffic loads because it can be easily expanded as needed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are some common examples of scaling in various technology contexts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Web Servers: Adding more web servers to distribute incoming web requests across multiple machines to handle increased user traffic. This is horizontal scaling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database Scaling: In database systems, scaling can involve adding more database servers or optimizing queries and indexes to handle larger data sets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Application Scaling: Scaling out application servers to accommodate more concurrent users or application instances to process more tasks simultaneously.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Load Balancing: Distributing incoming network traffic across multiple servers to ensure that no single server is overwhelmed. This can be done using load balancers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cloud Computing: Cloud services like AWS, Azure, and Google Cloud offer scalable resources on-demand, allowing you to scale your applications up or down as needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Microservices: Breaking down monolithic applications into smaller, independent microservices that can be individually scaled based on demand.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Scalability represents a critical cornerstone in the realm of technology and systems engineering, primarily focused on the assurance that a system possesses the capability to effectively embrace growth, uphold consistent performance levels, and swiftly respond to dynamic shifts in demand.&lt;/p&gt;

&lt;p&gt;The essence of scalability lies in its capacity to furnish systems with the agility required to seamlessly adapt to evolving workloads and user requirements. In doing so, it not only assures the preservation of a responsive and reliable user experience but also delivers on the promise of cost-efficiency by optimizing resource utilization and mitigating infrastructure expenses.&lt;/p&gt;

&lt;p&gt;Consequently, the concept of scalability stands as a fundamental and indispensable component of modern technological landscapes, underpinning the foundation of robust and adaptive systems.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Multi-Threading&lt;/strong&gt; : Efficiently handling multiple requests simultaneously.&lt;/p&gt;

&lt;p&gt;A thread is similar to a process because it represents the execution of a set of machine language instructions from a processor.&lt;/p&gt;

&lt;p&gt;Multithreading in the context of a web API refers to the ability of the web server to handle multiple incoming HTTP requests concurrently by using multiple threads. This is important for improving the scalability and responsiveness of web applications, as it allows the server to efficiently utilize the available hardware resources and handle a large number of client requests simultaneously.&lt;/p&gt;

&lt;p&gt;It helps improve the scalability of a web API. As the number of incoming requests increases, the server can create additional threads to handle the load, up to a certain limit, without significant degradation in performance.&lt;/p&gt;

&lt;p&gt;When designing a multithreaded web API, it’s essential to consider both blocking and non-blocking operations. Blocking operations, such as I/O operations, can cause a thread to wait, potentially reducing the server’s overall throughput. Non-blocking operations, like asynchronous programming, can help mitigate this issue by allowing threads to work on other tasks while waiting for I/O to complete.&lt;/p&gt;

&lt;p&gt;Overall, multithreading is a fundamental concept in the development of high-performance web APIs. It allows web servers to efficiently handle a large number of concurrent client requests, ensuring responsiveness and scalability. However, it also introduces complexity and potential pitfalls that developers need to be aware of and address in their designs and implementations.&lt;/p&gt;




&lt;p&gt;Server-side performance is a critical aspect of web and application development focused on optimizing the efficiency and speed of operations that occur on the server. It encompasses various strategies and techniques, including code optimization, database tuning, caching, load balancing, and scalability measures, all aimed at ensuring that server resources are used effectively and that applications can handle increasing user loads while maintaining responsiveness. High server-side performance is crucial for delivering a smooth and responsive user experience, particularly in web and mobile applications.&lt;/p&gt;

&lt;p&gt;Follow me there :&lt;/p&gt;

&lt;p&gt;linkedin.com/in/laetitia-christelle-ouelle-89373121b/&lt;/p&gt;

&lt;p&gt;twitter.com/OuelleLaetitia&lt;/p&gt;

&lt;p&gt;dev.to/ouelle&lt;/p&gt;

&lt;p&gt;Happy coding ! 😏&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>performance</category>
      <category>load</category>
    </item>
    <item>
      <title>APIs Response Time Optimization</title>
      <dc:creator>Laëtitia Christelle Ouelle</dc:creator>
      <pubDate>Mon, 21 Aug 2023 01:07:48 +0000</pubDate>
      <link>https://forem.com/ouelle/web-api-performance-5fp3</link>
      <guid>https://forem.com/ouelle/web-api-performance-5fp3</guid>
      <description>&lt;p&gt;Previously we talked about Restful Design, what it is and the importance for our API to follow its standards and conventions to create a fast, reliable and scalable RESTFUL API.&lt;/p&gt;

&lt;p&gt;Now let’s dive into the second step of optimizing web API performance: Response Time Optimization.&lt;/p&gt;

&lt;p&gt;Response time is a critical factor in delivering a responsive and efficient API experience to users. Here’s how you can optimize the response time of your API:&lt;/p&gt;

&lt;p&gt;Minimize Network Latency:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;a- ) Choose data centers or hosting locations that are geographically close to your target audience.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The logics of the real world rules are exactly the same in the logic of the programming world, because going to your kitchen to get a new bottle of coca cola will take less time than picking up that bottle from a supermarket.&lt;/p&gt;

&lt;p&gt;Here both supermarket and kitchen represent your data hosting location.&lt;/p&gt;

&lt;p&gt;It means that an app that will be only use in Ivory Coast with its hosting location in china will not have the same response speed as if its server(s) was in the same country.&lt;/p&gt;

&lt;p&gt;Use case with the image bellow as illustration&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S30yHIgn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7q4ahtvlo4z1cxedk97c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S30yHIgn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7q4ahtvlo4z1cxedk97c.png" alt="illustration" width="700" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here the bubbles with centered letters represent the servers (hosting location) and the square represents the application. Regardless of the quality and performance of the servers, you should choose the closest server possible.&lt;/p&gt;

&lt;p&gt;so servers (E, G, F, H ) are a better choice.&lt;/p&gt;

&lt;p&gt;I mentioned server performance and quality because distance is not the only parameter to consider. Choosing a bad server just because it’s the closest is not a good thing to do when you want your API to work properly.&lt;/p&gt;

&lt;p&gt;What you need to consider is the geographical distance and the server capacity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimize Database Queries:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;a- ) Use efficient database queries by selecting only the necessary columns and rows of data.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Selecting more fields than necessary will increase the response time and the volume of your response&lt;/p&gt;

&lt;p&gt;for example, an array of one thousand items 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;const itemArray :{username:string, email:string, pwd: string}=[
  {
    username:"John doe",
    email:"doe@mailio.az", 
    pwd: "skjdubss"
  },
  ....99 other items
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;will have a lower volume and response time than a query that needs to send a response 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;const itemArray :{
  username:string,
  email:string,
  pwd: string,
  avatar_url:string,
  posts: Post[],
  documents: Documents[]
}=[
  {
    username:"John doe",
    email:"doe@mailio.az", 
    pwd: "skjdubss",
    avatar_url:string,
    posts: [{...postsList}],
    documents: [{...documentList}]
  },
  ....99 other items
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So make sure you really need all the items you are asking your database to send via your queries.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;b- ) Avoid N+1 query problems by utilizing eager loading or database joins&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;N+1 query means querying your database more than once to get the final answer you need.&lt;/p&gt;

&lt;p&gt;Suppose you want to fetch a user by his id and in addition you want all his posts, by using the N+1 query method, you will firstly find and fetch the user by his id .&lt;/p&gt;

&lt;p&gt;Fetching route example : &lt;code&gt;https://api-route/users/426ghh-5266t-RZGUZHZ&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then fetch the posts table to get all the user posts&lt;/p&gt;

&lt;p&gt;Fetching route example : &lt;code&gt;https://api-route/posts/egZHZ-12tgeg-6272v-jzhz&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Performing two queries will take longer to get the data we need, which will cause a performance hit at the client level in addition to overloading the server with unnecessary queries.&lt;/p&gt;

&lt;p&gt;So do your best to get the data you need in a single query. (utilizing eager loading or database joins)&lt;/p&gt;

&lt;p&gt;— What is eager loading :&lt;/p&gt;

&lt;p&gt;Eager loading is a performance enhancement strategy employed in software development, often within the realm of Object-Relational Mapping (ORM) frameworks.&lt;/p&gt;

&lt;p&gt;In eager loading, when you retrieve data from a database, you fetch not only the main object you’re interested in but also related objects or data that are commonly accessed together. This reduces the number of database queries and, consequently, improves performance by minimizing the “N+1 query problem.”&lt;/p&gt;

&lt;p&gt;For instance, let’s take a blog application as an example. In the absence of eager loading, if you retrieve a list of blog posts and then separately retrieve comments for each post, you would execute one query for obtaining the blog posts and N additional queries to fetch comments for each post (with N representing the number of posts). This approach can result in a substantial performance overhead.&lt;/p&gt;

&lt;p&gt;In contrast, when you implement eager loading, you can direct your ORM to retrieve both the blog posts and their corresponding comments in a single database query, typically accomplished through SQL JOIN operations. This streamlined approach optimizes data retrieval by reducing the number of database queries, ultimately enhancing the efficiency of your application.&lt;/p&gt;

&lt;p&gt;Eager loading proves especially beneficial in situations where you anticipate that specific related data will frequently be accessed together, thereby reducing the time and computational resources required to load and display this data within your application.&lt;/p&gt;

&lt;p&gt;— What is database joins :&lt;/p&gt;

&lt;p&gt;Database joins are operations used in relational databases to combine data from two or more tables based on a related column between them. They are fundamental for retrieving and working with data distributed across multiple tables in a structured and efficient manner.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Optimizing response time through caching is a crucial strategy for improving the performance and responsiveness of web APIs and applications. Caching involves the temporary storage of frequently requested data or responses, so that subsequent requests for the same data can be serviced quickly without the need to regenerate the response from the source.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;a- ) Client-Side Caching:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Client-side caching involves storing data or responses on the user’s device, typically in the web browser’s cache, commonly used for static assets like images, stylesheets, and JavaScript files and controlled through HTTP caching headers (e.g., Cache-Control, Expires, ETag) sent by the server in response headers.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;b- ) Server-Side Caching:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Server-side caching involves storing data or responses on the server or an intermediary server (like a proxy or CDN), especially for dynamic content or data that doesn’t change frequently. It helps reduce the load on the application server and database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compressing Responses&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Response compression is a performance optimization technique used to reduce the size of data transferred over the network. Smaller responses result in faster load times and better user experience, especially for users with limited bandwidth or on slower connections.&lt;/p&gt;

&lt;p&gt;Common Compression Algorithms are :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;— GZIP&lt;/strong&gt;: widely used, and works well for compressing text-based content such as HTML, CSS, JavaScript, and JSON. Most modern web servers and clients support GZIP compression.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;— Brotli&lt;/strong&gt;: a new compression algorithm developed by Google. It offers better compression rates than GZIP, which makes it more efficient for textual content. However, Brotli support may not be as widespread as GZIP.&lt;/p&gt;

&lt;p&gt;Applying all these methods will help us to improve the performance of our Apis, which means better client-side application quality and better user experience.&lt;/p&gt;

&lt;p&gt;Next time we will talk about “network efficiency” but in the meantime, I hope you find this article useful and feel free to leave your opinions in the comments.&lt;/p&gt;

&lt;p&gt;Follow me there :&lt;/p&gt;

&lt;p&gt;linkedin.com/in/laetitia-christelle-ouelle-89373121b/&lt;/p&gt;

&lt;p&gt;twitter.com/OuelleLaetitia&lt;/p&gt;

&lt;p&gt;dev.to/ouelle&lt;/p&gt;

&lt;p&gt;Happy coding ! 😏&lt;/p&gt;

</description>
      <category>api</category>
      <category>webdev</category>
      <category>documentation</category>
      <category>programming</category>
    </item>
    <item>
      <title>Basic CRUD operations with NestJs, TypeScript, Fastify &amp; MongoDB</title>
      <dc:creator>Laëtitia Christelle Ouelle</dc:creator>
      <pubDate>Fri, 18 Aug 2023 17:49:09 +0000</pubDate>
      <link>https://forem.com/ouelle/basic-crud-operations-with-nestjs-typescript-fastify-mongodb-1f1k</link>
      <guid>https://forem.com/ouelle/basic-crud-operations-with-nestjs-typescript-fastify-mongodb-1f1k</guid>
      <description>&lt;p&gt;Fastify is a web framework for building efficient and high-performance web applications and APIs in Node.js. It is designed to be lightweight and focused on speed, making it particularly suitable for applications that require low latency and high throughput. Fastify was developed to address some of the shortcomings of existing Node.js frameworks in terms of performance and simplicity.&lt;/p&gt;

&lt;p&gt;Let’s go&lt;/p&gt;

&lt;p&gt;Create your NestJs project&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npx nest new project-name


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

&lt;/div&gt;

&lt;p&gt;Our project name is : fastify-mongo-crud and we’ll use yarn but you can choose any other package manager listed.&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%2Fxvqix0uz5qcxvokyi6q3.png" 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%2Fxvqix0uz5qcxvokyi6q3.png" alt="package manager choice"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the Fastify package with this command&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

yarn add @nestjs/platform-fastify


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

&lt;/div&gt;

&lt;p&gt;By default , when you create a new Nestjs project, Nest install “@nestjs/platform-express” package (see the image below),&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%2Fsl6mu01gfv5bz325qqyj.png" 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%2Fsl6mu01gfv5bz325qqyj.png" alt="Platform express"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because we’ll use Fastify we dont need this express platform anymore.&lt;/p&gt;

&lt;p&gt;Create a nest resource with&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npx nest generate resource articles --no-spec


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

&lt;/div&gt;

&lt;p&gt;then select REST API&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%2Fuaxufgelwtscscjgnmuh.png" 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%2Fuaxufgelwtscscjgnmuh.png" alt="Rest API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nest will ask you i f you want to generate CRUD entry points : Type ‘n’ to say no.&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%2Fdw42u8sb9efevgy2eke0.png" 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%2Fdw42u8sb9efevgy2eke0.png" alt="n"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great! now as we already know, the default framework is Express, we need to change it to Fastify.&lt;/p&gt;

&lt;p&gt;In the root of the project, pass the code bellow into main.ts file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { FastifyAdapter,NestFastifyApplication} from '@nestjs/platform-fastify';

async function bootstrap() {
  const app = await NestFactory.create&amp;lt;NestFastifyApplication&amp;gt;(AppModule, new FastifyAdapter());
  await app.listen(3000);
}
bootstrap();


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

&lt;/div&gt;

&lt;p&gt;PS: If you have the following issue :&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Type 'NestFastifyApplication&amp;lt;RawServerDefault&amp;gt;' does not satisfy the constraint 'INestApplication'.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Perhaps there is a compatibility versions issue of both &lt;code&gt;@nestjs/platform-fastify&lt;/code&gt; and &lt;code&gt;NestJS core packages&lt;/code&gt;, so run&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

yarn upgrade-interactive --latest


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

&lt;/div&gt;

&lt;p&gt;to update the dependencies to their last stable versions.&lt;/p&gt;

&lt;p&gt;Once you’ve done with that, install mongoDb to the project&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

yarn add @nestjs/mongoose mongoose


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

&lt;/div&gt;

&lt;p&gt;Once the mongoose package is installed, we need to import the MongooseModule into the root AppModule. At this stage, your app.module.ts should be like :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ArticlesModule } from './articles/articles.module';
import { MongooseModule } from '@nestjs/mongoose';


@Module({
  imports: [ MongooseModule.forRoot('mongodb://mongO_uri'), ArticlesModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}


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

&lt;/div&gt;

&lt;p&gt;Do not forget to replace the &lt;code&gt;mongodb://mongO_uri&lt;/code&gt; by a real mongoDb uri.&lt;/p&gt;

&lt;p&gt;Create our article schema in &lt;code&gt;src/article/schema/article.schema.ts&lt;/code&gt; :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';

export type ArticleDocument = HydratedDocument&amp;lt;Article&amp;gt;;

@Schema()
export class Article {
  @Prop()
  title: string;

  @Prop()
  slug: string;

  @Prop()
  content: string;  
}

export const ArticleSchema = SchemaFactory.createForClass(Article);


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

&lt;/div&gt;

&lt;p&gt;Import the MongooseModule, Article and ArticleSchema in your article.module.ts file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { Module } from '@nestjs/common';
import { ArticlesService } from './articles.service';
import { ArticlesController } from './articles.controller';
import { MongooseModule } from '@nestjs/mongoose';
import { Article, ArticleSchema } from './schema/article.schema';

@Module({
  imports:[MongooseModule.forFeature([{ name: Article.name, schema: ArticleSchema }])],
  controllers: [ArticlesController],
  providers: [ArticlesService]
})
export class ArticlesModule {}


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

&lt;/div&gt;

&lt;p&gt;It’s time to run the project to see if everything works properly.&lt;/p&gt;

&lt;p&gt;Run it with &lt;code&gt;yarn start dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If not and if you got this error:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

const stringWidth = require('string-width');
Error [ERR_REQUIRE_ESM]: require() of ES Module


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

&lt;/div&gt;

&lt;p&gt;Just delete the node-module file and install all the dependencies again.&lt;/p&gt;

&lt;p&gt;Great! MongoDb and Fastify added and set up successfully&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%2Frr1tyko636wjy70xxdzj.png" 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%2Frr1tyko636wjy70xxdzj.png" alt="clean console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s create our services now in order to post and get data from the database.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/articles/articles.service.ts&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { Injectable } from '@nestjs/common';
import { Article } from './schema/article.schema';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';

@Injectable()
export class ArticlesService {
    constructor(@InjectModel(Article.name) private readonly articleModel: Model&amp;lt;Article&amp;gt;){}

    async postArticle( body: Article):Promise&amp;lt;Article&amp;gt; {
        const create = new this.articleModel(body)
        return create.save()
    }

    async getArticles(){
        return this.articleModel.find().exec()
    }
}


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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;postArticle()&lt;/code&gt; is here for creating new article and save it to the mongoDb database and &lt;code&gt;getArticles()&lt;/code&gt; for getting all the articles from the database&lt;/p&gt;

&lt;p&gt;Once we created all the services we want, let’s create the controller:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/articles/articles.controller.ts&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { Body, Controller, Get, Post } from '@nestjs/common';
import { ArticlesService } from './articles.service';
import { Article } from './schema/article.schema';

@Controller('articles')
export class ArticlesController {
  constructor(private readonly articlesService: ArticlesService) {}

  @Post('create')
  postArticle( @Body() body : Article ){
    return this.articlesService.postArticle(body);
  }

   @Get('get-articles')
   getArticles(){
    return this.articlesService.getArticles();
   }
}


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

&lt;/div&gt;

&lt;p&gt;For each function, we defined the request type (POST or GET only for this example), the pathname and the necessary parameters.&lt;/p&gt;

&lt;p&gt;Great! now let’s open postman to see if we can post and get with our simple Fastify api implementation.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;localhost:3000/articles/get-articles&lt;/code&gt; result :&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%2Ff71k6is7tuxb205wyvle.png" 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%2Ff71k6is7tuxb205wyvle.png" alt="Get result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;localhost:3000/articles/create&lt;/code&gt; result :&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%2F9mehsjdta96496lnvv6o.png" 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%2F9mehsjdta96496lnvv6o.png" alt="Post result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulation, we’ve delved into the world of basic CRUD operations, leveraging the power of NestJs, TypeScript, Fastify, and MongoDB. By mastering these fundamental techniques, you’ve laid a strong foundation for creating robust applications. As you continue to explore and refine your skills, remember that the journey of a developer is an ongoing evolution.&lt;/p&gt;

&lt;p&gt;For more about Fastify 👉🏾 : &lt;a href="https://fastify.dev/" rel="noopener noreferrer"&gt;https://fastify.dev/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find the whole project on Github 👇🏾 : &lt;a href="https://github.com/laetitiaouelle/fastify-mongo-crud" rel="noopener noreferrer"&gt;https://github.com/laetitiaouelle/fastify-mongo-crud&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow me there :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://linkedin.com/in/laetitia-christelle-ouelle-89373121b/" rel="noopener noreferrer"&gt;https://linkedin.com/in/laetitia-christelle-ouelle-89373121b/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/OuelleLaetitia" rel="noopener noreferrer"&gt;https://twitter.com/OuelleLaetitia&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ouelle"&gt;https://dev.to/ouelle&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy coding ! 😏&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>nestjs</category>
      <category>typescript</category>
      <category>fastify</category>
    </item>
    <item>
      <title>API Design and Architecture</title>
      <dc:creator>Laëtitia Christelle Ouelle</dc:creator>
      <pubDate>Wed, 16 Aug 2023 12:02:02 +0000</pubDate>
      <link>https://forem.com/ouelle/web-api-performance-gh1</link>
      <guid>https://forem.com/ouelle/web-api-performance-gh1</guid>
      <description>&lt;p&gt;As a developer, the main goal is to produce apps that users can easily use. For this reason, we usually hear words such as: reliable, scalable, fast, etc. All that to say, you have to build great apps which also means you have to know a lot about how to do it.&lt;/p&gt;

&lt;p&gt;In our digital world, good application performance is vital, ensuring seamless user experiences. As apps rely more on web APIs to communicate with external services, API performance becomes crucial. Factors like low latency, high throughput, scalability, caching, and error handling influence API efficiency. Balancing these elements ensures apps run smoothly by interacting effectively with APIs in today’s interconnected landscape.&lt;/p&gt;

&lt;p&gt;Now let’s dive deeper into the first step of web API performance optimization, which is to design your API with performance in mind.&lt;/p&gt;

&lt;p&gt;There are many points to discuss on this subject but we will deal with the most important in my opinion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RESTful Design, Versioning, Response Size and Format, Caching Headers, Logging and Monitoring.&lt;/strong&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;RESTful Design:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rest is a type of architectural that provides some standards and/or conventions that must be followed by an API to be called a RestFull or a Rest API.&lt;/p&gt;

&lt;p&gt;In 2000, An American computer scientist Roy T. Fielding proposed Rest witch stands for “Representational State Transfert” for building distributed systems based on hypermedia and it aims to facilitate communication between apps.&lt;/p&gt;

&lt;p&gt;Rest has 6 standards that a Rest API must follow:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Separation of the client and the server&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This approach means that server and client are managed separately and are only linked by communication. Thus, the client can be of any type. Rest API server could be builded using “Python FastAPI” and the client using “ReactJs”.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Statelessness&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Communication between client and server does not consider the session state from one request to another because each request is self-sufficient.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Uniformity of the interface&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Uniform Interface constraint subdivides into distinct elements that establish a reliable and foreseeable communication pattern between clients and servers. Here are the main components of the Uniform Interface constraint in a REST API:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource Identification in Requests&lt;/strong&gt;: Each resource is identified by a unique URI&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource Manipulation Through Representations&lt;/strong&gt;: Resources are represented in a standardized format, such as JSON or XML.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-Descriptive Messages&lt;/strong&gt; : Every message (request or response) must carry sufficient information for the recipient to grasp its intent, including metadata, headers, and a clear representation format.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hypermedia as the Engine of Application State (HATEOAS)&lt;/strong&gt; : The server embeds hypermedia links in responses, directing clients toward potential next steps. Clients utilize these links to traverse the application’s states.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Caching&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Implementing caching mechanisms can significantly improve API performance by serving frequently requested data from memory rather than generating it anew each time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Layered architecture&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In REST APIs, interactions and replies span various tiers. It’s essential to avoid assuming direct client-server connections; intermediaries often come into play. REST APIs must be crafted to be agnostic about whether they engage with the end app or an intermediary in the communication loop.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Code on demand (optional)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Typically, REST APIs dispatch static resources, yet on occasion, responses might carry executable code (e.g., Java applets). In such instances, the code should solely execute when prompted.&lt;/p&gt;

&lt;p&gt;To put it simply, the RestFull Design:&lt;/p&gt;

&lt;p&gt;— Follow the principles of representative state transfer (REST) to design simple, intuitive, and resource-oriented APIs.&lt;br&gt;
— Use standard HTTP methods (GET, POST, PUT, DELETE) appropriately to perform CRUD (Create, Read, Update, Delete) operations.&lt;br&gt;
— Use meaningful resource URLs and adopt a consistent naming convention.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Versioning&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Versioning for web API design involves offering a means to handle modifications and updates to your API while upholding backward compatibility. It empowers you to introduce fresh features, adjust current functionality, or retire specific capabilities, all without disrupting existing client apps reliant on your API. Versioning plays a pivotal role in ensuring a seamless experience for developers utilizing your API and the end-users of their applications.&lt;/p&gt;

&lt;p&gt;There are several approaches to versioning APIs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;URL Versioning:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/v1/resource&lt;/code&gt;&lt;br&gt;
&lt;code&gt;/v2/resource&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;p&gt;Easy to understand and implement.&lt;br&gt;
Clear separation between different versions.&lt;/p&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;p&gt;Clutters the URL space, especially if multiple resources need versioning.&lt;/p&gt;

&lt;p&gt;Potential issues with caching and reverse proxy configurations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Header Versioning:&lt;/strong&gt; It means including the version information in the HTTP headers of the request or response&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Accept: application/vnd.myapi.v1+json&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Accept: application/vnd.myapi.v2+json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;p&gt;Keeps the URL cleaner.&lt;br&gt;
Allows for easier integration with client libraries.&lt;/p&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;p&gt;Developers need to be aware of and handle the versioning in their code.&lt;br&gt;
Slightly more complex implementation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Query Parameter Versioning:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Version information is included as a query parameter in the URL.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/resource?v=1&lt;/code&gt;&lt;br&gt;
&lt;code&gt;/resource?v=2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;p&gt;Allows clients to easily switch between versions.&lt;/p&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;p&gt;Can lead to issues with caching and search engine indexing.&lt;br&gt;
Can make URLs less readable.&lt;/p&gt;

&lt;p&gt;API versioning holds utmost importance in design, wielding substantial influence over your API’s long-term maintainability and user-friendliness. Selecting a versioning approach that harmonizes with your API’s objectives and is effectively conveyed to your developer community is vital.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Response Size and Format&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Keep response payloads as small as possible by only including necessary data fields.&lt;/p&gt;

&lt;p&gt;Choose a compact data format, such as JSON, and minimize unnecessary whitespace.&lt;/p&gt;

&lt;p&gt;Avoid sending excessive metadata in responses.&lt;br&gt;
Implement pagination for large datasets to avoid sending all data in a single response.&lt;/p&gt;

&lt;p&gt;Use query parameters (e.g., ?page=2&amp;amp;limit=10) to control the number of items per page and the current page.&lt;/p&gt;

&lt;p&gt;Provide the ability for clients to specify which fields they need in the response (field selection).&lt;/p&gt;

&lt;p&gt;Use query parameters (e.g., ?fields=name,email) to customize response content.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Caching Headers&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Caching headers, HTTP headers employed to manage caching actions for resources shared between clients (like web browsers or API users) and servers, play a pivotal role.&lt;br&gt;
 Caching bolsters web app performance by curbing the necessity to continually fetch identical resources from the server.&lt;/p&gt;

&lt;p&gt;By configuring suitable caching headers, you wield control over how resources are retained and reused by clients and intermediate caches, including proxy servers and content delivery networks (CDNs).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Logging and Monitoring&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Logging&lt;/strong&gt;: Involves recording events, errors, and relevant information about the interactions and activities of your API.&lt;br&gt;
 These logs serve as a historical record that can be used for debugging, auditing, and understanding how your API is being used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitoring&lt;/strong&gt;: Involves the continuous observation of key metrics and indicators related to your API’s performance, availability, and usage. Monitoring helps you proactively identify performance bottlenecks, downtime, and anomalies, allowing you to take corrective action in a timely manner.&lt;/p&gt;

&lt;p&gt;Bear in mind that crafting an efficient API revolves around harmonizing simplicity, flexibility, and efficiency.&lt;/p&gt;

&lt;p&gt;As you center your efforts on these design tenets, stay open to adjustments and refinements to align with the shifting usage patterns and needs of your API.&lt;/p&gt;

&lt;p&gt;I hope you will find this article useful.&lt;br&gt;
See you soon 🙃&lt;/p&gt;

&lt;p&gt;Follow me there :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/in/laetitia-christelle-ouelle-89373121b/"&gt;https://www.linkedin.com/in/laetitia-christelle-ouelle-89373121b/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ouelle.medium.com/"&gt;https://ouelle.medium.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>webdev</category>
      <category>documentation</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
