<?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: Nikolás C. Meléndez</title>
    <description>The latest articles on DEV Community by Nikolás C. Meléndez (@cesar_nikolascamacmelen).</description>
    <link>https://dev.to/cesar_nikolascamacmelen</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%2F3071942%2Faaccf335-06b2-45af-bc0e-2e0c0a88593d.jpg</url>
      <title>DEV Community: Nikolás C. Meléndez</title>
      <link>https://dev.to/cesar_nikolascamacmelen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cesar_nikolascamacmelen"/>
    <language>en</language>
    <item>
      <title>🚀 Markflow: The Ultimate Free Online Markdown Editor (with Marp Support)</title>
      <dc:creator>Nikolás C. Meléndez</dc:creator>
      <pubDate>Sun, 01 Feb 2026 03:34:44 +0000</pubDate>
      <link>https://dev.to/cesar_nikolascamacmelen/markflow-the-ultimate-free-online-markdown-editor-with-marp-support-kpk</link>
      <guid>https://dev.to/cesar_nikolascamacmelen/markflow-the-ultimate-free-online-markdown-editor-with-marp-support-kpk</guid>
      <description>&lt;p&gt;Markdown is everywhere. We use it for documentation, blog posts, READMEs, and even presentations.&lt;br&gt;
But surprisingly, &lt;strong&gt;most online Markdown editors are either limited, locked behind accounts, or not designed for real workflows&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s why I built &lt;strong&gt;Markflow&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;👉 Try it here: &lt;a href="https://markflow.kormind.com/" rel="noopener noreferrer"&gt;https://markflow.kormind.com/&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%2Fhn9umknw5407z7s5dbt4.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%2Fhn9umknw5407z7s5dbt4.png" alt="Free online Markdown editor with Marp support – Markflow" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What is Markflow?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Markflow is a completely free, no-login, online editor for Markdown and Marp&lt;/strong&gt;, designed to be fast, visual, and developer-friendly.&lt;/p&gt;

&lt;p&gt;It’s built for people who want to &lt;strong&gt;write, structure, present, and export content&lt;/strong&gt; without friction.&lt;/p&gt;




&lt;h2&gt;
  
  
  📝 Full Markdown + Marp Support
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Standard &lt;strong&gt;Markdown&lt;/strong&gt; for articles, docs, and notes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marp&lt;/strong&gt; support for creating slide decks directly from Markdown&lt;/li&gt;
&lt;li&gt;Perfect for developers, students, educators, and content creators&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Write once. Use it everywhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧰 A Toolbar That Actually Helps
&lt;/h2&gt;

&lt;p&gt;One of the biggest pain points of online editors is usability.&lt;/p&gt;

&lt;p&gt;Markflow includes a &lt;strong&gt;clean, intuitive toolbar&lt;/strong&gt; that lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Format text (bold, italic, headings, lists)&lt;/li&gt;
&lt;li&gt;Insert code blocks, links, images, and quotes&lt;/li&gt;
&lt;li&gt;Focus on content instead of syntax&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Ideal for beginners &lt;strong&gt;and&lt;/strong&gt; power users.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤖 Built-in AI Assistant
&lt;/h2&gt;

&lt;p&gt;Markflow includes an &lt;strong&gt;AI assistant&lt;/strong&gt; to help you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improve your writing&lt;/li&gt;
&lt;li&gt;Rephrase or summarize content&lt;/li&gt;
&lt;li&gt;Generate sections or slide outlines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All directly inside the editor — no context switching.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Export Your Work, Your Way
&lt;/h2&gt;

&lt;p&gt;When you’re done, export instantly to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📄 &lt;code&gt;.md&lt;/code&gt; (Markdown)&lt;/li&gt;
&lt;li&gt;🌐 &lt;code&gt;.html&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;📑 &lt;code&gt;.pdf&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No watermarks. No restrictions.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔓 100% Free. No Account Required.
&lt;/h2&gt;

&lt;p&gt;This is important:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ No sign-up&lt;/li&gt;
&lt;li&gt;❌ No login&lt;/li&gt;
&lt;li&gt;❌ No paywalls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just open Markflow and start writing.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Who Is Markflow For?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🧑‍💻 Developers writing docs or presentations&lt;/li&gt;
&lt;li&gt;👨‍🏫 Teachers creating slides with Marp&lt;/li&gt;
&lt;li&gt;🎓 Students preparing reports and expos&lt;/li&gt;
&lt;li&gt;✍️ Writers who love Markdown&lt;/li&gt;
&lt;li&gt;🚀 Anyone who wants a simple, powerful editor&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌱 Still Growing
&lt;/h2&gt;

&lt;p&gt;Markflow is actively evolving, and feedback from the dev community is more than welcome.&lt;br&gt;
If you care about Markdown, Marp, and better writing tools on the web — this one’s for you.&lt;/p&gt;

&lt;p&gt;👉 Try Markflow for free: &lt;a href="https://markflow.kormind.com/" rel="noopener noreferrer"&gt;https://markflow.kormind.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>markdown</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>ai</category>
    </item>
    <item>
      <title>🚀 Top 5 Free AI APIs to Supercharge Your Apps in 2026</title>
      <dc:creator>Nikolás C. Meléndez</dc:creator>
      <pubDate>Sat, 31 Jan 2026 02:14:17 +0000</pubDate>
      <link>https://dev.to/cesar_nikolascamacmelen/top-5-free-ai-apis-to-supercharge-your-apps-in-2026-5ajb</link>
      <guid>https://dev.to/cesar_nikolascamacmelen/top-5-free-ai-apis-to-supercharge-your-apps-in-2026-5ajb</guid>
      <description>&lt;p&gt;Building a side project or an MVP shouldn't break the bank. In 2026, the barrier to entry for integrating Artificial Intelligence has never been lower. Whether you are building a tool like &lt;em&gt;GameOn&lt;/em&gt; or a productivity suite like &lt;em&gt;Markflow&lt;/em&gt;, choosing the right "Generous Free Tier" is the key to scaling without immediate costs. 🛠️&lt;/p&gt;

&lt;p&gt;Here are the best free AI API providers you should be using right now:&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Google AI Studio (Gemini) 🤖
&lt;/h2&gt;

&lt;p&gt;Google is currently dominating the free tier space, particularly for developers who need to process massive amounts of data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Best Part:&lt;/strong&gt; You get a staggering &lt;strong&gt;1 million token context window&lt;/strong&gt; for free.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Pros:&lt;/strong&gt; High rate limits (up to 15 RPM on Flash models); native multimodal support (it can "see" images and "watch" videos). ✅&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cons:&lt;/strong&gt; In the free tier, your data may be used to train their models. ❌&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Best for:&lt;/strong&gt; Processing long documents or complex codebases.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Groq Cloud ⚡
&lt;/h2&gt;

&lt;p&gt;If your app needs to feel "instant," Groq is the undisputed king of speed. By using specialized LPU (Language Processing Unit) hardware, they run open-source models faster than anyone else.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Best Part:&lt;/strong&gt; &lt;strong&gt;Near-instant responses&lt;/strong&gt; that feel like the AI is typing at the speed of light.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Pros:&lt;/strong&gt; Access to Llama 3 and Mistral at incredible speeds. ✅&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cons:&lt;/strong&gt; Rate limits can be tight during peak hours. ❌&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Best for:&lt;/strong&gt; Real-time chatbots and voice assistants.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. OpenRouter 🌐
&lt;/h2&gt;

&lt;p&gt;Think of OpenRouter as a "unified gateway." Instead of managing ten different API keys, you manage one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Best Part:&lt;/strong&gt; Access to a curated list of &lt;strong&gt;completely free models&lt;/strong&gt; (marked as $0.00/token).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Pros:&lt;/strong&gt; Swap between models (GPT, Claude, Llama) by changing just one line of code. ✅&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cons:&lt;/strong&gt; Free models can sometimes be congested or slower. ❌&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Best for:&lt;/strong&gt; Developers who want to experiment with different models without rewriting their backend.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Hugging Face (Serverless Inference) 🤗
&lt;/h2&gt;

&lt;p&gt;The "GitHub of AI" offers a serverless API to test thousands of community-driven models.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Best Part:&lt;/strong&gt; Access to niche, specialized models for tasks like translation, sentiment analysis, or image recognition.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Pros:&lt;/strong&gt; Massive variety (+100k models). ✅&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cons:&lt;/strong&gt; "Cold starts" can lead to high latency (up to 30 seconds) if the model isn't active. ❌&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Best for:&lt;/strong&gt; Specific, non-chat tasks like audio-to-text or image classification.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. GitHub Models 🐙
&lt;/h2&gt;

&lt;p&gt;If you already have a GitHub account, you're already in. GitHub has integrated high-end models directly into the developer workflow.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Best Part:&lt;/strong&gt; Deep integration with Codespaces and VS Code.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Pros:&lt;/strong&gt; Access to "heavyweights" like GPT-4o and Llama 3.1 for prototyping. ✅&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cons:&lt;/strong&gt; Strictly for prototyping; you cannot use the free tier for production/commercial apps. ❌&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Best for:&lt;/strong&gt; Rapid prototyping and internal testing.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Quick Comparison 📊
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Ideal for...&lt;/th&gt;
&lt;th&gt;Killer Feature&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Google AI Studio&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Massive Context&lt;/td&gt;
&lt;td&gt;1M+ Token Memory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Groq&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Speed&lt;/td&gt;
&lt;td&gt;Ultra-low Latency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OpenRouter&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Flexibility&lt;/td&gt;
&lt;td&gt;Universal API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hugging Face&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Niche Tasks&lt;/td&gt;
&lt;td&gt;Model Diversity&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  💡 Pro Tip: Stay Flexible
&lt;/h2&gt;

&lt;p&gt;Most of these providers (especially Groq and Google) offer &lt;strong&gt;OpenAI-compatible SDKs&lt;/strong&gt;. This is a game-changer! 💻&lt;/p&gt;

