<?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: Daleska</title>
    <description>The latest articles on DEV Community by Daleska (@paltadash).</description>
    <link>https://dev.to/paltadash</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%2F1432543%2F76a30739-6ace-4cfe-aa20-73417fb312ee.png</url>
      <title>DEV Community: Daleska</title>
      <link>https://dev.to/paltadash</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/paltadash"/>
    <language>en</language>
    <item>
      <title>🛰️ Observability Practices with Prometheus and Grafana Monitoring a Node.js API</title>
      <dc:creator>Daleska</dc:creator>
      <pubDate>Sat, 05 Jul 2025 20:05:34 +0000</pubDate>
      <link>https://dev.to/paltadash/observability-practices-with-prometheus-and-grafana-monitoring-a-nodejs-api-33b3</link>
      <guid>https://dev.to/paltadash/observability-practices-with-prometheus-and-grafana-monitoring-a-nodejs-api-33b3</guid>
      <description>&lt;h2&gt;
  
  
  📌 Introduction
&lt;/h2&gt;

&lt;p&gt;In today's cloud-native and microservices-based systems, observability has become a critical component for ensuring system health and performance. While traditional monitoring focuses on known failure scenarios, &lt;strong&gt;observability empowers teams to explore the unknown&lt;/strong&gt; by collecting telemetry data like &lt;strong&gt;metrics&lt;/strong&gt;, &lt;strong&gt;logs&lt;/strong&gt;, and &lt;strong&gt;traces&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This article walks through a real-world implementation of observability using &lt;strong&gt;Prometheus&lt;/strong&gt; and &lt;strong&gt;Grafana&lt;/strong&gt; to monitor a simple &lt;strong&gt;Node.js API&lt;/strong&gt;. We'll explore how to instrument the application, export metrics, collect them with Prometheus, and visualize them in Grafana.&lt;/p&gt;

&lt;p&gt;By the end of this guide, you will have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A running Node.js REST API that exposes useful metrics&lt;/li&gt;
&lt;li&gt;Prometheus configured to scrape those metrics&lt;/li&gt;
&lt;li&gt;Grafana visualizing system behavior in real time&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 What is Observability?
&lt;/h2&gt;

&lt;p&gt;Observability answers the question: &lt;strong&gt;“What’s going on inside my system?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It relies on three fundamental pillars:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pillar&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;Metrics&lt;/td&gt;
&lt;td&gt;Numeric representation of data over time (e.g., CPU usage)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logs&lt;/td&gt;
&lt;td&gt;Text records of events (e.g., errors, requests)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Traces&lt;/td&gt;
&lt;td&gt;Track request flow across distributed services&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Unlike basic uptime monitoring, observability helps answer &lt;strong&gt;why&lt;/strong&gt; something is wrong, not just &lt;strong&gt;what&lt;/strong&gt; is wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧰 Tools and Technologies Used
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js + Express&lt;/strong&gt;: Lightweight web server to simulate an API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;prom-client&lt;/strong&gt;: Prometheus client library for Node.js&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prometheus&lt;/strong&gt;: Time-series database that scrapes and stores metrics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grafana&lt;/strong&gt;: Visualization tool for dashboards and alerts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker + Docker Compose&lt;/strong&gt;: To containerize and orchestrate services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: For source code versioning and sharing&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ System Architecture
&lt;/h2&gt;

&lt;p&gt;User&lt;br&gt;
|&lt;br&gt;
v&lt;br&gt;
Node.js API (Express)&lt;br&gt;
|&lt;br&gt;
└── /metrics (prom-client)&lt;br&gt;
|&lt;br&gt;
Prometheus&lt;br&gt;
|&lt;br&gt;
Grafana&lt;/p&gt;


&lt;h2&gt;
  
  
  🛠️ Step-by-Step Implementation
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1️⃣ Setting up the Node.js API
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1.1 Install dependencies
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
npm install express prom-client

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

&lt;/div&gt;

&lt;h3&gt;
  
  
  1.2 API Code (index.js)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const client = require('prom-client');
const app = express();

// Enable collection of default metrics like memory usage, CPU, etc.
client.collectDefaultMetrics();

const httpRequestDurationMicroseconds = new client.Histogram({
  name: 'http_request_duration_ms',
  help: 'Duration of HTTP requests in ms',
  labelNames: ['method', 'route', 'code'],
  buckets: [50, 100, 300, 500, 750, 1000, 2000]
});

app.use((req, res, next) =&amp;gt; {
  const start = Date.now();
  res.on('finish', () =&amp;gt; {
    const duration = Date.now() - start;
    httpRequestDurationMicroseconds
      .labels(req.method, req.route?.path || req.path, res.statusCode)
      .observe(duration);
  });
  next();
});

app.get('/hello', (req, res) =&amp;gt; {
  res.send('Hello, observability world!');
});

app.get('/metrics', async (req, res) =&amp;gt; {
  res.set('Content-Type', client.register.contentType);
  res.end(await client.register.metrics());
});

app.listen(3000, () =&amp;gt; {
  console.log('Server listening on http://localhost:3000');
});

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

&lt;/div&gt;

&lt;h3&gt;
  
  
  2️⃣ Prometheus Configuration
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1.1 Create a file named prometheus.yml:
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;global:
  scrape_interval: 5s

scrape_configs:
  - job_name: 'nodeapp'
    static_configs:
      - targets: ['nodeapp:3000']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Prometheus will now scrape metrics from /metrics every 5 seconds.&lt;/p&gt;
&lt;h3&gt;
  
  
  3️⃣ Dockerizing Everything
&lt;/h3&gt;

&lt;p&gt;Dockerfile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:18
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "index.js"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;docker-compose.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.8'

services:
  nodeapp:
    build: .
    ports:
      - "3000:3000"

  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"

  grafana:
    image: grafana/grafana
    ports:
      - "3001:3000"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4️⃣ Running the Project
&lt;/h3&gt;

&lt;p&gt;Start everything with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose up --build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, go to:&lt;/p&gt;

&lt;p&gt;`&lt;a href="http://localhost:3000/hello" rel="noopener noreferrer"&gt;http://localhost:3000/hello&lt;/a&gt; → API endpoint&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:3000/metrics" rel="noopener noreferrer"&gt;http://localhost:3000/metrics&lt;/a&gt; → Raw Prometheus metrics&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:9090" rel="noopener noreferrer"&gt;http://localhost:9090&lt;/a&gt; → Prometheus dashboard&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:3001" rel="noopener noreferrer"&gt;http://localhost:3001&lt;/a&gt; → Grafana (login: admin/admin)`&lt;/p&gt;