&lt;p&gt;By using a standard implementation, migrating from a free model to a paid production model is as simple as changing two lines in your &lt;code&gt;.env&lt;/code&gt; file:&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;// Example: Switching from Groq to OpenAI is just an environment variable away!&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AI_BASE_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Switch between Groq, OpenRouter, or OpenAI&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AI_API_KEY&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;Which one are you using for your next project? Let me know in the comments! 👇&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>javascript</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>The Best Free AI APIs for Developers in 2026 🚀</title>
      <dc:creator>Nikolás C. Meléndez</dc:creator>
      <pubDate>Sat, 31 Jan 2026 02:11:26 +0000</pubDate>
      <link>https://dev.to/cesar_nikolascamacmelen/the-best-free-ai-apis-for-developers-in-2026-3a0j</link>
      <guid>https://dev.to/cesar_nikolascamacmelen/the-best-free-ai-apis-for-developers-in-2026-3a0j</guid>
      <description>&lt;p&gt;Finding the right free API is a constant balance between &lt;strong&gt;power&lt;/strong&gt;, &lt;strong&gt;speed&lt;/strong&gt;, and &lt;strong&gt;privacy&lt;/strong&gt;. For developing modern applications like &lt;em&gt;GameOn&lt;/em&gt; or &lt;em&gt;Markflow&lt;/em&gt;, it's essential to identify providers with "Generous Free Tiers"—those that allow building and testing a complete MVP without initial costs. 🛠️&lt;/p&gt;

&lt;p&gt;Below is a curated list of the best AI API providers for 2026:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Google AI Studio (Gemini) 🤖
&lt;/h2&gt;

&lt;p&gt;Google currently offers one of the most competitive free tiers on the market, especially optimized for its "Flash" models.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Pros:&lt;/strong&gt; High rate limits (up to 15 RPM); massive context window of up to 1 million tokens; native multimodal capabilities (image and video analysis). ✅&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cons:&lt;/strong&gt; In the free tier, Google uses data to improve its models (privacy concerns); "Pro" models have much stricter restrictions. ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Groq Cloud ⚡
&lt;/h2&gt;

&lt;p&gt;More than just a model creator, Groq stands out for its specialized chips (LPUs) designed to run open-source models (Llama, Mistral) at unprecedented speeds.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Pros:&lt;/strong&gt; &lt;strong&gt;Near-instant responses&lt;/strong&gt;; free access to open-source models through its "Beta" tier. ✅&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cons:&lt;/strong&gt; Prone to rate limit errors during traffic peaks; model variety is limited to their current hosting catalog. ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. OpenRouter 🌐
&lt;/h2&gt;

&lt;p&gt;Acts as a "unified gateway." With a single API key, you can connect to virtually any existing model (Claude, GPT-4, Llama, etc.).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Pros:&lt;/strong&gt; Access to a wide variety of &lt;strong&gt;completely free models&lt;/strong&gt; (marked as $0.00/token); allows pivoting between models by changing just one line of code. ✅&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cons:&lt;/strong&gt; Free models often suffer from congestion; requires manual filtering within their extensive list of options. ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Hugging Face (Serverless Inference) 🤗
&lt;/h2&gt;

&lt;p&gt;Considered the "GitHub of AI," Hugging Face allows testing thousands of community models through its serverless API.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Pros:&lt;/strong&gt; Unmatched diversity (text, image, audio, and translation); excellent for specialized or niche tasks. ✅&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cons:&lt;/strong&gt; The free tier is exclusively for evaluation; high initial latency (models can take 30 seconds to "wake up"); not recommended for production. ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. GitHub Models 🐙
&lt;/h2&gt;

&lt;p&gt;If you are already a GitHub user, you can access their model marketplace directly from your development environment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Pros:&lt;/strong&gt; Seamless integration with the development workflow; access to top-tier models like GPT-4o and Llama 3. ✅&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cons:&lt;/strong&gt; Use strictly limited to prototyping; commercial or public-facing use is prohibited in the free version. ❌&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Comparative Table 📊
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Ideal for...&lt;/th&gt;
&lt;th&gt;Main Advantage&lt;/th&gt;
&lt;th&gt;Main Disadvantage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Google AI Studio&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Large contexts&lt;/td&gt;
&lt;td&gt;1M+ token memory&lt;/td&gt;
&lt;td&gt;Data privacy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Groq&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Real-time chat&lt;/td&gt;
&lt;td&gt;Extreme speed&lt;/td&gt;
&lt;td&gt;Strict rate limits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OpenRouter&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multi-model usage&lt;/td&gt;
&lt;td&gt;Universal single API&lt;/td&gt;
&lt;td&gt;Variable quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hugging Face&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Specific tasks&lt;/td&gt;
&lt;td&gt;Variety (+100k models)&lt;/td&gt;
&lt;td&gt;Latency (Cold start)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Recommendation for Your Projects 💡
&lt;/h2&gt;

&lt;p&gt;If you are working with technologies like &lt;strong&gt;NextJS&lt;/strong&gt; and &lt;strong&gt;Supabase&lt;/strong&gt;, the technical recommendation is to start with &lt;strong&gt;Groq&lt;/strong&gt; or &lt;strong&gt;Google AI Studio&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Both providers offer SDKs compatible with the OpenAI standard. This means if you decide to migrate to a paid model in the future, you'll only need to update the &lt;code&gt;baseURL&lt;/code&gt; and &lt;code&gt;apiKey&lt;/code&gt; in your environment variables, keeping your code logic intact. 💻&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>javascript</category>
    </item>
    <item>
      <title>🔍 Observability Practices: A Practical Guide With Real-World Examples</title>
      <dc:creator>Nikolás C. Meléndez</dc:creator>
      <pubDate>Mon, 24 Nov 2025 02:34:56 +0000</pubDate>
      <link>https://dev.to/cesar_nikolascamacmelen/observability-practices-a-practical-guide-with-real-world-examples-4eld</link>
      <guid>https://dev.to/cesar_nikolascamacmelen/observability-practices-a-practical-guide-with-real-world-examples-4eld</guid>
      <description>&lt;p&gt;Modern software systems are more distributed, dynamic, and complex than ever. Microservices, serverless functions, containers, and event-driven architectures make traditional monitoring insufficient.&lt;br&gt;
To understand what is actually happening inside your application, you need &lt;strong&gt;observability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This article explains the foundational pillars of observability, best practices, common tools, and includes a hands-on real-world example using &lt;strong&gt;Grafana + Prometheus&lt;/strong&gt; for metrics and &lt;strong&gt;ELK Stack&lt;/strong&gt; for logs.&lt;/p&gt;


&lt;h2&gt;
  
  
  🚦 What Is Observability?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Observability&lt;/strong&gt; is the ability to understand the internal state of a system based solely on the data it produces, such as metrics, logs, and traces.&lt;/p&gt;

&lt;p&gt;Unlike classical monitoring, which answers &lt;em&gt;“Is the system up?”&lt;/em&gt;, observability answers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Why is the system slow?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Where is the latency coming from?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Which dependency failed?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;What changed recently that caused errors?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  📊 The Three Pillars of Observability
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1. Metrics&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Numeric measurements collected over time.&lt;br&gt;
Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU usage&lt;/li&gt;
&lt;li&gt;Request throughput&lt;/li&gt;
&lt;li&gt;Error rate&lt;/li&gt;
&lt;li&gt;Database latency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tools: Prometheus, Grafana, Datadog Metrics, AWS CloudWatch Metrics.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;2. Logs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Immutable records about events happening in the system.&lt;br&gt;
Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Info logs&lt;/li&gt;
&lt;li&gt;Warnings&lt;/li&gt;
&lt;li&gt;Errors&lt;/li&gt;
&lt;li&gt;Audit logs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tools: ELK Stack, Datadog Logs, Azure Log Analytics, Loki.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;3. Traces&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A trace follows a single request across distributed components.&lt;br&gt;
Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microservices call chain&lt;/li&gt;
&lt;li&gt;Latency across services&lt;/li&gt;
&lt;li&gt;Errors from downstream dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tools: Jaeger, Zipkin, OpenTelemetry, AWS X-Ray, New Relic.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧱 Core Observability Practices
&lt;/h2&gt;
&lt;h3&gt;
  
  
  ✔️ 1. Use Structured Logging
&lt;/h3&gt;

&lt;p&gt;Instead of plain text logs, use JSON.&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-11-23T10:15:20Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ERROR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"orders-api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Payment gateway timeout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"orderId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10422&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"durationMs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3200&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Structured logs allow better filtering and search on platforms like ELK, Datadog, and CloudWatch.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✔️ 2. Define Standard Business Metrics
&lt;/h3&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;orders_created_total&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;failed_logins_total&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;payment_latency_seconds&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Business KPIs help identify anomalies beyond pure infrastructure.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✔️ 3. Trace End-to-End Requests
&lt;/h3&gt;

&lt;p&gt;Use &lt;strong&gt;OpenTelemetry&lt;/strong&gt; to instrument services.&lt;br&gt;
Traces give visibility across microservices.&lt;/p&gt;


&lt;h3&gt;
  
  
  ✔️ 4. Set SLOs and Alert Policies
&lt;/h3&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SLO:&lt;/strong&gt; 99% of HTTP requests &amp;lt; 150ms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alert:&lt;/strong&gt; More than 5% errors in 5 minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good alerts are &lt;em&gt;meaningful&lt;/em&gt;, not noisy.&lt;/p&gt;


&lt;h3&gt;
  
  
  ✔️ 5. Centralize All Telemetry Data
&lt;/h3&gt;

&lt;p&gt;Use &lt;strong&gt;one platform&lt;/strong&gt; for metrics + logs + traces.&lt;br&gt;
Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Datadog&lt;/li&gt;
&lt;li&gt;New Relic&lt;/li&gt;
&lt;li&gt;Grafana Cloud&lt;/li&gt;
&lt;li&gt;AWS CloudWatch&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🛠️ Real-World Example: Observability With Prometheus + Grafana + ELK Stack
&lt;/h2&gt;

&lt;p&gt;Below is a complete example using a simple &lt;strong&gt;Node.js API&lt;/strong&gt; instrumented with &lt;strong&gt;Prometheus metrics&lt;/strong&gt; and &lt;strong&gt;ELK logging&lt;/strong&gt;.&lt;/p&gt;


&lt;h1&gt;
  
  
  📌 Example Application (Node.js)
&lt;/h1&gt;

&lt;p&gt;We will expose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/metrics&lt;/code&gt;&lt;/strong&gt; endpoint for Prometheus scraping&lt;/li&gt;
&lt;li&gt;Structured logs sent to Logstash (ELK stack)&lt;/li&gt;
&lt;li&gt;A simple API endpoint&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🔧 Step 1 — Install Dependencies
&lt;/h2&gt;


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

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧪 Step 2 — Node.js Code With Observability
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prom-client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;winston&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;winston&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ElasticsearchTransport&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;winston-elasticsearch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;register&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&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;Registry&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// ----- PROMETHEUS METRICS -----&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;httpRequestCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&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;Counter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http_requests_total&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;help&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Total HTTP requests&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;labelNames&lt;/span&gt;&lt;span class="p"&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;method&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;route&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;status&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="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerMetric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;httpRequestCounter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;httpRequestDuration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&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;Histogram&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http_request_duration_seconds&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;help&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HTTP request latency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;buckets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; 
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerMetric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;httpRequestDuration&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="nf"&gt;collectDefaultMetrics&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;register&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// ----- ELK LOGGING -----&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;esTransportOpts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;info&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;clientOpts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:9200&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;winston&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createLogger&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;transports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ElasticsearchTransport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;esTransportOpts&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// ----- NORMAL API ROUTE -----&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;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;/api/orders&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;httpRequestDuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startTimer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fetching orders&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;orders-api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;httpRequestCounter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/orders&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// ----- METRICS ENDPOINT FOR PROMETHEUS -----&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;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;/metrics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// ----- START SERVER -----&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;API running on port 3000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📊 Step 3 — Prometheus Scrape Configuration
&lt;/h2&gt;

&lt;p&gt;Add to &lt;code&gt;prometheus.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;scrape_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orders-api"&lt;/span&gt;
    &lt;span class="na"&gt;static_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;localhost:3000"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prometheus now collects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;request count&lt;/li&gt;
&lt;li&gt;request latency&lt;/li&gt;
&lt;li&gt;default node metrics&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📈 Step 4 — Grafana Dashboard
&lt;/h2&gt;

&lt;p&gt;Grafana automatically detects metrics from Prometheus and you can plot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requests per second&lt;/li&gt;
&lt;li&gt;Error rate&lt;/li&gt;
&lt;li&gt;Latency percentiles (P95, P99)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create a panel and use this query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rate(http_requests_total[5m])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another useful panel for latency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📝 Step 5 — ELK Stack for Logs
&lt;/h2&gt;

&lt;p&gt;Logs go to &lt;strong&gt;Elasticsearch&lt;/strong&gt;, and you can search them with Kibana:&lt;/p&gt;

&lt;p&gt;Example search query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;service: "orders-api" AND level: "info"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example rendered log:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Fetching orders"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"orders-api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"environment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"production"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-11-23T10:20:34.123Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  🚀 Final Thoughts
&lt;/h1&gt;

&lt;p&gt;Modern systems demand more than simple health checks—&lt;br&gt;
they require full &lt;strong&gt;observability&lt;/strong&gt; to identify, diagnose, and prevent problems in production.&lt;/p&gt;

&lt;p&gt;By applying:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structured logs&lt;/li&gt;
&lt;li&gt;custom metrics&lt;/li&gt;
&lt;li&gt;distributed tracing&lt;/li&gt;
&lt;li&gt;centralized dashboards&lt;/li&gt;
&lt;li&gt;SLO-driven alerting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;you significantly increase reliability, and most importantly, you gain the ability to understand your system deeply.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>programming</category>
      <category>productivity</category>
      <category>analytics</category>
    </item>
    <item>
      <title>🌐 Build Your Own MCP Server — and Connect It to *Any* MCP Client (Claude, VSCode, GitHub, and More)</title>
      <dc:creator>Nikolás C. Meléndez</dc:creator>
      <pubDate>Tue, 11 Nov 2025 14:36:13 +0000</pubDate>
      <link>https://dev.to/cesar_nikolascamacmelen/build-your-own-mcp-server-and-connect-it-to-any-mcp-client-claude-vscode-github-and-more-c55</link>
      <guid>https://dev.to/cesar_nikolascamacmelen/build-your-own-mcp-server-and-connect-it-to-any-mcp-client-claude-vscode-github-and-more-c55</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Imagine building a tool once… and instantly using it across &lt;strong&gt;Claude Desktop&lt;/strong&gt;, &lt;strong&gt;VSCode&lt;/strong&gt;, &lt;strong&gt;GitHub&lt;/strong&gt;, or &lt;strong&gt;any future AI platform&lt;/strong&gt; that supports MCP.&lt;br&gt;&lt;br&gt;
Welcome to the next evolution of AI/tool interoperability.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🚀 What is MCP?
&lt;/h2&gt;

&lt;p&gt;MCP (Model Context Protocol) is an &lt;strong&gt;open-source standard&lt;/strong&gt; designed to enable seamless integration between LLM-based clients and external systems/tools/data sources. :contentReference[oaicite:1]{index=1}&lt;/p&gt;

&lt;p&gt;It defines how clients (which may wrap chat-apps, IDEs, or other AI interfaces) connect to servers exposing context, tools, resources, and prompts — abstracting away most compatibility issues. :contentReference[oaicite:2]{index=2}&lt;/p&gt;




&lt;h2&gt;
  
  
  🔧 Example Public Repositories
&lt;/h2&gt;

&lt;p&gt;You don’t have to reinvent the wheel — there are &lt;strong&gt;reference MCP server implementations&lt;/strong&gt; available to get you started:  &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Repo / SDK / Server&lt;/th&gt;
&lt;th&gt;Description / Key Features&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;GitHub MCP Server&lt;/strong&gt; — &lt;code&gt;github/github-mcp-server&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;A server that connects AI clients to GitHub: enables reading repos, managing issues/PRs, analyzing code, automating workflows via natural-language interactions. :contentReference[oaicite:4]{index=4}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;ModelContextProtocol/servers&lt;/strong&gt; — &lt;code&gt;modelcontextprotocol/servers&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;A curated collection of reference MCP server implementations: includes &lt;em&gt;Template MCP Server&lt;/em&gt;, &lt;em&gt;mcp-open-library&lt;/em&gt;, &lt;em&gt;MCP-OpenStack-Ops&lt;/em&gt;, and more, in various languages/contexts. :contentReference[oaicite:6]{index=6}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These repos let you &lt;strong&gt;fork&lt;/strong&gt;, &lt;strong&gt;modify&lt;/strong&gt;, or &lt;strong&gt;extend&lt;/strong&gt; existing MCP servers — saving time and helping you follow established patterns.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ How to Spin Up a Sample MCP Server Locally (Example with GitHub MCP Server)
&lt;/h2&gt;

&lt;p&gt;Here’s how you could get started with the GitHub MCP Server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/github/github-mcp-server.git
&lt;span class="nb"&gt;cd &lt;/span&gt;github-mcp-server
&lt;span class="c"&gt;# follow setup instructions (auth, env vars, etc.)&lt;/span&gt;
&lt;span class="c"&gt;# likely you'll need to provide a GitHub token or configure OAuth&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;   &lt;span class="c"&gt;# or the appropriate build/deploy command&lt;/span&gt;
node ./server.js   &lt;span class="c"&gt;# or equivalent start command&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Security warning&lt;/strong&gt;: MCP servers can execute arbitrary logic/tools, so only run trusted servers or audit code carefully before using them. MCP supports various transports including &lt;code&gt;stdio&lt;/code&gt;, &lt;code&gt;http&lt;/code&gt;, etc. ([Visual Studio Code][1])&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once running, you can configure your MCP-aware client (Claude Desktop, VSCode, or others) to connect to it — more on configuration below.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Client Configuration &amp;amp; Usage
&lt;/h2&gt;

&lt;p&gt;Most MCP clients support multiple “server” transports (HTTP, stdio, SSE, etc.). ([Visual Studio Code][1])&lt;/p&gt;