&lt;h2&gt;
  
  
  You can find the full source code and instructions here:
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;a href="https://github.com/Daleskadf/Observability-Practices-with-Prometheus-and-Grafana-" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Automated CI/CD with GitHub Actions: From Testing to Production Deployment</title>
      <dc:creator>Daleska</dc:creator>
      <pubDate>Sat, 05 Jul 2025 04:18:58 +0000</pubDate>
      <link>https://dev.to/paltadash/complete-automation-with-github-actions-from-testing-to-automatic-deployment-495h</link>
      <guid>https://dev.to/paltadash/complete-automation-with-github-actions-from-testing-to-automatic-deployment-495h</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In modern software engineering practices, the integration and deployment of code is as important as writing the code itself. Continuous Integration (CI) and Continuous Deployment (CD) are essential methodologies for ensuring that changes in code are tested, integrated, and deployed in an automated and efficient manner. GitHub Actions is a powerful tool for automating these workflows directly within GitHub repositories, facilitating both the execution of automated tests and the deployment of applications to production environments.&lt;/p&gt;

&lt;p&gt;In this article, we will explore how to set up a comprehensive CI/CD pipeline using GitHub Actions. Specifically, we will demonstrate how to automate the process of running tests whenever changes are pushed to the repository, and how to automatically deploy the application to a production environment such as Heroku, upon successful completion of the tests.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Prerequisites&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before starting with the configuration, ensure you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A project with automated tests set up (we’ll be using Node.js and Jest in this case).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A repository on GitHub.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Access to a production server or cloud service, such as Heroku.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Setting Up the CI/CD Workflow with GitHub Actions&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Create the GitHub Actions Configuration File&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;GitHub Actions uses YAML configuration files to define workflows. These workflows specify the various jobs and steps that GitHub will execute automatically upon certain triggers (e.g., pushing code to the repository).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a directory .github/workflows in the root of your repository if it does not already exist.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inside this folder, create a file named ci-cd.yml. This file will define the CI/CD pipeline.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here’s an example configuration for automating tests and deploying the application to Heroku:&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;CI/CD Pipeline&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;  &lt;span class="c1"&gt;# Triggers the workflow when there is a push to the main branch&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Job to run the tests&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="c1"&gt;# Specifies the environment (Ubuntu latest version)&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;Checkout code&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@v2&lt;/span&gt;  &lt;span class="c1"&gt;# Checks out the repository code&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;Set up Node.js&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/setup-node@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;14'&lt;/span&gt;  &lt;span class="c1"&gt;# Specifies the Node.js version for the environment&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="c1"&gt;# Installs the project dependencies&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;span class="c1"&gt;# Runs the tests using npm&lt;/span&gt;

  &lt;span class="c1"&gt;# Job to deploy the app to production (only if tests pass)&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;  &lt;span class="c1"&gt;# Ensures that the deploy job runs only if the test job is successful&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&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@v2&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;Set up Heroku credentials&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;akshatshah/heroku-action@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;heroku_api_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.HEROKU_API_KEY }}&lt;/span&gt;  &lt;span class="c1"&gt;# Using GitHub Secrets for Heroku API key&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;Deploy to Heroku&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;git remote add heroku https://git.heroku.com/your-app.git&lt;/span&gt;
          &lt;span class="s"&gt;git push heroku main  # Deploys the application to Heroku.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Explanation of the Workflow:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;on.push.branches:&lt;/strong&gt; This section defines the event that triggers the workflow. Here, it is configured to run whenever code is pushed to the main branch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;jobs.test:&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This job will run on Ubuntu.&lt;/p&gt;

&lt;p&gt;It consists of several steps:&lt;/p&gt;

&lt;p&gt;Checkout code: This step pulls the latest code from the repository.&lt;/p&gt;

&lt;p&gt;Set up Node.js: Ensures that the correct version of Node.js is available for the application.&lt;/p&gt;

&lt;p&gt;Install dependencies: Installs all the necessary dependencies listed in your package.json.&lt;/p&gt;

&lt;p&gt;Run tests: Executes the tests using npm test.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;jobs.deploy:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This job is set to run only after the test job is successful (needs: test).&lt;/p&gt;