&lt;p&gt;Here’s a minimal example of what your MCP config might look like in VSCode’s &lt;code&gt;.vscode/mcp.json&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;json&lt;br&gt;
{&lt;br&gt;
  "servers": {&lt;br&gt;
    "my-github-mcp": {&lt;br&gt;
      "type": "http",&lt;br&gt;
      "url": "http://localhost:PORT"  &lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Replace &lt;code&gt;PORT&lt;/code&gt; with what your server is listening on. With this, your AI-assisted environment will be able to call the exposed MCP tools (e.g. list repos, open issues, analyze code) securely and interactively.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Why This is Awesome
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Interoperability&lt;/strong&gt; — One server + many clients.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modular AI tooling&lt;/strong&gt; — Expose custom logic/APIs as tools the AI can call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-source &amp;amp; community-driven&lt;/strong&gt; — Benefit from reference servers and SDKs maintained by the wider ecosystem (TS, Python, Java, etc.). ([GitHub][2])&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incremental adoption&lt;/strong&gt; — Start small (e.g. expose a weather or search tool), then grow.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💬 What’s Next — Extend &amp;amp; Share
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Fork one of the example MCP servers above.&lt;/li&gt;
&lt;li&gt;Add your own tools/resources (DB access, private APIs, file parsers, whatever).&lt;/li&gt;
&lt;li&gt;Connect it to &lt;em&gt;any&lt;/em&gt; UI client (Claude, VSCode, or home-grown client).&lt;/li&gt;
&lt;li&gt;Publish &amp;amp; share — the community thrives on real-world use-cases and feedback.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🔗 References &amp;amp; Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Official servers listing: &lt;code&gt;modelcontextprotocol/servers&lt;/code&gt; repo.&lt;/li&gt;
&lt;li&gt;GitHub-specific MCP server: &lt;code&gt;github/github-mcp-server&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Official MCP docs: build guides, spec, transports, resource/types. ([Model Context Protocol][3])&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Discussion — Over to You
&lt;/h2&gt;

&lt;p&gt;What’s the &lt;strong&gt;coolest tool&lt;/strong&gt; you’d build using MCP?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;em&gt;code review bot&lt;/em&gt; that hooks directly into GitHub&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;knowledge assistant&lt;/em&gt; over private docs/DB&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;UI-driven tool&lt;/em&gt; that visually exposes data via AI prompts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop your thoughts, ideas or questions — let’s hack this together 👇&lt;/p&gt;

</description>
      <category>ai</category>
      <category>developers</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>🚀 Meet Telelinker: A CLI Tool to Extract and Analyze Links from Telegram Groups</title>
      <dc:creator>Nikolás C. Meléndez</dc:creator>
      <pubDate>Thu, 06 Nov 2025 02:39:22 +0000</pubDate>
      <link>https://dev.to/cesar_nikolascamacmelen/meet-telelinker-a-cli-tool-to-extract-and-analyze-links-from-telegram-groups-14aj</link>
      <guid>https://dev.to/cesar_nikolascamacmelen/meet-telelinker-a-cli-tool-to-extract-and-analyze-links-from-telegram-groups-14aj</guid>
      <description>&lt;p&gt;👋 Hey everyone!&lt;/p&gt;

&lt;p&gt;I recently built &lt;strong&gt;&lt;a href="https://github.com/nkmelndz/telelinker" rel="noopener noreferrer"&gt;Telelinker&lt;/a&gt;&lt;/strong&gt; — an open-source &lt;strong&gt;command-line tool&lt;/strong&gt; that helps you extract and analyze links shared in &lt;strong&gt;Telegram groups&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you’ve ever wanted to know &lt;em&gt;what people are sharing most often&lt;/em&gt; in your community — YouTube videos, TikToks, LinkedIn posts, Medium articles — Telelinker can help you find out in seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Why I built it
&lt;/h2&gt;

&lt;p&gt;Telegram is full of interesting content. But if you manage or research multiple groups, tracking &lt;em&gt;what gets shared&lt;/em&gt; can get messy.&lt;/p&gt;

&lt;p&gt;I wanted a simple tool that could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grab all links shared in a group&lt;/li&gt;
&lt;li&gt;Detect which platform they belong to (YouTube, TikTok, etc.)&lt;/li&gt;
&lt;li&gt;Collect useful metadata like username, likes, comments, views&lt;/li&gt;
&lt;li&gt;Export everything to CSV or PostgreSQL for analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, I built &lt;strong&gt;Telelinker&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ What Telelinker does
&lt;/h2&gt;

&lt;p&gt;Once you connect it to your Telegram account, Telelinker can:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Extract links automatically&lt;/strong&gt; from groups you’re a member of&lt;br&gt;
✅ &lt;strong&gt;Detect platforms&lt;/strong&gt; — YouTube, TikTok, Instagram, LinkedIn, Medium, Dev.to, and more&lt;br&gt;
✅ &lt;strong&gt;Pull metadata&lt;/strong&gt; (username, views, likes, comments, date, title…)&lt;br&gt;
✅ &lt;strong&gt;Export results&lt;/strong&gt; to CSV, JSON, or PostgreSQL&lt;br&gt;
✅ &lt;strong&gt;Run interactively&lt;/strong&gt; or headless&lt;br&gt;
✅ &lt;strong&gt;Process multiple groups&lt;/strong&gt; at once&lt;/p&gt;

&lt;p&gt;Perfect for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📊 Content trend analysis&lt;/li&gt;
&lt;li&gt;🧠 Social research&lt;/li&gt;
&lt;li&gt;🧰 Community management&lt;/li&gt;
&lt;li&gt;🧮 Data mining and social media analytics&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🧩 Installation
&lt;/h2&gt;

&lt;p&gt;You can install Telelinker in a few ways.&lt;/p&gt;
&lt;h3&gt;
  
  
  Option 1 — Scoop (Windows)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;telelinker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://github.com/nkmelndz/telelinker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;telelinker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Option 2 — Docker
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/nkmelndz/telelinker.git
&lt;span class="nb"&gt;cd &lt;/span&gt;telelinker
docker build &lt;span class="nt"&gt;-t&lt;/span&gt; telelinker &lt;span class="nb"&gt;.&lt;/span&gt;
docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/app telelinker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Option 3 — From Source (Python 3.11+)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/nkmelndz/telelinker.git
&lt;span class="nb"&gt;cd &lt;/span&gt;telelinker
python &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate  &lt;span class="c"&gt;# Windows: venv\Scripts\activate&lt;/span&gt;
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
python &lt;span class="nt"&gt;-m&lt;/span&gt; src.main setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🎮 How to use Telelinker
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1️⃣ Configure your Telegram API credentials
&lt;/h3&gt;

&lt;p&gt;You’ll need an API ID and HASH from &lt;a href="https://my.telegram.org" rel="noopener noreferrer"&gt;my.telegram.org&lt;/a&gt;.&lt;br&gt;
Once you have them, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;telelinker setup
telelinker login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2️⃣ List your Telegram groups
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;telelinker &lt;span class="nb"&gt;groups&lt;/span&gt; &lt;span class="nt"&gt;--interactive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or export them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;telelinker &lt;span class="nb"&gt;groups&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; csv &lt;span class="nt"&gt;--out&lt;/span&gt; my_groups.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3️⃣ Extract and analyze links
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;telelinker fetch &lt;span class="nt"&gt;--interactive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can filter by group, limit results, and choose export formats.&lt;br&gt;
Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;telelinker fetch &lt;span class="nt"&gt;--group&lt;/span&gt; @mygroup &lt;span class="nt"&gt;--limit&lt;/span&gt; 100 &lt;span class="nt"&gt;--format&lt;/span&gt; csv &lt;span class="nt"&gt;--out&lt;/span&gt; links.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📊 Example output
&lt;/h2&gt;

&lt;p&gt;After running Telelinker, you’ll get a CSV or JSON file like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Username&lt;/th&gt;
&lt;th&gt;Likes&lt;/th&gt;
&lt;th&gt;Comments&lt;/th&gt;
&lt;th&gt;Views&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;YouTube&lt;/td&gt;
&lt;td&gt;devtips&lt;/td&gt;
&lt;td&gt;2345&lt;/td&gt;
&lt;td&gt;120&lt;/td&gt;
&lt;td&gt;10k&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://youtu.be/" rel="noopener noreferrer"&gt;https://youtu.be/&lt;/a&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TikTok&lt;/td&gt;
&lt;td&gt;codeguru&lt;/td&gt;
&lt;td&gt;842&lt;/td&gt;
&lt;td&gt;59&lt;/td&gt;
&lt;td&gt;2.3k&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://tiktok.com/" rel="noopener noreferrer"&gt;https://tiktok.com/&lt;/a&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LinkedIn&lt;/td&gt;
&lt;td&gt;jane_dev&lt;/td&gt;
&lt;td&gt;150&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://linkedin.com/" rel="noopener noreferrer"&gt;https://linkedin.com/&lt;/a&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧠 What you can do with the data
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Find trends:&lt;/strong&gt; Which platforms are most shared in your groups&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Research topics:&lt;/strong&gt; What kind of content spreads fastest&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build dashboards:&lt;/strong&gt; Combine Telelinker exports with tools like Grafana or Metabase&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automate reports:&lt;/strong&gt; Use cron jobs to fetch fresh data weekly&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤝 Want to contribute?
&lt;/h2&gt;

&lt;p&gt;Telelinker is open source under the &lt;strong&gt;MIT License&lt;/strong&gt; — everyone’s welcome to contribute!&lt;/p&gt;

&lt;p&gt;You can help by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding scrapers for more platforms&lt;/li&gt;
&lt;li&gt;Improving metadata extraction&lt;/li&gt;
&lt;li&gt;Suggesting new features&lt;/li&gt;
&lt;li&gt;Writing docs or tutorials&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/nkmelndz/telelinker/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;CONTRIBUTING.md&lt;/a&gt; for details.&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 Final thoughts
&lt;/h2&gt;

&lt;p&gt;I built this tool to make Telegram data more accessible for analysis — and I’d love to see what others do with it.&lt;/p&gt;

&lt;p&gt;If you find it useful, please ⭐ star the repo or share it withothers!&lt;br&gt;
Feedback, ideas, and contributions are all super welcome 🙌&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/nkmelndz/telelinker" rel="noopener noreferrer"&gt;github.com/nkmelndz/telelinker&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>cli</category>
      <category>opensource</category>
      <category>telegram</category>
    </item>
    <item>
      <title>🏢 Enterprise Design Patterns: Building Scalable Systems with Fowler’s Patterns in Go</title>
      <dc:creator>Nikolás C. Meléndez</dc:creator>
      <pubDate>Tue, 28 Oct 2025 02:36:58 +0000</pubDate>
      <link>https://dev.to/cesar_nikolascamacmelen/enterprise-design-patterns-building-scalable-systems-with-fowlers-patterns-in-go-2ckk</link>
      <guid>https://dev.to/cesar_nikolascamacmelen/enterprise-design-patterns-building-scalable-systems-with-fowlers-patterns-in-go-2ckk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Inspired by Martin Fowler’s &lt;em&gt;Catalog of Patterns of Enterprise Application Architecture&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Enterprise applications are complex by nature. They manage large datasets, coordinate multiple services, and must remain maintainable and scalable over time.&lt;br&gt;&lt;br&gt;
Martin Fowler’s &lt;em&gt;Enterprise Application Architecture Patterns&lt;/em&gt; provides a timeless catalog of design patterns that help developers structure large-scale systems.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore &lt;strong&gt;Enterprise Design Patterns&lt;/strong&gt;, understand their key categories, and implement a &lt;strong&gt;real-world example in Go (Golang)&lt;/strong&gt; that demonstrates how they work in practice.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 What Are Enterprise Design Patterns?
&lt;/h2&gt;

&lt;p&gt;Enterprise Design Patterns are &lt;strong&gt;reusable solutions&lt;/strong&gt; to common architectural problems in enterprise applications — such as managing transactions, persistence, or business logic.&lt;/p&gt;

&lt;p&gt;Fowler classifies them into several major categories:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Domain Logic Patterns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Organize business logic (e.g., &lt;em&gt;Transaction Script&lt;/em&gt;, &lt;em&gt;Domain Model&lt;/em&gt;, &lt;em&gt;Table Module&lt;/em&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Source Architectural Patterns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Handle how data is accessed and stored (e.g., &lt;em&gt;Active Record&lt;/em&gt;, &lt;em&gt;Data Mapper&lt;/em&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Object-Relational Behavioral Patterns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manage interaction between objects and relational data (e.g., &lt;em&gt;Identity Map&lt;/em&gt;, &lt;em&gt;Unit of Work&lt;/em&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Web Presentation Patterns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Structure the UI and interaction (e.g., &lt;em&gt;Model View Controller&lt;/em&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Distribution Patterns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manage distributed system behavior (e.g., &lt;em&gt;Remote Facade&lt;/em&gt;, &lt;em&gt;Data Transfer Object&lt;/em&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  ⚙️ Example: Repository + Unit of Work Pattern in Go
&lt;/h2&gt;

&lt;p&gt;Let’s take a practical example of an enterprise-grade approach to managing persistence in a &lt;strong&gt;Go web service&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We’ll combine two Fowler patterns:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;🧩 &lt;strong&gt;Repository Pattern&lt;/strong&gt; — provides an abstraction layer over data access logic.
&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;Unit of Work Pattern&lt;/strong&gt; — tracks changes to objects during a transaction and coordinates the writing out of changes.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🧱 Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
go-enterprise-patterns/
├── main.go
├── domain/
│   └── user.go
├── repository/
│   └── user_repository.go
└── unitofwork/
└── unit_of_work.go

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧩 domain/user.go
&lt;/h2&gt;



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

// User represents a simple domain entity.
type User struct {
    ID    int
    Name  string
    Email string
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📦 repository/user_repository.go
&lt;/h2&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;repository&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;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"go-enterprise-patterns/domain"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// UserRepository simulates a simple in-memory data storage.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;UserRepository&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// NewUserRepository initializes a new repository instance.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewUserRepository&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Add inserts a new user into the repository.&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;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"🟢 Added user:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// GetAll retrieves all stored users.&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;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GetAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&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="n"&gt;users&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔄 unitofwork/unit_of_work.go
&lt;/h2&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;unitofwork&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;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"go-enterprise-patterns/domain"&lt;/span&gt;
    &lt;span class="s"&gt;"go-enterprise-patterns/repository"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// UnitOfWork tracks pending changes and commits them as a single transaction.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;UnitOfWork&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;newEntities&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;
    &lt;span class="n"&gt;repo&lt;/span&gt;        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// NewUnitOfWork creates a new UnitOfWork.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UnitOfWork&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;UnitOfWork&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;newEntities&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;
        &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="n"&gt;repo&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="c"&gt;// RegisterNew queues a new user for persistence.&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;u&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UnitOfWork&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;RegisterNew&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"📝 Registering new user:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;newEntities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;newEntities&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Commit saves all queued users in a single transaction.&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;u&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UnitOfWork&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;newEntities&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;newEntities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"✅ Transaction committed."&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;h2&gt;
  
  
  🚀 main.go
&lt;/h2&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;"go-enterprise-patterns/domain"&lt;/span&gt;
    &lt;span class="s"&gt;"go-enterprise-patterns/repository"&lt;/span&gt;
    &lt;span class="s"&gt;"go-enterprise-patterns/unitofwork"&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="c"&gt;// Initialize repository and unit of work&lt;/span&gt;
    &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewUserRepository&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;uow&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;unitofwork&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Create domain entities&lt;/span&gt;
    &lt;span class="n"&gt;user1&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Email&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"alice@example.com"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;user2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Email&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"bob@example.com"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Register new entities for persistence&lt;/span&gt;
    &lt;span class="n"&gt;uow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterNew&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;uow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterNew&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Commit transaction&lt;/span&gt;
    &lt;span class="n"&gt;uow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Retrieve all users from repository&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"👤"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Email&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;h2&gt;
  
  
  🧠 Why It Matters
&lt;/h2&gt;

&lt;p&gt;This pattern combination helps ensure that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Business logic stays independent&lt;/strong&gt; from database details&lt;/li&gt;
&lt;li&gt;🧩 You can &lt;strong&gt;batch commit&lt;/strong&gt; all new entities in one transaction&lt;/li&gt;
&lt;li&gt;🧪 It becomes easier to &lt;strong&gt;test&lt;/strong&gt; or &lt;strong&gt;swap out data sources&lt;/strong&gt; later (e.g., move from in-memory to PostgreSQL)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach scales as your system grows — a foundational step for clean, maintainable enterprise applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔗 GitHub Repository
&lt;/h2&gt;

&lt;p&gt;👉 Full source code is available on GitHub:&lt;br&gt;
&lt;a href="https://github.com/yourusername/go-enterprise-patterns" rel="noopener noreferrer"&gt;https://github.com/yourusername/go-enterprise-patterns&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Enterprise patterns aren’t just academic ideas — they are &lt;strong&gt;battle-tested abstractions&lt;/strong&gt; that help teams manage complexity in real-world systems.&lt;/p&gt;

&lt;p&gt;By implementing these patterns in languages like &lt;strong&gt;Go, Rust, or Python&lt;/strong&gt;, you create software that’s &lt;strong&gt;modular, testable, and adaptable&lt;/strong&gt; to change — all core values in modern enterprise development.&lt;/p&gt;




&lt;h3&gt;
  
  
  📚 Further Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://martinfowler.com/eaaCatalog/" rel="noopener noreferrer"&gt;Martin Fowler – Patterns of Enterprise Application Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/design-patterns/repository" rel="noopener noreferrer"&gt;Refactoring Guru – Repository Pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bxcodec/go-clean-arch" rel="noopener noreferrer"&gt;Go Clean Architecture Example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;💬 &lt;em&gt;If you found this article useful, drop a ❤️ on Dev.to or follow me for more deep dives into software architecture and Go!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>designpatterns</category>
      <category>go</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Design Principles of Software: Building Better Systems</title>
      <dc:creator>Nikolás C. Meléndez</dc:creator>
      <pubDate>Sun, 14 Sep 2025 03:52:33 +0000</pubDate>
      <link>https://dev.to/cesar_nikolascamacmelen/design-principles-of-software-building-better-systems-424</link>
      <guid>https://dev.to/cesar_nikolascamacmelen/design-principles-of-software-building-better-systems-424</guid>
      <description>&lt;p&gt;Software development is more than just writing code that works. The difference between a quick hack and a robust, maintainable system lies in &lt;strong&gt;design principles&lt;/strong&gt;. These principles guide developers in writing code that is clean, scalable, and easy to maintain.&lt;/p&gt;

&lt;p&gt;In this article, we will explore some of the most important software design principles and see them in action with a real-world example using &lt;strong&gt;Python&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Design Principles Matter
&lt;/h2&gt;

&lt;p&gt;Imagine you are building a house. You could randomly place bricks and beams together until it vaguely looks like a house — but would you want to live in it? Software is similar: without good design principles, your code might "work," but it will become fragile, hard to maintain, and nearly impossible to extend.&lt;/p&gt;

&lt;p&gt;Design principles help ensure that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your code is &lt;strong&gt;readable&lt;/strong&gt; (other developers can understand it).&lt;/li&gt;
&lt;li&gt;Your code is &lt;strong&gt;maintainable&lt;/strong&gt; (bugs can be fixed easily).&lt;/li&gt;
&lt;li&gt;Your code is &lt;strong&gt;scalable&lt;/strong&gt; (new features can be added without breaking everything).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Core Design Principles
&lt;/h2&gt;

&lt;p&gt;Here are some fundamental principles you should know:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Single Responsibility Principle (SRP)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Each class, function, or module should have one reason to change. This keeps code focused and reduces unintended side effects.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Open/Closed Principle (OCP)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Software should be open for extension but closed for modification. Instead of modifying existing code, we extend it by adding new functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Liskov Substitution Principle (LSP)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Subtypes must be substitutable for their base types. In other words, objects of a derived class should be usable wherever the base class is expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Interface Segregation Principle (ISP)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Clients should not be forced to depend on interfaces they do not use.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Dependency Inversion Principle (DIP)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Depend on abstractions, not on concrete implementations. This decouples high-level logic from low-level details.&lt;/p&gt;

&lt;p&gt;These five principles together are known as &lt;strong&gt;SOLID&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Example: A Payment Processor
&lt;/h2&gt;

&lt;p&gt;Let’s imagine you are building an e-commerce system that supports multiple payment methods: credit card, PayPal, and crypto.&lt;/p&gt;

&lt;p&gt;Here’s an example in Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;abc&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;abstractmethod&lt;/span&gt;

&lt;span class="c1"&gt;# Abstraction (DIP): PaymentMethod defines a contract
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# Concrete implementations (SRP: each handles one payment type)
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreditCardPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PaymentMethod&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processing credit card payment of $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PayPalPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PaymentMethod&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processing PayPal payment of $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CryptoPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PaymentMethod&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processing crypto payment of $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# High-level module (depends on abstraction, not details)
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Checkout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payment_method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PaymentMethod&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payment_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payment_method&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payment_method&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Usage: we can easily extend with new payment types without modifying Checkout
&lt;/span&gt;&lt;span class="n"&gt;order1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Checkout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CreditCardPayment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;order1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;100.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;order2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Checkout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PayPalPayment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;order2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;50.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why This Example is Good Design:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SRP&lt;/strong&gt;: Each class has one job – handling a specific payment type.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OCP&lt;/strong&gt;: To add Apple Pay support, we just add a new class implementing &lt;code&gt;PaymentMethod&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LSP&lt;/strong&gt;: Any &lt;code&gt;PaymentMethod&lt;/code&gt; subclass can be used in &lt;code&gt;Checkout&lt;/code&gt; without breaking behavior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DIP&lt;/strong&gt;: &lt;code&gt;Checkout&lt;/code&gt; depends on &lt;code&gt;PaymentMethod&lt;/code&gt; (an abstraction), not on specific payment classes.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Benefits of Following These Principles
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility:&lt;/strong&gt; You can add new features without touching existing code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testability:&lt;/strong&gt; You can mock &lt;code&gt;PaymentMethod&lt;/code&gt; for unit tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainability:&lt;/strong&gt; You avoid tightly coupled, monolithic code.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Design principles are not just theoretical guidelines – they are practical tools for building robust systems. Applying them will make your code cleaner, easier to extend, and more resilient to change.&lt;/p&gt;

&lt;p&gt;The next time you start a project, think about these principles from the beginning. Your future self (and your teammates) will thank you.&lt;/p&gt;




&lt;p&gt;💡 &lt;strong&gt;What about you?&lt;/strong&gt; Which design principle do you find the hardest to follow in real projects? Share your thoughts in the comments!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>javascript</category>
    </item>
    <item>
      <title>🏢 Enterprise Design Patterns: From Fowler’s Catalog to Real Code</title>
      <dc:creator>Nikolás C. Meléndez</dc:creator>
      <pubDate>Fri, 12 Sep 2025 04:50:28 +0000</pubDate>
      <link>https://dev.to/cesar_nikolascamacmelen/enterprise-design-patterns-from-fowlers-catalog-to-real-code-58d8</link>
      <guid>https://dev.to/cesar_nikolascamacmelen/enterprise-design-patterns-from-fowlers-catalog-to-real-code-58d8</guid>
      <description>&lt;p&gt;Enterprise applications are some of the most &lt;strong&gt;complex and mission-critical&lt;/strong&gt; systems in software engineering. They must support &lt;strong&gt;large user bases&lt;/strong&gt;, integrate with &lt;strong&gt;databases&lt;/strong&gt;, handle &lt;strong&gt;business rules&lt;/strong&gt;, and remain &lt;strong&gt;maintainable&lt;/strong&gt; over years of evolution.&lt;/p&gt;

&lt;p&gt;To tackle these challenges, &lt;strong&gt;Martin Fowler&lt;/strong&gt; introduced the &lt;strong&gt;Catalog of Patterns of Enterprise Application Architecture (P of EAA)&lt;/strong&gt; — a curated set of reusable patterns that help developers build &lt;strong&gt;clean, scalable, and robust enterprise systems&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This article explores what these patterns are, why they matter, and shows a practical example with real code.&lt;/p&gt;




&lt;h2&gt;
  
  
  📚 What Are Enterprise Design Patterns?
&lt;/h2&gt;

&lt;p&gt;Enterprise design patterns are &lt;strong&gt;reusable solutions&lt;/strong&gt; to common problems in enterprise application development. Instead of reinventing the wheel, these patterns offer &lt;strong&gt;battle-tested designs&lt;/strong&gt; that improve:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Maintainability&lt;/strong&gt; – Clear separation of concerns&lt;br&gt;
✅ &lt;strong&gt;Testability&lt;/strong&gt; – Easier unit testing of business rules&lt;br&gt;
✅ &lt;strong&gt;Scalability&lt;/strong&gt; – Code that adapts as systems grow&lt;br&gt;
✅ &lt;strong&gt;Flexibility&lt;/strong&gt; – Swap out infrastructure (e.g., database) without rewriting core logic&lt;/p&gt;




&lt;h2&gt;
  
  
  🗂️ Fowler’s Catalog at a Glance
&lt;/h2&gt;

&lt;p&gt;Fowler organizes enterprise patterns into &lt;strong&gt;categories&lt;/strong&gt; based on the layer or problem they solve:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Example Patterns&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Domain Logic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Transaction Script, Table Module, Domain Model&lt;/td&gt;
&lt;td&gt;Organize business rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Source&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Table Data Gateway, Row Data Gateway, Data Mapper, Active Record&lt;/td&gt;
&lt;td&gt;Manage database access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Object-Relational Behavioral&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unit of Work, Lazy Load, Identity Map&lt;/td&gt;
&lt;td&gt;Optimize DB interaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Web Presentation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Front Controller, Template View, Transform View&lt;/td&gt;
&lt;td&gt;Structure web UIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Distribution&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Remote Facade, Data Transfer Object&lt;/td&gt;
&lt;td&gt;Handle remote communication&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each category complements the others, forming a &lt;strong&gt;layered architecture&lt;/strong&gt; that is easier to evolve.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Example Pattern: &lt;strong&gt;Data Mapper&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let’s dive deeper into &lt;strong&gt;Data Mapper&lt;/strong&gt;, one of the most influential patterns.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt;&lt;br&gt;
“A layer of mappers that moves data between objects and a database while keeping them independent of each other.”&lt;br&gt;
— &lt;em&gt;Martin Fowler&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Without this pattern, &lt;strong&gt;domain objects&lt;/strong&gt; might contain SQL queries — tightly coupling business rules with persistence logic. This makes the code harder to maintain, test, or change.&lt;/p&gt;




&lt;h3&gt;
  
  
  🏗️ Architecture Overview
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+-------------------+          +-------------------+
|   Domain Object   | &amp;lt;------&amp;gt; |   Data Mapper     |
| (Business Rules)  |          | (Persistence API) |
+-------------------+          +-------------------+
                                    |
                                    v
                               +-----------+
                               | Database  |
                               +-----------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Domain Object&lt;/strong&gt;: Pure business logic, no database knowledge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Mapper&lt;/strong&gt;: Knows how to fetch/save domain objects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt;: Stores raw data.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💻 Real-World Example in Python
&lt;/h2&gt;

&lt;p&gt;Imagine we are building a &lt;strong&gt;Customer Management System&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  1️⃣ Domain Model (Business Logic)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# domain.py
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Business rule: Validate before updating.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;new_email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid email format&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_email&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__repr__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;Customer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2️⃣ Data Mapper (Persistence Layer)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# data_mapper.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Customer&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomerMapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT id, name, email FROM customers WHERE id=?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INSERT INTO customers (id, name, email) VALUES (?, ?, ?)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UPDATE customers SET name=?, email=? WHERE id=?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3️⃣ Application Code (Usage)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;data_mapper&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CustomerMapper&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Customer&lt;/span&gt;

&lt;span class="c1"&gt;# Setup (for demo purposes)
&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:memory:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CREATE TABLE customers (id INTEGER, name TEXT, email TEXT)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;mapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CustomerMapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create and insert a new customer
&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alice@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Fetch and print
&lt;/span&gt;&lt;span class="n"&gt;retrieved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Retrieved:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;retrieved&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Update email and persist
&lt;/span&gt;&lt;span class="n"&gt;retrieved&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alice.new@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retrieved&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Verify update
&lt;/span&gt;&lt;span class="n"&gt;updated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Updated:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;updated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🖨️ Output
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Retrieved: &amp;lt;Customer 1: Alice, alice@example.com&amp;gt;
Updated: &amp;lt;Customer 1: Alice, alice.new@example.com&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🏆 Benefits of Using Data Mapper
&lt;/h2&gt;

&lt;p&gt;✅ &lt;strong&gt;Separation of Concerns&lt;/strong&gt; – Business rules stay in &lt;code&gt;Customer&lt;/code&gt;, persistence logic stays in &lt;code&gt;CustomerMapper&lt;/code&gt;.&lt;br&gt;
✅ &lt;strong&gt;Testability&lt;/strong&gt; – You can test the domain model without touching the database.&lt;br&gt;
✅ &lt;strong&gt;Flexibility&lt;/strong&gt; – You can replace SQLite with PostgreSQL or MySQL with minimal changes.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔑 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise Design Patterns&lt;/strong&gt; are essential for scalable, maintainable systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fowler’s Catalog&lt;/strong&gt; gives us a shared vocabulary to discuss and design enterprise architectures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Mapper&lt;/strong&gt; is a powerful way to decouple business logic from persistence concerns.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Pro Tip:&lt;/strong&gt; Many modern ORMs (like SQLAlchemy, Hibernate, Django ORM) internally implement Data Mapper — so understanding this pattern helps you use those tools more effectively.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>Building Interactive Dashboards with Streamlit, Dash, and Bokeh: From Code to Cloud</title>
      <dc:creator>Nikolás C. Meléndez</dc:creator>
      <pubDate>Thu, 11 Sep 2025 23:12:12 +0000</pubDate>
      <link>https://dev.to/cesar_nikolascamacmelen/building-interactive-dashboards-with-streamlit-dash-and-bokeh-from-code-to-cloud-5hdb</link>
      <guid>https://dev.to/cesar_nikolascamacmelen/building-interactive-dashboards-with-streamlit-dash-and-bokeh-from-code-to-cloud-5hdb</guid>
      <description>&lt;p&gt;Data visualization plays a central role in computer science and data-driven decision making. While libraries like &lt;strong&gt;Matplotlib&lt;/strong&gt; and &lt;strong&gt;Seaborn&lt;/strong&gt; are often the first tools learned, more interactive frameworks exist to build dashboards and reports for real-world applications. Among them, &lt;strong&gt;Streamlit&lt;/strong&gt;, &lt;strong&gt;Dash&lt;/strong&gt;, and &lt;strong&gt;Bokeh&lt;/strong&gt; stand out because they allow developers to turn Python code into full web applications without requiring advanced web development skills.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Streamlit
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Streamlit&lt;/strong&gt; is one of the simplest ways to build interactive dashboards. It allows developers to use pure Python code and automatically creates a responsive web interface. You can add widgets (sliders, checkboxes, text inputs) with minimal syntax, making it an ideal tool for rapid prototyping.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Dash
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Dash&lt;/strong&gt;, developed by Plotly, is more powerful and customizable. It combines Flask (for backend), React.js (for frontend), and Plotly (for charts). Dash applications are more structured and allow you to build enterprise-level dashboards with callbacks and layouts.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Bokeh
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bokeh&lt;/strong&gt; is a library designed for creating interactive and scalable visualizations in the browser. Unlike Streamlit or Dash, Bokeh focuses mainly on visualizations, but it can also serve as a backend for dashboards.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example: Building and Deploying a Dashboard with Streamlit
&lt;/h2&gt;

&lt;p&gt;Below is a small example using &lt;strong&gt;Streamlit&lt;/strong&gt; to visualize a dataset of random values. We’ll then deploy it to &lt;strong&gt;Streamlit Cloud&lt;/strong&gt; (free tier for students).&lt;/p&gt;

&lt;h3&gt;
  
  
  Code (&lt;code&gt;app.py&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;streamlit&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;

&lt;span class="c1"&gt;# Title
&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;📊 Interactive Data Dashboard Example&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Sidebar options
&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Controls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;n_points&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Number of Data Points&lt;/span&gt;&lt;span class="sh"&gt;"&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="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chart_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;selectbox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Chart Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Line&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Scatter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Histogram&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# Generate random data
&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n_points&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;y&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n_points&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;cumsum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;# Show dataframe
&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;### Randomly Generated Data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="c1"&gt;# Visualization
&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;### Visualization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;chart_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Line&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;line_chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;chart_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Scatter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scatter_chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;chart_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Histogram&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subplots&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;y&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;bins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;skyblue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edgecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;black&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pyplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running Locally
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;streamlit pandas numpy matplotlib
streamlit run app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visit: &lt;code&gt;http://localhost:8501&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Deployment to the Cloud (Streamlit Cloud Example)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Push your code to &lt;strong&gt;GitHub&lt;/strong&gt; (repository with &lt;code&gt;app.py&lt;/code&gt; and &lt;code&gt;requirements.txt&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Example &lt;code&gt;requirements.txt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; streamlit
 pandas
 numpy
 matplotlib
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to &lt;a href="https://streamlit.io/cloud" rel="noopener noreferrer"&gt;https://streamlit.io/cloud&lt;/a&gt; and log in with GitHub.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;“New App”&lt;/strong&gt;, select your repository and branch, and choose &lt;code&gt;app.py&lt;/code&gt; as the entry file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deploy — in a few seconds, your app will be live with a public URL like:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   https://your-username-your-repo.streamlit.app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why Use These Tools?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Streamlit&lt;/strong&gt; → quick, simple dashboards (ideal for students, prototypes).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dash&lt;/strong&gt; → structured, production-ready dashboards (enterprise use).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bokeh&lt;/strong&gt; → powerful interactive plots with flexibility.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Streamlit, Dash, and Bokeh expand the possibilities of data visualization beyond static plots. They enable computer science students and professionals to share insights interactively and even deploy them as web apps. Deploying to cloud platforms like &lt;strong&gt;Streamlit Cloud&lt;/strong&gt;, &lt;strong&gt;Heroku&lt;/strong&gt;, or &lt;strong&gt;AWS&lt;/strong&gt; makes these tools accessible from anywhere, turning local experiments into shareable projects.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>datascience</category>
      <category>python</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🧪 Testing Management Tools Comparative Guide</title>
      <dc:creator>Nikolás C. Meléndez</dc:creator>
      <pubDate>Thu, 03 Jul 2025 22:18:28 +0000</pubDate>
      <link>https://dev.to/cesar_nikolascamacmelen/testing-management-tools-comparative-guide-4f8k</link>
      <guid>https://dev.to/cesar_nikolascamacmelen/testing-management-tools-comparative-guide-4f8k</guid>
      <description>&lt;p&gt;Managing automated testing efficiently is critical in modern software development. In this article, we compare popular testing management and CI/CD tools using real-world examples and open-source code repositories. The tools discussed include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitLab Pipelines&lt;/li&gt;
&lt;li&gt;GitHub Actions&lt;/li&gt;
&lt;li&gt;Jenkins&lt;/li&gt;
&lt;li&gt;CircleCI&lt;/li&gt;
&lt;li&gt;TeamCity&lt;/li&gt;
&lt;li&gt;Travis CI&lt;/li&gt;
&lt;li&gt;Bitbucket Pipelines&lt;/li&gt;
&lt;li&gt;Tekton&lt;/li&gt;
&lt;li&gt;Harness&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔧 1. GitLab Pipelines
&lt;/h2&gt;

&lt;p&gt;GitLab offers a powerful CI/CD pipeline tool built into its platform. It supports YAML-based configuration and tight integration with Git repositories.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Real-World Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://gitlab.com/gitlab-examples/ci-project" rel="noopener noreferrer"&gt;GitLab CI Demo&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Config Snippet:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;

&lt;span class="na"&gt;test_job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Running tests"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pytest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔧 2. GitHub Actions
&lt;/h2&gt;

&lt;p&gt;GitHub Actions enables workflow automation directly in your GitHub repository. It's highly flexible and widely adopted.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Real-World Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/actions/starter-workflows" rel="noopener noreferrer"&gt;Actions Demo&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Config Snippet:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Tests&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Tests&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔧 3. Jenkins
&lt;/h2&gt;

&lt;p&gt;Jenkins is one of the most popular open-source automation servers. It supports hundreds of plugins and is highly customizable.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Real-World Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/jenkins-docs/simple-java-maven-app" rel="noopener noreferrer"&gt;Jenkins Pipeline Example&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Config Snippet (Jenkinsfile):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;
    &lt;span class="n"&gt;stages&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Test'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'mvn test'&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔧 4. CircleCI
&lt;/h2&gt;

&lt;p&gt;CircleCI offers performance-focused CI/CD services with support for Docker, caching, and parallelism.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Real-World Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/CircleCI-Public/circleci-demo-javascript-express" rel="noopener noreferrer"&gt;CircleCI Demo&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Config Snippet:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.1&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cimg/node:14.17&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔧 5. TeamCity
&lt;/h2&gt;

&lt;p&gt;TeamCity by JetBrains is a robust CI/CD server suitable for enterprise environments with visual build pipelines.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Real-World Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/JetBrains/teamcity-config-examples" rel="noopener noreferrer"&gt;TeamCity Configuration Demo&lt;/a&gt;&lt;br&gt;
(&lt;em&gt;Example includes Kotlin DSL for pipeline configuration.&lt;/em&gt;)&lt;/p&gt;


&lt;h2&gt;
  
  
  🔧 6. Travis CI
&lt;/h2&gt;

&lt;p&gt;Travis CI is known for its simplicity and integration with GitHub.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✅ Real-World Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/travis-ci/travis-ci" rel="noopener noreferrer"&gt;Travis CI Example&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Config Snippet:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node_js&lt;/span&gt;
&lt;span class="na"&gt;node_js&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;16"&lt;/span&gt;
&lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔧 7. Bitbucket Pipelines
&lt;/h2&gt;

&lt;p&gt;Bitbucket Pipelines offers integrated CI/CD for Bitbucket repositories, using YAML configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Real-World Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://bitbucket.org/atlassianlabs/pipeline-examples/src/master/" rel="noopener noreferrer"&gt;Bitbucket Pipeline Examples&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Config Snippet:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;pipelines&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Tests&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node:14&lt;/span&gt;
        &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔧 8. Tekton
&lt;/h2&gt;

&lt;p&gt;Tekton is a Kubernetes-native CI/CD framework designed for flexibility and scalability.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Real-World Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/tektoncd/pipeline" rel="noopener noreferrer"&gt;Tekton Example Pipelines&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Pipeline Snippet:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tekton.dev/v1beta1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Task&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test-task&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;run-tests&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node:14&lt;/span&gt;
      &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;npm install&lt;/span&gt;
        &lt;span class="s"&gt;npm test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔧 9. Harness
&lt;/h2&gt;

&lt;p&gt;Harness is a modern CI/CD platform with built-in machine learning for deployment verification.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Real-World Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/harness-community/pipeline-samples" rel="noopener noreferrer"&gt;Harness CD Sample&lt;/a&gt;&lt;br&gt;
(Requires Harness account to run fully.)&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Summary Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;YAML Support&lt;/th&gt;
&lt;th&gt;Docker Support&lt;/th&gt;
&lt;th&gt;Cloud-native&lt;/th&gt;
&lt;th&gt;Git Integration&lt;/th&gt;
&lt;th&gt;UI Friendly&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitLab Pipelines&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;GitLab&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;GitHub&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jenkins&lt;/td&gt;
&lt;td&gt;❌ (Groovy)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Any&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CircleCI&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;GitHub, Bitbucket&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TeamCity&lt;/td&gt;
&lt;td&gt;✅ (Kotlin DSL)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Any&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Travis CI&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;GitHub&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bitbucket Pipelines&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Bitbucket&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tekton&lt;/td&gt;
&lt;td&gt;✅ (K8s YAML)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Any&lt;/td&gt;
&lt;td&gt;❌ (CLI/K8s)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Harness&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Any&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;p&gt;Each testing management tool has its strengths. Choose based on your project size, team skill set, and integration preferences. For open-source simplicity, GitHub Actions or GitLab CI are excellent choices. For enterprise-scale orchestration, Harness or Tekton may provide advanced flexibility.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Applying API Testing Frameworks: Real-World Examples with Code</title>
      <dc:creator>Nikolás C. Meléndez</dc:creator>
      <pubDate>Thu, 05 Jun 2025 03:34:14 +0000</pubDate>
      <link>https://dev.to/cesar_nikolascamacmelen/applying-api-testing-frameworks-real-world-examples-with-code-40pi</link>
      <guid>https://dev.to/cesar_nikolascamacmelen/applying-api-testing-frameworks-real-world-examples-with-code-40pi</guid>
      <description>&lt;p&gt;API testing is a critical component of modern software development, ensuring that your application programming interfaces (APIs) function correctly, perform well, and remain secure. In this article, we'll explore practical implementations of popular API testing frameworks with real-world code examples, inspired by insights from &lt;a href="https://medium.com/@alicealdaine/top-10-api-testing-tools-rest-soap-services-5395cb03cfa9" rel="noopener noreferrer"&gt;Top 10 API Testing Tools for REST &amp;amp; SOAP Services&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Postman (Collection Runner + Newman)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use Case&lt;/strong&gt;: Testing a RESTful e-commerce API&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;// postman_test_example.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newman&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;newman&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;newman&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./ecommerce-api-tests.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;reporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cli&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;iterationCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nf"&gt;function &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;if &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;throw&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Postman collection run complete!&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="c1"&gt;// Example test in Postman collection&lt;/span&gt;
&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Status code is 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&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 time is less than 200ms&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseTime&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;below&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Product has valid structure&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsonData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;price&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&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;&lt;strong&gt;Real-world application&lt;/strong&gt;: Run regression tests in CI/CD pipeline using Newman (Postman's CLI tool)&lt;/p&gt;

&lt;h2&gt;
  
  
  2. RestAssured (Java)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use Case&lt;/strong&gt;: Testing a banking API with authentication&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BankingAPITest.java&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.restassured.RestAssured&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.restassured.response.Response&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;restassured&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RestAssured&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;given&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hamcrest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Matchers&lt;/span&gt;&lt;span class="o"&gt;.*;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BankingAPITest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testAccountBalanceEndpoint&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;RestAssured&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;baseURI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://api.bank.example.com"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;given&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;oauth2&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"valid-access-token"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pathParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"accountId"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"12345"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/accounts/{accountId}/balance"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;then&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"accountId"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;equalTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"12345"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"balance"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="o"&gt;())))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"currency"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;equalTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"USD"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;time&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lessThan&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000L&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testTransactionHistory&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;given&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;basic&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;queryParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"from"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2023-01-01"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;queryParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"to"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2023-12-31"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/transactions"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;then&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"transactions"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hasSize&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;greaterThan&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"transactions[0].amount"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notNullValue&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Real-world application&lt;/strong&gt;: Comprehensive testing of financial APIs with complex authentication requirements&lt;/p&gt;

&lt;h2&gt;
  
  
  3. PyTest with Requests (Python)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use Case&lt;/strong&gt;: Testing a weather API with parameterized tests&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# test_weather_api.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pytest&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.weather.example.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nd"&gt;@pytest.mark.parametrize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;city,country,expected_status&lt;/span&gt;&lt;span class="sh"&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;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;London&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;New York&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid City&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;XX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_get_weather_by_city&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected_status&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/weather&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;city&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;country&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer test-api-key&lt;/span&gt;&lt;span class="sh"&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;assert&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expected_status&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;expected_status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;humidity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;conditions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@pytest.fixture&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;auth_token&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Get auth token once for multiple tests
&lt;/span&gt;    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/auth&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;testuser&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;password&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;testpass&lt;/span&gt;&lt;span class="sh"&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="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_forecast_endpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth_token&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/forecast&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;days&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;auth_token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&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;assert&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
    &lt;span class="n"&gt;forecast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forecast&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;forecast&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Real-world application&lt;/strong&gt;: Data-driven testing of weather API with different locations and authentication scenarios&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Karate DSL (BDD Style)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use Case&lt;/strong&gt;: Testing a microservices architecture with complex workflows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# user_management.feature
Feature: User Management API Tests

Background:
  * url 'https://api.users.example.com'
  * header Authorization = 'Bearer ' + token
  * def token = call read('get_token.js') { username: 'admin', password: 'admin123' }

Scenario: Create and verify new user
  Given path '/users'
  And request { name: 'Test User', email: 'test.user@example.com', role: 'member' }
  When method post
  Then status 201
  And match response == { id: '#number', name: 'Test User', email: 'test.user@example.com', role: 'member' }

  * def userId = response.id

  Given path '/users/' + userId
  When method get
  Then status 200
  And match response contains { id: '#number', name: 'Test User' }

Scenario: Test user search with parameters
  Given path '/users/search'
  And param role = 'admin'
  When method get
  Then status 200
  And match each response.users contains { role: 'admin' }
  And assert response.users.length &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Real-world application&lt;/strong&gt;: Testing complex user flows in microservices with readable BDD syntax&lt;/p&gt;

&lt;h2&gt;
  
  
  5. SoapUI (SOAP Service Testing)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use Case&lt;/strong&gt;: Testing a legacy SOAP-based inventory system&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- inventory_check.xml --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;soapenv:Envelope&lt;/span&gt; &lt;span class="na"&gt;xmlns:soapenv=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.xmlsoap.org/soap/envelope/"&lt;/span&gt; 
                 &lt;span class="na"&gt;xmlns:inv=&lt;/span&gt;&lt;span class="s"&gt;"http://www.example.com/inventory"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;soapenv:Header/&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;soapenv:Body&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;inv:CheckInventoryRequest&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;inv:productId&amp;gt;&lt;/span&gt;1001&lt;span class="nt"&gt;&amp;lt;/inv:productId&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;inv:warehouse&amp;gt;&lt;/span&gt;NYC&lt;span class="nt"&gt;&amp;lt;/inv:warehouse&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/inv:CheckInventoryRequest&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/soapenv:Body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/soapenv:Envelope&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Groovy Script Assertion in SoapUI&lt;/span&gt;
&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;groovyUtils&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;eviware&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;soapui&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;support&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GroovyUtils&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;holder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;groovyUtils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getXmlHolder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"CheckInventoryRequest#Response"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;availableQty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;holder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getNodeValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"//*:availableQuantity"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;holder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getNodeValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"//*:status"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;availableQty&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toInteger&lt;/span&gt;&lt;span class="o"&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="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"IN_STOCK"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"OUT_OF_STOCK"&lt;/span&gt;

&lt;span class="c1"&gt;// Performance check&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;responseTime&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Real-world application&lt;/strong&gt;: Maintaining and testing legacy SOAP services with complex XML payloads&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices for API Testing Frameworks
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Environment Management&lt;/strong&gt;: Use config files to manage different environments
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="c1"&gt;// config.js&lt;/span&gt;
   &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;dev&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://dev.api.example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dev-key-123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
     &lt;span class="p"&gt;},&lt;/span&gt;
     &lt;span class="na"&gt;staging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://staging.api.example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;staging-key-456&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
     &lt;span class="p"&gt;},&lt;/span&gt;
     &lt;span class="na"&gt;prod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PROD_API_KEY&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;ol&gt;
&lt;li&gt;
&lt;strong&gt;Test Data Management&lt;/strong&gt;: Generate test data dynamically
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;   &lt;span class="c1"&gt;# test_data.py
&lt;/span&gt;   &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;faker&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Faker&lt;/span&gt;

   &lt;span class="n"&gt;fake&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Faker&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_user_data&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
           &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
           &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;address&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
           &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;phone&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;phone_number&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;ol&gt;
&lt;li&gt;
&lt;strong&gt;Reporting&lt;/strong&gt;: Generate comprehensive test reports
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;   &lt;span class="c1"&gt;// RestAssured with ExtentReports&lt;/span&gt;
   &lt;span class="nd"&gt;@AfterSuite&lt;/span&gt;
   &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;tearDown&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
       &lt;span class="nc"&gt;ExtentReports&lt;/span&gt; &lt;span class="n"&gt;extent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ExtentReports&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
       &lt;span class="nc"&gt;ExtentSparkReporter&lt;/span&gt; &lt;span class="n"&gt;spark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ExtentSparkReporter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"target/Spark.html"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
       &lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;attachReporter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;spark&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
       &lt;span class="n"&gt;extent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flush&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
   &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Performance Checks&lt;/strong&gt;: Always include performance assertions
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="c1"&gt;// Postman&lt;/span&gt;
   &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&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 time is acceptable&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseTime&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;below&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;300&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;ol&gt;
&lt;li&gt;
&lt;strong&gt;Security Testing&lt;/strong&gt;: Include basic security checks
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;   &lt;span class="c1"&gt;# pytest
&lt;/span&gt;   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_secure_headers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
       &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;X-Content-Type-Options&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;
       &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;X-Frame-Options&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DENY&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
       &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Content-Security-Policy&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Choosing the right API testing framework depends on your tech stack, team skills, and API complexity. Postman is excellent for collaborative manual testing, RestAssured integrates well with Java ecosystems, PyTest offers Python simplicity, Karate provides BDD readability, and SoapUI handles SOAP services effectively.&lt;/p&gt;

&lt;p&gt;By implementing these real-world examples and following best practices, you can build a robust API testing strategy that catches bugs early, ensures performance standards, and maintains API reliability throughout your development lifecycle.&lt;/p&gt;

&lt;p&gt;Remember to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test for both happy paths and error cases&lt;/li&gt;
&lt;li&gt;Validate response schemas&lt;/li&gt;
&lt;li&gt;Include performance assertions&lt;/li&gt;
&lt;li&gt;Test security aspects&lt;/li&gt;
&lt;li&gt;Automate in your CI/CD pipeline&lt;/li&gt;
&lt;li&gt;Maintain your tests as your API evolves&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