&lt;p&gt;It deploys the application to Heroku using a stored API key in GitHub Secrets. This makes the deployment secure.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;2. Configuring Tests with Jest&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To automate the testing process, we need to configure a testing framework. In this tutorial, we will use Jest, a popular testing framework for JavaScript applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Install Jest as a Development Dependency:&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev jest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a simple test file in the &lt;strong&gt;tests&lt;/strong&gt; folder:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// __tests__/app.test.js
test('sumar 2 + 2', () =&amp;gt; {
  expect(2 + 2).toBe(4);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Make sure your package.json has a test script:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`"scripts": {
  "test": "jest"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3. Create GitHub Secrets&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To connect GitHub Actions to your production server (for example, Heroku), you need to configure credentials in GitHub Secrets.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to your GitHub repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the top menu, click Settings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the left sidebar, select Secrets and variables &amp;gt; Actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new secret with the name HEROKU_API_KEY and paste your Heroku API key as the value.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Verify the Workflow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Once everything is configured, make a "push" to your repository and verify that the workflow runs automatically. You can do this in the Actions tab of your repository on GitHub. If everything is set up correctly, GitHub Actions will run the tests, and if they pass, it will deploy the application to production.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;GitHub Actions is an incredibly powerful tool for automating your CI/CD workflows. In this article, we’ve configured a workflow that not only runs tests automatically but also deploys our application to a production environment using Heroku, all from within GitHub.&lt;/p&gt;

&lt;p&gt;This example is just a starting point. GitHub Actions has many more features, such as integrating other CI/CD services, generating documentation, or even notifying your team automatically about the status of tests and deployments.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example Repository&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here’s the link to my example repository on GitHub where you can see the full code and configuration of this workflow:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Daleskadf/Example-CI-CD-with-GitHub-Actions" rel="noopener noreferrer"&gt;GitHub Repository - Example CI/CD with GitHub Actions&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>KICS: A Developer-Friendly SAST Tool for Securing Infrastructure as Code</title>
      <dc:creator>Daleska</dc:creator>
      <pubDate>Wed, 30 Apr 2025 05:08:13 +0000</pubDate>
      <link>https://dev.to/paltadash/kics-a-developer-friendly-sast-tool-for-securing-infrastructure-as-code-2koa</link>
      <guid>https://dev.to/paltadash/kics-a-developer-friendly-sast-tool-for-securing-infrastructure-as-code-2koa</guid>
      <description>&lt;p&gt;In the cloud-native era, where speed, scalability, and automation dominate, Infrastructure as Code (IaC) has emerged as a critical practice for DevOps and platform engineering teams. Tools like &lt;strong&gt;Terraform&lt;/strong&gt;, &lt;strong&gt;Pulumi&lt;/strong&gt;, and &lt;strong&gt;OpenTofu&lt;/strong&gt; allow infrastructure to be defined, versioned, and deployed with the same rigor as application code.&lt;/p&gt;

&lt;p&gt;But just like any other code, infrastructure code is prone to &lt;strong&gt;security misconfigurations, errors, and vulnerabilities&lt;/strong&gt;. A single misconfigured security group or publicly accessible storage bucket can result in devastating data breaches. This is where &lt;strong&gt;SAST tools for IaC&lt;/strong&gt; play a vital role.&lt;/p&gt;

&lt;p&gt;Among the many open-source tools available, &lt;strong&gt;KICS (Keeping Infrastructure as Code Secure)&lt;/strong&gt; stands out for its &lt;strong&gt;breadth of support&lt;/strong&gt;, &lt;strong&gt;ease of use&lt;/strong&gt;, and &lt;strong&gt;community-driven rules engine&lt;/strong&gt;. In this article, we’ll explore what KICS is, how it works, and how it can be applied to a real-world IaC project to prevent security issues &lt;em&gt;before deployment&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 What is KICS?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Checkmarx/kics" rel="noopener noreferrer"&gt;KICS&lt;/a&gt; is an open-source static code analysis tool developed by &lt;strong&gt;Checkmarx&lt;/strong&gt; for scanning IaC files and detecting security vulnerabilities and misconfigurations. It performs &lt;strong&gt;static analysis&lt;/strong&gt;, meaning it analyzes code without executing it. This makes it fast, safe, and ideal for early development stages.&lt;/p&gt;

&lt;p&gt;Supported technologies include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Terraform&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Pulumi&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;CloudFormation&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Kubernetes&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Ansible&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Dockerfile&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Azure ARM Templates&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With over &lt;strong&gt;1,500+ pre-built security queries&lt;/strong&gt;, KICS checks for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open ports to the public internet&lt;/li&gt;
&lt;li&gt;Unencrypted storage&lt;/li&gt;
&lt;li&gt;Hardcoded secrets&lt;/li&gt;
&lt;li&gt;Privilege escalation risks&lt;/li&gt;
&lt;li&gt;Misconfigured IAM policies&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ How KICS Works
&lt;/h2&gt;

&lt;p&gt;KICS scans your infrastructure code and compares it to a database of misconfiguration rules written in YAML or JSON. Each finding includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔎 Description of the vulnerability&lt;/li&gt;
&lt;li&gt;🔒 Security context (CIS Benchmarks, etc.)&lt;/li&gt;
&lt;li&gt;📍 File name and line number&lt;/li&gt;
&lt;li&gt;🛠️ Suggested remediation&lt;/li&gt;
&lt;li&gt;⚠️ Severity (Low, Medium, High, Critical)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It runs via:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker (&lt;code&gt;checkmarx/kics&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;CLI (&lt;code&gt;kics scan -p ./path&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;GitHub Actions / GitLab / Jenkins&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚧 Example: Terraform Scan
&lt;/h2&gt;

&lt;p&gt;Here's a common misconfiguration in Terraform:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_security_group"&lt;/span&gt; &lt;span class="s2"&gt;"open_sg"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"open-sg"&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow SSH from all"&lt;/span&gt;
  &lt;span class="nx"&gt;ingress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;
    &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
    &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run KICS:&lt;br&gt;
&lt;code&gt;docker run -v $(pwd):/path checkmarx/kics:latest scan -p /path&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;code&gt;[CRITICAL] aws_security_group.open_sg allows 0.0.0.0/0 for SSH&lt;br&gt;
Remediation: Restrict to known IPs only.&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;CI/CD Integration Example (GitHub Actions)&lt;br&gt;
`name: KICS Scan&lt;/p&gt;

&lt;p&gt;on:&lt;br&gt;
  push:&lt;br&gt;
    branches:&lt;br&gt;
      - main&lt;/p&gt;

&lt;p&gt;jobs:&lt;br&gt;
  kics-scan:&lt;br&gt;
    runs-on: ubuntu-latest&lt;br&gt;
    steps:&lt;br&gt;
    - uses: actions/checkout@v2&lt;br&gt;
    - name: Run KICS Scan&lt;br&gt;
      uses: checkmarx/kics-action@v1&lt;br&gt;
      with:&lt;br&gt;
        path: './'&lt;br&gt;
`&lt;/p&gt;

&lt;h2&gt;
  
  
  📊 Reporting Formats
&lt;/h2&gt;

&lt;p&gt;KICS supports:&lt;/p&gt;

&lt;p&gt;JSON: for automation&lt;/p&gt;

&lt;p&gt;HTML: for humans&lt;/p&gt;

&lt;p&gt;SARIF: for GitHub Advanced Security&lt;/p&gt;

&lt;p&gt;Export to your security dashboards or ticket systems easily.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ TL;DR:
&lt;/h2&gt;

&lt;p&gt;KICS scans your IaC code (Terraform, Pulumi, K8s, Docker, etc.) for vulnerabilities and misconfigurations. It's open-source, fast, supports CI/CD, and helps you fix issues before deployment. Say goodbye to insecure cloud deployments!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>📊 Interactive Dashboards with Dash: Python Data Visualization</title>
      <dc:creator>Daleska</dc:creator>
      <pubDate>Fri, 25 Apr 2025 22:53:25 +0000</pubDate>
      <link>https://dev.to/paltadash/interactive-dashboards-with-dash-python-data-visualization-l1l</link>
      <guid>https://dev.to/paltadash/interactive-dashboards-with-dash-python-data-visualization-l1l</guid>
      <description>&lt;p&gt;If you’ve ever wanted to build an interactive dashboard in Python without dealing with frontend code, &lt;strong&gt;Dash&lt;/strong&gt; is the tool you need. Dash is a powerful and easy-to-use framework that allows you to create interactive web apps with dynamic data visualizations. In this article, you’ll learn how to build an interactive dashboard from scratch, connect it to a database, and visualize your data easily using &lt;strong&gt;Plotly&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Dash?
&lt;/h2&gt;

&lt;p&gt;Dash is a Python framework created by Plotly for building interactive web applications focused on data visualization. With Dash, you can create dashboards with interactive charts without writing complex frontend code. It supports a high level of interactivity, making it ideal for real-time data analysis.&lt;/p&gt;

&lt;p&gt;One of Dash’s biggest advantages is that it allows you to work entirely in Python using Plotly to create advanced visualizations—no need to learn HTML, CSS, or JavaScript. That makes Dash perfect for both developers and data analysts alike.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Dash?
&lt;/h2&gt;

&lt;p&gt;Here are a few reasons to consider Dash for your next data project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ease of use: Building interactive dashboards is simple and straightforward.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interactivity: Add callbacks to make charts react to user inputs in real time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Flexibility: Integrate with multiple data sources, including SQL databases, Excel, and CSV files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scalability: From simple apps to complex analytical dashboards—Dash grows with your needs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, Dash is ideal for anyone looking to create dynamic, custom data visualizations with minimal complexity.&lt;/p&gt;




&lt;h3&gt;
  
  
  Archivos del Proyecto:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;app.py&lt;/strong&gt;: This file contains the logic of the Dash application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;config.py&lt;/strong&gt;: Holds the credentials and configuration for the database connection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;requirements.txt&lt;/strong&gt;: Lists all the dependencies required to run the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📦 Step 1: Install Dependencies
&lt;/h2&gt;

&lt;p&gt;First, make sure you have all required libraries installed. Create a requirements.txt file like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dash&lt;br&gt;
pandas&lt;br&gt;
mysql-connector-python&lt;br&gt;
plotly&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, install everything with:&lt;br&gt;
&lt;code&gt;pip install -r requirements.txt&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🔌 Step 2: Connect to a MySQL Database
&lt;/h2&gt;

&lt;p&gt;We'll use MySQL as our data source. You’ll need to configure your database connection in config.py like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# config.py

DB_CONFIG = {
    "host": "localhost",      
    "user": "root",           
    "password": "",          
    "database": "tienda_ventas"   
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in your app.py, write a function to fetch the data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# app.py

import dash
from dash import html, dcc
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
import mysql.connector
from config import DB_CONFIG  # Usamos config para la conexión

def get_data():
    conn = mysql.connector.connect(
        host=DB_CONFIG["host"],
        user=DB_CONFIG["user"],
        password=DB_CONFIG["password"],
        database=DB_CONFIG["database"]
    )

    query = """
    SELECT p.nombre AS producto, p.categoria, p.precio, v.cantidad, v.fecha
    FROM ventas v
    JOIN productos p ON v.producto_id = p.id
    """
    df = pd.read_sql(query, conn)
    conn.close()
    return df

# Obtener datos
df = get_data()

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

&lt;/div&gt;



&lt;p&gt;We use mysql.connector.connect() to connect, and pd.read_sql() to query and load data into a Pandas DataFrame.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ Step 3: Build the Dash App
&lt;/h2&gt;

&lt;p&gt;Let’s build the actual dashboard. We'll use a dropdown to select product categories, a line chart for daily sales, and a bar chart for total sales by product.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# app.py

# Crear app
app = dash.Dash(__name__)
app.title = "Dashboard de Ventas"

# Layout
app.layout = html.Div([
    html.H1("📊 Dashboard de Ventas", style={'textAlign': 'center'}),

    dcc.Dropdown(
        id='categoria-dropdown',
        options=[{'label': cat, 'value': cat} for cat in df['categoria'].unique()],
        value=df['categoria'].unique()[0],
        style={'width': '50%', 'margin': 'auto'}
    ),

    dcc.Graph(id='grafico-ventas'),

    html.Hr(),

    dcc.Graph(
        figure=px.bar(
            df.groupby('producto')['cantidad'].sum().reset_index(),
            x='producto',
            y='cantidad',
            title="Ventas totales por producto"
        )
    )
])

@app.callback(
    Output('grafico-ventas', 'figure'),
    Input('categoria-dropdown', 'value')
)
def update_graph(categoria):
    filtrado = df[df['categoria'] == categoria]
    fig = px.line(filtrado, x='fecha', y='cantidad', color='producto',
                  title=f"Ventas por día - Categoría: {categoria}")
    return fig

# Ejecutar
if __name__ == '__main__':
    app.run(debug=True)

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Code Breakdown
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Dropdown: Users select a product category; charts update based on this selection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Line Chart: Shows daily sales per product in the selected category.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bar Chart: Displays total units sold per product.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To run your dashboard locally, simply run the app.py file:&lt;br&gt;
&lt;code&gt;archivo app.py&lt;/code&gt;&lt;br&gt;
After a few seconds, you'll see this in your terminal:&lt;br&gt;
&lt;code&gt;Running on http://127.0.0.1:8050/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Open that URL in your browser, and voilà! 🎉 You’ll see your fully functional dashboard in action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Daleskadf/dash_python" rel="noopener noreferrer"&gt;Repositorio en GitHub&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Software Design Principles with Ruby (Applying SOLID)</title>
      <dc:creator>Daleska</dc:creator>
      <pubDate>Sat, 19 Apr 2025 14:04:17 +0000</pubDate>
      <link>https://dev.to/paltadash/software-design-principles-with-ruby-applying-solid-19g9</link>
      <guid>https://dev.to/paltadash/software-design-principles-with-ruby-applying-solid-19g9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Clean code is its own best documentation.” — Steve McConnell&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When we start programming, it's common to focus on &lt;strong&gt;just making it work&lt;/strong&gt;. But true skill lies in &lt;strong&gt;making it maintainable&lt;/strong&gt;, &lt;strong&gt;readable&lt;/strong&gt;, and &lt;strong&gt;easy to extend&lt;/strong&gt; over time. &lt;/p&gt;

&lt;p&gt;That's where the &lt;strong&gt;SOLID principles&lt;/strong&gt; come in. In this article, I’ll show you &lt;strong&gt;what they are&lt;/strong&gt;, &lt;strong&gt;why they matter&lt;/strong&gt;, and how to apply them with a &lt;strong&gt;real Ruby example&lt;/strong&gt; to see how powerful they can be.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧱 What is SOLID?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;SOLID&lt;/strong&gt; is a set of five object-oriented design principles introduced by Robert C. Martin to improve code quality and make it scalable and maintainable.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Principles:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;S&lt;/strong&gt; - &lt;strong&gt;Single Responsibility Principle (SRP)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O&lt;/strong&gt; - &lt;strong&gt;Open/Closed Principle (OCP)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L&lt;/strong&gt; - &lt;strong&gt;Liskov Substitution Principle (LSP)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I&lt;/strong&gt; - &lt;strong&gt;Interface Segregation Principle (ISP)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;D&lt;/strong&gt; - &lt;strong&gt;Dependency Inversion Principle (DIP)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;SRP - Single Responsibility Principle: A class should have only one reason to change — a single responsibility.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OCP - Open/Closed Principle: Software should be open for extension but closed for modification. You should be able to add new functionality without changing existing code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LSP - Liskov Substitution Principle: Subclasses should be substitutable for their base classes without altering the correctness of the program.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ISP - Interface Segregation Principle: Clients should not be forced to depend on interfaces they do not use. Prefer small, specific interfaces over large ones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DIP - Dependency Inversion Principle: High-level modules should not depend on low-level modules. Both should depend on abstractions.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  📚 Case Study: Report Generator
&lt;/h2&gt;

&lt;p&gt;Let’s imagine we are building an app that generates reports in multiple formats. We start with PDF and HTML, but then Markdown and DOCX get added.&lt;/p&gt;

&lt;p&gt;Let’s see how to apply SOLID to this scenario.&lt;/p&gt;

&lt;h2&gt;
  
  
  ❌ Version 1: Rigid and Hard to Scale
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Report
  attr_reader :title, :content

  def initialize(title, content)
    @title = title
    @content = content
  end

  def generate_pdf
    puts "Generating PDF for #{@title}"
  end

  def generate_html
    puts "Generating HTML for #{@title}"
  end
end

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

&lt;/div&gt;



&lt;p&gt;This version works, but it violates two major principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SRP: Report has two responsibilities: storing data and generating formats.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OCP: To add a new format (e.g. DOCX), you must modify this class.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ Refactored: SOLID Principles Applied
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# SRP (Single Responsibility Principle):
# This class is only responsible for storing the report's data.
class Report
  attr_reader :title, :content

  def initialize(title, content)
    @title = title
    @content = content
  end
end

# DIP (Dependency Inversion Principle):
# Abstract class that defines an interface for formatters.
# High-level classes will depend on this abstraction.
class ReportFormatter
  def format(report)
    raise NotImplementedError, 'This method must be implemented'
  end
end

# SRP and LSP
class PDFFormatter &amp;lt; ReportFormatter
  def format(report)
    puts "Generating PDF for #{report.title}"
  end
end

# SRP and LSP
class HTMLFormatter &amp;lt; ReportFormatter
  def format(report)
    puts "Generating HTML for #{report.title}"
  end
end

# OCP, SRP, LSP
class MarkdownFormatter &amp;lt; ReportFormatter
  def format(report)
    puts "# #{report.title}\n\n#{report.content}"
  end
end

# Client using the system
# DIP: Does not depend on a specific class, only on the abstraction
report = Report.new("Sales Report", "This is the content of the report")

formatter = HTMLFormatter.new
formatter.format(report)

formatter = PDFFormatter.new
formatter.format(report)

formatter = MarkdownFormatter.new
formatter.format(report)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What did we improve?
&lt;/h2&gt;

&lt;p&gt;SRP: Report only handles data, not formatting.&lt;br&gt;
OCP: We can add MarkdownFormatter without modifying any existing classes.ninguna clase existente.&lt;br&gt;
LSP: Any formatter can be used as a ReportFormatter without breaking the system.&lt;br&gt;
DIP: The client depends on the abstraction (ReportFormatter), not on specific implementations.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>programming</category>
      <category>solid</category>
      <category>bestpractices</category>
    </item>
    <item>
      <title>Enterprise Design Patterns: Applying the Data Mapper pattern with Java</title>
      <dc:creator>Daleska</dc:creator>
      <pubDate>Wed, 16 Apr 2025 01:34:47 +0000</pubDate>
      <link>https://dev.to/paltadash/enterprise-design-patterns-aplicando-el-patron-data-mapper-con-java-1okh</link>
      <guid>https://dev.to/paltadash/enterprise-design-patterns-aplicando-el-patron-data-mapper-con-java-1okh</guid>
      <description>&lt;p&gt;In this article, we will explore the &lt;strong&gt;Data Mappe&lt;/strong&gt; pattern, one of the patterns proposed by &lt;strong&gt;Martin Fowler&lt;/strong&gt; in his catalog Patterns of Enterprise Application Architecture. We will see how to implement it in Java &lt;strong&gt;without using a database&lt;/strong&gt;, ideal for those who want to understand the concept without extra technical complications.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What is the Data Mapper Pattern?
&lt;/h2&gt;

&lt;p&gt;It is an enterprise architecture pattern that separates business logic from data access logic. Unlike the Active Record pattern, where the same object knows how to save or load its data, Data Mapper introduces an intermediate layer (the "Mapper") that handles transferring data between the domain model and the data source (in this case, simulated).&lt;/p&gt;




&lt;h2&gt;
  
  
  Why is it useful?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Avoids mixing business logic with persistence.&lt;/li&gt;
&lt;li&gt;Improves maintainability and scalability of the system.&lt;/li&gt;
&lt;li&gt;Facilitates writing unit tests (no need for a DB).&lt;/li&gt;
&lt;li&gt;Allows changing the persistence mechanism without affecting domain classes.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Implementation in Java
&lt;/h2&gt;

&lt;p&gt;Below is a complete example using Java, simulating persistence in memory with a &lt;code&gt;HashMap&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Suggested Package Structure:
&lt;/h3&gt;




&lt;h3&gt;
  
  
  🧱 1. Model &lt;code&gt;User.java&lt;/code&gt;
&lt;/h3&gt;



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

public class User {
    private int id;
    private String name;
    private String email;

    public User() {}

    public User(int id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    // Getters y Setters

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧱 2. Interface &lt;code&gt;UserMapper.java&lt;/code&gt;
&lt;/h3&gt;



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

import model.User;
import java.util.List;

public interface UserMapper {
    User findById(int id);
    List&amp;lt;User&amp;gt; findAll();
    void insert(User user);
    void update(User user);
    void delete(int id);
}

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧱 3. Implementation &lt;code&gt;UserMapperImpl.java&lt;/code&gt;
&lt;/h3&gt;



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

import model.User;
import java.util.*;

public class UserMapperImpl implements UserMapper {
    private Map&amp;lt;Integer, User&amp;gt; database = new HashMap&amp;lt;&amp;gt;();

    @Override
    public User findById(int id) {
        return database.get(id);
    }

    @Override
    public List&amp;lt;User&amp;gt; findAll() {
        return new ArrayList&amp;lt;&amp;gt;(database.values());
    }

    @Override
    public void insert(User user) {
        database.put(user.getId(), user);
    }

    @Override
    public void update(User user) {
        if (database.containsKey(user.getId())) {
            database.put(user.getId(), user);
        }
    }

    @Override
    public void delete(int id) {
        database.remove(id);
    }
}

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧱 4. Test Class &lt;code&gt;UserService.java&lt;/code&gt;
&lt;/h3&gt;



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

import mapper.UserMapper;
import mapper.UserMapperImpl;
import model.User;

public class UserService {
    public static void main(String[] args) {
        UserMapper userMapper = new UserMapperImpl();

        User u1 = new User(1, "Juan", "juan@gmail.com");
        userMapper.insert(u1);

        User u2 = new User(2, "Lucía", "lucia@gmail.com");
        userMapper.insert(u2);

        System.out.println("📋 Todos los usuarios:");
        userMapper.findAll().forEach(u -&amp;gt; 
            System.out.println(u.getId() + " - " + u.getName())
        );

        System.out.println("✏️ Actualizando usuario:");
        u1.setName("Juan Pérez");
        userMapper.update(u1);
        System.out.println("Nuevo nombre: " + userMapper.findById(1).getName());

        System.out.println("🗑️ Eliminando usuario con ID 2");
        userMapper.delete(2);

        System.out.println("✅ Usuarios actuales:");
        userMapper.findAll().forEach(u -&amp;gt; 
            System.out.println(u.getId() + " - " + u.getName())
        );
    }
}

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Output
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;All users:&lt;br&gt;
1 - Juan&lt;br&gt;
2 - Lucía&lt;br&gt;
Updating user:&lt;br&gt;
New name: Juan Pérez&lt;br&gt;
Deleting user with ID 2&lt;br&gt;
Current users:&lt;br&gt;
1 - Juan Pérez&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can see the code on GitHub: &lt;a href="https://github.com/Daleskadf/java_data_mapper" rel="noopener noreferrer"&gt;GitHub Project Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Data Mapper&lt;/strong&gt; pattern is a powerful tool within the set of Enterprise Design Patterns, especially when aiming to maintain a clean and decoupled architecture. Separating data access logic from business logic not only improves the maintainability of the system but also facilitates its long-term evolution and scalability.&lt;/p&gt;

&lt;p&gt;This Java example demonstrates how this pattern can be applied without the need for a real database, using in-memory structures to focus on conceptual understanding. This approach is particularly useful in educational environments, prototypes, or when validating the architecture before connecting to a more complex persistence system.&lt;/p&gt;

&lt;p&gt;Adopting patterns like Data Mapper not only promotes good design but also trains the development mindset toward solid software engineering principles, which are key in real-world enterprise projects.&lt;/p&gt;

</description>
      <category>java</category>
      <category>designpatterns</category>
      <category>architecture</category>
      <category>backend</category>
    </item>
    <item>
      <title>🛡️ Simple Guide to Using PMD in Your Application</title>
      <dc:creator>Daleska</dc:creator>
      <pubDate>Sat, 12 Apr 2025 16:03:50 +0000</pubDate>
      <link>https://dev.to/paltadash/simple-guide-to-using-pmd-in-your-application-4i9g</link>
      <guid>https://dev.to/paltadash/simple-guide-to-using-pmd-in-your-application-4i9g</guid>
      <description>&lt;p&gt;🛡️ How to Apply PMD as a SAST Tool to Your Application&lt;/p&gt;

&lt;p&gt;In the modern development world, where cyberattacks are increasing every day, &lt;strong&gt;security can no longer be left for the end&lt;/strong&gt;. One of the most effective ways to protect your applications is to apply &lt;strong&gt;SAST (Static Application Security Testing)&lt;/strong&gt; from the start of development. In this article, I’ll show you how to use &lt;strong&gt;PMD&lt;/strong&gt;, a free static analysis tool that will help keep your code clean, efficient, and with fewer security risks.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 What is PMD?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PMD&lt;/strong&gt; is an open-source tool that analyzes source code (mainly in Java, but also supports Apex, JavaScript, XML, among others) and detects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Duplicated code&lt;/li&gt;
&lt;li&gt;Unused variables&lt;/li&gt;
&lt;li&gt;Poorly structured statements&lt;/li&gt;
&lt;li&gt;Excessively complex code&lt;/li&gt;
&lt;li&gt;Bad programming practices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although it is not solely focused on security, its ability to identify risky patterns makes it ideal for improving code health from a security perspective.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ How to Apply PMD to Your Application?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Install PMD
&lt;/h3&gt;

&lt;p&gt;You can download the tool from its official website:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://pmd.github.io" rel="noopener noreferrer"&gt;https://pmd.github.io&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download the .zip file corresponding to your operating system.&lt;/li&gt;
&lt;li&gt;Extract the files to a folder of your choice.&lt;/li&gt;
&lt;li&gt;(Optional) Add the bin/ folder to your system's environment variables to use it from any terminal.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 2: Prepare Your Application
&lt;/h3&gt;

&lt;p&gt;Make sure you have a Java application with a clear structure (such as src/main/java). PMD will directly analyze the .java files, &lt;strong&gt;so no need to compile the app.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 3: Run the Analysis
&lt;/h3&gt;

&lt;p&gt;Open your terminal and run the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pmd check -d src -R rulesets/java/quickstart.xml -f html &amp;gt; reporte.html&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Practical Example
&lt;/h2&gt;

&lt;p&gt;Want to see a real example of how PMD was applied to a Java application? You can check out this GitHub repository where the analysis was executed, and an HTML report was generated with the findings:&lt;/p&gt;

&lt;p&gt;🔗 &lt;a href="https://github.com/Daleskadf/java_pmd" rel="noopener noreferrer"&gt;See example on GitHub&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;Applying SAST tools like PMD early in the development process not only improves code quality but also strengthens the overall security of the application. Although PMD is not exclusively focused on finding security vulnerabilities, it does allow you to detect dangerous patterns, unnecessary complexities, and bad practices that could lead to more severe issues.&lt;/p&gt;

&lt;p&gt;Integrating it into your workflow is straightforward, and with minimal effort, you can start automating reviews that might otherwise go unnoticed. Whether you're working on a personal project or in a professional environment, using PMD is a smart step toward more robust and reliable development.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Deploying an Application on Azure: Guide</title>
      <dc:creator>Daleska</dc:creator>
      <pubDate>Sat, 06 Jul 2024 00:33:57 +0000</pubDate>
      <link>https://dev.to/paltadash/deploying-an-application-on-azure-guide-5680</link>
      <guid>https://dev.to/paltadash/deploying-an-application-on-azure-guide-5680</guid>
      <description>&lt;p&gt;In today's world of cloud computing, Microsoft Azure stands out as one of the leading platforms enabling developers and businesses to deploy applications efficiently and at scale. This article will guide you through the essential steps to deploy an application on Azure, from initial setup to production deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Creating an Azure Account
&lt;/h3&gt;

&lt;p&gt;Before you begin, you'll need a Microsoft Azure account. If you don't have one yet, you can sign up at azure.microsoft.com and create a free or paid account depending on your needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Creating a Resource Group
&lt;/h3&gt;

&lt;p&gt;In Azure, a Resource Group acts as a logical container that groups related resources for an application. Follow these steps to create one:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Sign in to the Azure Portal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on "Create a resource" in the side menu.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select "Resource group" and click on "Create".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fill in the details such as the resource group name, region, and then click on "Review + Create" and finally on "Create".&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 3: Creating a Web Application (Example with Azure App Service)
&lt;/h3&gt;

&lt;p&gt;Azure App Service allows you to deploy and scale web applications quickly and easily. To create one:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In the Azure Portal, select your newly created Resource Group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on "Add" to add a new resource.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Search for "App Service" and select "Create".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Complete the details such as application name, development stack (e.g., .NET, Node.js), and service plan (consumption plan or an App Service plan).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on "Review + Create" and then on "Create".&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 4: Application Deployment
&lt;/h3&gt;

&lt;p&gt;Once your App Service is configured, you can deploy your application:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open the settings of your App Service from the Azure Portal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the "Deployment" section, choose the option that best fits your application (e.g., FTP, GitHub, Azure DevOps).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Follow the instructions to connect your repository or upload your &lt;br&gt;
code.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 5: Configuration and Management
&lt;/h3&gt;

&lt;p&gt;Azure offers various tools to configure and manage your application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Application Settings:&lt;/strong&gt; Adjust environment variables, connection settings, and more from the Azure Portal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monitoring and Scaling:&lt;/strong&gt; Use Azure Monitor to track your application's performance and adjust scaling as needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security:&lt;/strong&gt; Implement security measures such as SSL certificates, multi-factor authentication, and access policies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 6: Optimization and Maintenance
&lt;/h3&gt;

&lt;p&gt;Once deployed, optimize your application to improve performance and ensure it stays updated with the latest software versions and security patches.&lt;/p&gt;

&lt;p&gt;Deploying applications on Azure not only enhances accessibility and scalability through its diverse service options but also streamlines operational efficiencies and enhances security protocols. With this guide, you now possess a robust foundation to harness Azure's cloud capabilities effectively, enabling seamless project expansion and innovation while ensuring optimal performance and reliability across your applications.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Evolution of API Development Styles: The GraphQL Architecture</title>
      <dc:creator>Daleska</dc:creator>
      <pubDate>Mon, 10 Jun 2024 19:48:12 +0000</pubDate>
      <link>https://dev.to/paltadash/the-evolution-of-api-development-styles-the-graphql-architecture-3jjl</link>
      <guid>https://dev.to/paltadash/the-evolution-of-api-development-styles-the-graphql-architecture-3jjl</guid>
      <description>&lt;p&gt;In the changing landscape of modern application development, the selection of API architecture style has become a critical factor in ensuring the efficiency, scalability and adaptability of solutions. While traditional approaches have been widely used, an increasingly popular alternative is the use of GraphQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is GraphQL?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Type system:&lt;/strong&gt; GraphQL has a type system that defines how data is &lt;br&gt;
     structured in the API, making it easy to explore and understand the &lt;br&gt;
     API.&lt;br&gt;
&lt;strong&gt;2. Flexible queries:&lt;/strong&gt; Clients can perform complex, nested queries to &lt;br&gt;
     get the data they need, rather than having to make multiple requests &lt;br&gt;
     to different endpoints.&lt;br&gt;
&lt;strong&gt;3. Execution environment:&lt;/strong&gt; GraphQL has a server-side execution &lt;br&gt;
     environment that interprets client queries, retrieves the necessary &lt;br&gt;
     data and returns a response in JSON format.&lt;br&gt;
&lt;strong&gt;4. API evolution:&lt;/strong&gt; GraphQL facilitates API evolution, since clients &lt;br&gt;
     can continue to use the same API even if the server adds or modifies &lt;br&gt;
     fields, as long as it does not remove fields that clients are &lt;br&gt;
     already using.&lt;/p&gt;
&lt;h2&gt;
  
  
  Benefits of GraphQL API Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;- Efficiency in data usage:&lt;/strong&gt; GraphQL allows clients to get only the &lt;br&gt;
    data they need, which reduces network traffic and improves &lt;br&gt;
    performance.&lt;br&gt;
&lt;strong&gt;- Flexibility and control:&lt;/strong&gt; Clients can request exactly the data they &lt;br&gt;
    need, giving them more control over the information they receive.&lt;br&gt;
&lt;strong&gt;- API evolution:&lt;/strong&gt; GraphQL makes it easy to evolve APIs without &lt;br&gt;
    breaking compatibility with existing clients.&lt;br&gt;
&lt;strong&gt;- Integrated documentation:&lt;/strong&gt; GraphQL's type system provides integrated &lt;br&gt;
    API documentation, making it easy to explore and use.&lt;br&gt;
&lt;strong&gt;- Reduced complexity:&lt;/strong&gt; GraphQL simplifies the architecture by &lt;br&gt;
    eliminating the need for multiple endpoints and response formats.&lt;/p&gt;
&lt;h2&gt;
  
  
  GraphQL Use Cases
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;- Web and mobile applications:&lt;/strong&gt; GraphQL enables clients to get only &lt;br&gt;
    the data they need, improving performance and user experience.&lt;br&gt;
&lt;strong&gt;- Microservices:&lt;/strong&gt; GraphQL can act as an integration layer between &lt;br&gt;
    multiple microservices, simplifying the interaction between them.&lt;br&gt;
&lt;strong&gt;- IoT applications:&lt;/strong&gt; GraphQL can be useful for managing communication &lt;br&gt;
    and data flow between IoT devices and the core application.&lt;br&gt;
&lt;strong&gt;- Large-scale data applications:&lt;/strong&gt; GraphQL facilitates querying and &lt;br&gt;
    manipulating large data sets, without the need for multiple requests.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Schema Definition
&lt;/h3&gt;

&lt;p&gt;Suppose we have a simple API to manage a list of books. We will start by defining the GraphQL schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Book {
  id: ID!
  title: String!
  author: String!
  published: Int
}

type Query {
  books: [Book]
  book(id: ID!): Book
}

type Mutation {
  createBook(title: String!, author: String!, published: Int): Book
  updateBook(id: ID!, title: String, author: String, published: Int): Book
  deleteBook(id: ID!): Book
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this schema, we have:&lt;/p&gt;

&lt;p&gt;Type Book: Represents a book, with fields such as id, title, author and published.&lt;br&gt;
Type Query: Defines query operations, such as getting a list of books or a book by its ID (book).&lt;br&gt;
Mutation type: Defines mutation operations, such as creating a new book (createBook), updating an existing book (updateBook) and deleting a book (deleteBook).&lt;/p&gt;
&lt;h3&gt;
  
  
  Query Example
&lt;/h3&gt;

&lt;p&gt;Suppose we want to get a list of books with their titles and authors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {
  books {
    id
    title
    author
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response would look something similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "data": {
    "books": [
      {
        "id": "1",
        "title": "The Great Gatsby",
        "author": "F. Scott Fitzgerald"
      },
      {
        "id": "2",
        "title": "To Kill a Mockingbird",
        "author": "Harper Lee"
      },
      {
        "id": "3",
        "title": "1984",
        "author": "George Orwell"
      }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Functional Programming in Python: A Practical Basic Guide to Functors, Monads, and Promises.</title>
      <dc:creator>Daleska</dc:creator>
      <pubDate>Thu, 18 Apr 2024 04:56:35 +0000</pubDate>
      <link>https://dev.to/paltadash/functional-programming-in-python-a-practical-basic-guide-to-functors-monads-and-promises-344l</link>
      <guid>https://dev.to/paltadash/functional-programming-in-python-a-practical-basic-guide-to-functors-monads-and-promises-344l</guid>
      <description>&lt;p&gt;Functional programming has gained popularity in recent years due to its focus on building programs using pure functions and composition. In Python, a versatile and widely used language, we can also leverage the concepts of functors, monads and promises to write cleaner and more readable code. In this article, we will explore how to use these concepts in Python and provide code examples to illustrate their application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Functors
&lt;/h2&gt;

&lt;p&gt;Functionors are structures that allow us to apply functions to wrapped values within a context. In Python, we can take advantage of the built-in capabilities of data types such as lists, dictionaries or sets to accomplish this efficiently.&lt;/p&gt;

&lt;p&gt;We want to apply a function that converts all strings in a list to uppercase. We can use the list functor in Python to accomplish this efficiently: 🧑‍💻&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;strings = ["hello", "world", "python"]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;upper_strings = list(map(str.upper, strings))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;print(upper_strings)  # Output: ['HELLO', 'WORLD', 'PYTHON']&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Monads
&lt;/h2&gt;

&lt;p&gt;Monads are an extension of functors that allow us to chain operations that return values wrapped in a context. In Python, we can take advantage of libraries such as pymonad to work with monads and simplify the handling of side effects and complex situations.&lt;/p&gt;

&lt;p&gt;We want to calculate the area of a triangle, but the base or height values could be None if they are not provided. We can use the Maybe monad to handle these optional values safely: 🧑‍💻&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;from pymonad.maybe import Maybe&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;def calculate_triangle_area(base, height):&lt;br&gt;
    if base is not None and height is not None:&lt;br&gt;
        return Maybe.just(0.5 * base * height)&lt;br&gt;
    else:&lt;br&gt;
        return Maybe.nothing()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;base = 5&lt;br&gt;
height = None&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;triangle_area = calculate_triangle_area(base, height)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;if triangle_area.is_just():&lt;br&gt;
    print("Área del triángulo:", triangle_area.just)&lt;br&gt;
else:&lt;br&gt;
    print("No se pudo calcular el área del triángulo.")&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Promises
&lt;/h2&gt;

&lt;p&gt;Promises are another important concept in functional programming that allow us to handle asynchronous operations in a more concise and structured way. In Python, we can use libraries such as asyncio to work with promises and take advantage of asynchronous programming.&lt;/p&gt;

&lt;p&gt;Suppose we want to make three HTTP requests asynchronously and process the responses when they are available. We can use the aiohttp library together with asyncio to work with promises and perform asynchronous operations: 🧑‍💻&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;import asyncio&lt;br&gt;
import aiohttp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;async def fetch_data(url):&lt;br&gt;
    async with aiohttp.ClientSession() as session:&lt;br&gt;
        async with session.get(url) as response:&lt;br&gt;
            return await response.text()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;async def main():&lt;br&gt;
    urls = ["https://api.example.com/data1", "https://api.example.com/data2", "https://api.example.com/data3"]&lt;br&gt;
    tasks = [fetch_data(url) for url in urls]&lt;br&gt;
    results = await asyncio.gather(*tasks)&lt;br&gt;
    for result in results:&lt;br&gt;
        print("Respuesta:", result)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;asyncio.run(main())&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We have explored how to apply the concepts of functors, monads and promises in Python to write cleaner and more readable code. Functors allow us to apply functions to values wrapped in a context, monads allow us to chain operations and handle optional values, and promises help us handle asynchronous operations in a structured way. These concepts are useful for building more robust and flexible programs in Python, taking advantage of the benefits of functional programming. 😉&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
