Mostrando entradas con la etiqueta api. Mostrar todas las entradas
Mostrando entradas con la etiqueta api. Mostrar todas las entradas

miércoles, 8 de julio de 2026

MuleSoft para desarrolladores de APIs

MuleSoft es una plataforma de integración que te permite conectar aplicaciones, datos y APIs de manera centralizada.

Para un desarrollador Java con Spring Boot, sirve como un puente que complementa su backend con capacidades de gestión de APIs, orquestación de servicios y conectividad con sistemas externos.

MuleSoft en pocas palabras

  1. Plataforma de integración: MuleSoft (con su runtime Mule 4) permite crear flujos de integración entre sistemas heterogéneos (bases de datos, servicios REST/SOAP, colas de mensajería, SaaS).
  2. Anypoint Platform: Incluye herramientas como Anypoint Studio (IDE), API Designer (para diseño contract-first), y API Manager (para aplicar políticas de seguridad, rate limiting, etc.).
  3. SDK para Java: Puedes extender Mule creando conectores y módulos en Java usando Maven y el Mule SDK.

¿Para qué sirve en tu contexto Spring Boot?

Como desarrollador Java con experiencia en Spring Boot, MuleSoft nos aporta:

Diseño contract-first: Puedes definir tu API en RAML u OAS en Anypoint Designer y luego implementar la lógica en Spring Boot. Esto asegura consistencia entre diseño y código.

Gestión de APIs: MuleSoft API Manager permite aplicar políticas como:

  • Validación JWT con Keycloak.
  • Rate limiting para proteger tu backend.
  • Control de tráfico y seguridad centralizada.

Integración embebida: Existe un Spring Boot Starter para Mule 4, que te permite correr Mule Runtime dentro de tu aplicación Spring Boot. Esto facilita:

  • Monitoreo con Spring Boot Admin.
  • Exposición de servicios de despliegue Mule vía REST.
  • Control de tráfico y seguridad centralizada.

Comparativa: Spring Boot vs MuleSoft

Tabla comparativa entre Spring Boot y MuleSoft:

Aspecto Spring Boot MuleSoft
Foco principal Desarrollo rápido de microservicios y APIs Integración, gestión y orquestación de APIs
Diseño API Implementación directa con Spring MVC Contract-first con RAML/OAS + mockeo
Gestión de tráfico Necesitas librerías externas (Resilience4j, Spring Cloud Gateway) Políticas listas en API Manager
Extensibilidad Beans, filtros, interceptores Conectores y módulos vía Mule SDK
Despliegue Microservicios en contenedores Integraciones como aplicaciones Mule, embebibles en Spring Boot

Consideraciones y trade-offs

  • Licenciamiento: MuleSoft Enterprise puede ser costoso; evalúa si tu proyecto requiere gestión avanzada de APIs o si basta con Spring Cloud Gateway.
  • Curva de aprendizaje: Aunque conoces Java, MuleSoft introduce conceptos propios (flows, connectors, RAML).
  • Complementariedad: No reemplaza Spring Boot, sino que lo potencia en escenarios de integración compleja.

MuleSoft puede ser algo complejo para aprender. Existen mucha información, tutoriales y cursos en internet que podrían servirte para aprender a usarlo.

Enlaces:

https://www.mulesoft.com/
https://es.wikipedia.org/wiki/MuleSoft
https://www.seidor.com/es-mx/blog/salesforce-mulesoft-que-es
https://rootstack.com/es/blog/mulesoft-todo-lo-que-tienes-que-saber

domingo, 25 de enero de 2026

gRPC y GraphQL en una comparativa

gRPC y GraphQL son dos de los protocolos de comunicación más utilizados actualmente en el desarrollo de APIs.

GraphQL es ideal cuando el cliente necesita controlar qué datos obtiene, evitando cargas innecesarias. Consultas flexibles y un solo endpoint para múltiples recursos.

gRPC destaca en rendimiento, streaming y comunicación entre microservicios gracias a su formato binario y contratos estrictos. Con una comunicación bidireccional y streaming.

Comparativa entre gRPC y GraphQL

He aquí una tabla comparativa entre estos dos protocolos de comunicación:

Aspecto GraphQL gRPC
Modelo de comunicación Basado en consultas declarativas; el cliente define qué datos necesita. Basado en llamadas a procedimientos remotos (RPC) con contratos definidos en archivos .proto.
Formato de datos JSON, fácil de leer y depurar. Protocol Buffers (binario), más eficiente en tamaño y velocidad.
Orientación Optimizado para APIs orientadas a frontends y aplicaciones con múltiples vistas. Optimizado para comunicación entre microservicios y sistemas distribuidos de alto rendimiento.
Similitudes Ambos buscan mejorar la eficiencia respecto a REST, soportan tipado fuerte y facilitan la evolución de APIs.
Pros - Flexibilidad en consultas.
- Evita el overfetching y underfetching.
- Gran ecosistema y soporte en frontend.
- Alto rendimiento y baja latencia.
- Streaming bidireccional.
- Contratos estrictos con Protobuf.
Contras - Mayor complejidad en servidores.
- Problemas de caché.
- Curva de aprendizaje para consultas avanzadas.
- Menos legible para humanos (binario).
- Requiere más configuración inicial.
- Ecosistema más orientado a backend que frontend.
Casos de uso ideales Aplicaciones web y móviles que requieren flexibilidad en datos. Microservicios, sistemas distribuidos y aplicaciones de tiempo real.


GraphQL en un ejemplo

Miremos la siguiente imagen que muestra un ejemplo del uso de GraphQL.

El flujo nos dice que:

  • El cliente (una app web o móvil) envía una consulta específica. 
  • El servidor GraphQL responde solo con los datos solicitados, evitando el overfetching
  • Además se usa JSON como formato de respuesta, y el cliente controla qué campos necesita.

gRPC en un ejemplo

Ahora miremos un ejemplo de uso de gRPC.

El flujo nos dice que:

  • El cliente (normalmente otro microservicio) realiza una llamada RPC. 
  • El servidor gRPC responde con datos serializados en Protocol Buffers, optimizados para velocidad y eficiencia. 
  • El contrato entre ambos está definido en archivos .proto, lo que garantiza tipado fuerte y evolución controlada.

Lenguajes de programación más utlizados para ambos protocolos

Lenguaje Uso en GraphQL Uso en gRPC
JavaScript / TypeScript Muy popular en frontend y backend con frameworks como Apollo Server y Express. Soporte limitado; se usa más en clientes que en servidores.
Python Usado con librerías como Graphene y Ariadne. Bien soportado con gRPC Python; útil en ciencia de datos y microservicios.
Java Compatible con librerías como graphql-java. Muy usado en backend empresarial con soporte oficial de gRPC.
Go Menos común en GraphQL, aunque existen librerías como gqlgen. Uno de los lenguajes más eficientes para gRPC; ideal para microservicios.
C++ Raramente usado en GraphQL. Alto rendimiento en sistemas embebidos y backend con gRPC.
.NET (C#) Compatible con HotChocolate y GraphQL.NET. Soporte oficial de gRPC en .NET Core; muy usado en entornos Windows.
Ruby Popular en startups con graphql-ruby. Soporte limitado para gRPC.

Como se puede observar:

  • Go, Java y .NET son excelentes opciones para gRPC
  • JavaScript/TypeScript y Python son ideales para GraphQL.

Conclusiones:

Ambos son alternativas modernas a REST, pero su elección depende del contexto: GraphQL para flexibilidad en frontends y gRPC para eficiencia en backends distribuidos.

Enlaces:

https://alquimistadecodigo.blogspot.com/2024/04/un-vistazo-grpc-una-alternativa-soap-y.html
https://alquimistadecodigo.blogspot.com/2024/05/graphql-en-un-vistazo.html
https://unpocodejava.com/2019/01/23/que-es-grpc/
https://alquimistadecodigo.blogspot.com/2024/05/grpc-protobuff-protocol-buffers.html
https://learn.microsoft.com/es-es/dotnet/architecture/cloud-native/grpc
https://learn.microsoft.com/es-es/dotnet/architecture/cloud-native/grpc



sábado, 18 de octubre de 2025

Consumiendo una API pública con Kotlin & OkHttp

En el pasado post vimos cómo consumir un servicio Node desde una aplicación Java gracias a la librería OkHttp. Esta vez usaremos Kotlin como lenguaje base y Gradle para la administración de las dependencias y ejecución del proyecto.

¿Qué haremos?

1. Comenzaremos con la creación del directorio del proyecto:

$ mkdir proyecto-kotlin
$ cd proyecto-kotlin

El directorio del proyecto se verá así:

proyecto-kotlin/
   .gitattributes
   .gitignore
   .gradle
   .kotlin
   app/
   build/
   gradle/
   gradle.properties
   gradlew
   gradlew.bat
   settings.gradle.kts

2. Agregamos la dependencia de ``OkHttp`` en el archivo ``build.gradle.kts``:

plugins {
    alias(libs.plugins.kotlin.jvm)
    application
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("com.squareup.okhttp3:okhttp:4.12.0") // Moved to implementation
    testImplementation("org.jetbrains.kotlin:kotlin-test")
    testImplementation(libs.junit.jupiter.engine)
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
    implementation(libs.guava)
    testImplementation("org.junit.jupiter:junit-jupiter:5.10.3")
    testImplementation("org.mockito:mockito-core:5.12.0")
    testImplementation("org.mockito:mockito-junit-jupiter:5.12.0")
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

application {
    mainClass = "org.inforhomex.AppKt"
}

tasks.named<Test>("test") {
    useJUnitPlatform()
}

Con esto se podrá descargar la dependencia.

3. Editamos el programa ``app/src/main/kotlin/org/inforhomex/App.kt``.

package org.inforhomex

import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.IOException

private const val URL_API = "https://api.chucknorris.io/jokes/random"

fun run(client: OkHttpClient = OkHttpClient()) {
    val request = Request.Builder().url(URL_API).build()
    client.newCall(request).execute().use { response ->
        if (!response.isSuccessful) throw IOException("Unexpected code $response")
        for ((name: String, value: String) in response.headers) {
            println("$name: $value")
        }
        println(response.body?.string() ?: "No response body")
    }
}

fun main() {
    run()
}

4. Creamos una prueba unitaria ``AppTest.kt``

package org.inforhomex


import okhttp3.*
import okio.Buffer
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.junit.jupiter.MockitoExtension
import java.io.IOException
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith

@ExtendWith(MockitoExtension::class)
class AppTest {

    @Mock
    private lateinit var client: OkHttpClient

    @Mock
    private lateinit var response: Response

    @Mock
    private lateinit var responseBody: ResponseBody

    @Mock
    private lateinit var call: Call

    private val urlApi = "https://api.chucknorris.io/jokes/random"

    @BeforeEach
    fun setUp() {
        
        Mockito.`when`(client.newCall(Mockito.any(Request::class.java))).thenReturn(call)
    }

    @Test
    fun `test run success response`() {
        
        val mockJson = """
            {
                "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
                "id": "abc123",
                "url": "",
                "value": "Chuck Norris can divide by zero."
            }
        """
        Mockito.`when`(call.execute()).thenReturn(response)
        Mockito.`when`(response.isSuccessful).thenReturn(true)
        Mockito.`when`(response.body).thenReturn(responseBody)
        Mockito.`when`(responseBody.string()).thenReturn(mockJson)
        Mockito.`when`(response.headers).thenReturn(Headers.Builder().add("Content-Type", "application/json").build())

        
        val output = captureOutput {
            run(client) 
        }

        
        assert(output.contains("Content-Type: application/json"))
        assert(output.contains("Chuck Norris can divide by zero."))
    }

    @Test
    fun `test run unsuccessful response throws IOException`() {
       
        Mockito.`when`(call.execute()).thenReturn(response)
        Mockito.`when`(response.isSuccessful).thenReturn(false)
        Mockito.`when`(response.code).thenReturn(404)

       
        val exception = assertFailsWith<IOException> {
            run(client) 
        }
        assertEquals("Unexpected code 404", exception.message)
    }

    
    private fun captureOutput(block: () -> Unit): String {
        val outputStream = java.io.ByteArrayOutputStream()
        val printStream = java.io.PrintStream(outputStream)
        val originalOut = System.out
        System.setOut(printStream)
        try {
            block()
        } finally {
            System.setOut(originalOut)
        }
        return outputStream.toString()
    }
}

5. Compilamos y ejecutamos la aplicación:

$ gradle build
$ gradle run

Si todo va bien, veremos esto en la consola:

date: Sun, 19 Oct 2025 03:25:17 GMT
content-type: application/json
nel: {"report_to":"heroku-nel","response_headers":["Via"],"max_age":3600,"success_fraction":0.01,"failure_fraction":0.1}
report-to: {"group":"heroku-nel","endpoints":[{"url":"https://nel.heroku.com/reports?s=e%2BRTonTfjrgED0WXfh1o2mxbl6%2BLhQQ4LIu%2F1NhF4MM%3D\u0026sid=812dcc77-0bd0-43b1-a5f1-b25750382959\u0026ts=1760844317"}],"max_age":3600}
reporting-endpoints: heroku-nel="https://nel.heroku.com/reports?s=e%2BRTonTfjrgED0WXfh1o2mxbl6%2BLhQQ4LIu%2F1NhF4MM%3D&sid=812dcc77-0bd0-43b1-a5f1-b25750382959&ts=1760844317"
server: cloudflare
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
via: 1.1 heroku-router
cf-cache-status: DYNAMIC
cf-ray: 990d2ad69c2f69de-DFW
alt-svc: h3=":443"; ma=86400
{"categories":[],"created_at":"2020-01-05 13:42:20.262289","icon_url":"https://api.chucknorris.io/img/avatar/chuck-norris.png","id":"zDUih4UaS82sDRjSX0hlLQ","updated_at":"2020-01-05 13:42:20.262289","url":"https://api.chucknorris.io/jokes/zDUih4UaS82sDRjSX0hlLQ","value":"Chuck Norris always wanted to surf but couldn't. Everytime his board touches the water, the sea parts."}

¡La aplicación ha funcionado correctamente!

Continuaremos con esta serie de ejemplos en próximas entregas.

Enlaces:

https://square.github.io/okhttp/
https://www.baeldung.com/guide-to-okhttp
https://ironpdf.com/es/java/blog/java-help/okhttp-java/


sábado, 11 de octubre de 2025

Programando en Java no. 10: Consumir una API con la librería OkHttp

En el post anterior vimos como consumir una API desde C#. Ahora lo haremos con Java y OkHttp, un cliente HTTP que es muy eficiente y que ofrece:

  • La compatibilidad con HTTP/2 permite que todas las solicitudes al mismo host compartan un socket. 
  • La agrupación de conexiones reduce la latencia de las solicitudes (si HTTP/2 no está disponible). GZIP transparente reduce el tamaño de las descargas. 
  • El almacenamiento en caché de respuestas evita por completo que la red reciba solicitudes repetidas.

Además de seguir especificaciones HTTP modernas como:

  • Semántica HTTP - RFC 9110.
  • Almacenamiento en caché HTTP - RFC 9111 
  • HTTP/1.1 - RFC 9112 
  • HTTP/2 - RFC 9113 
  • WebSockets - RFC 6455
  • SSE - Eventos enviados por el servidor.

1. Comencemos creando el proyecto con Maven:

$ mvn archetype:generate \
        -DgroupId=com.inforhomex.app \
        -DartifactId=proyecto \
        -DarchetypeArtifactId=maven-archetype-quickstart \
        -DarchetypeVersion=1.4 \
        -DinteractiveMode=false

Nos posicionamos en el directorio creado y modificamos la clase principal.

App.java

package com.inforhomex.app;

import okhttp3.*;
import java.io.IOException;
import static java.lang.System.out;
import static java.lang.System.err;

/**
 * @author Codemonkey Junior
 */
public class App {

    public static final String URL_STRING = "http://localhost:3000/api/saludo";
    public static void main(String[] args) {
        out.println("\t [ Consumiendo una API con okhttp ]");
        hacerPeticionEnApi(args);
    }

    private static void hacerPeticionEnApi(String... args){
        OkHttpClient client = new OkHttpClient();
        HttpUrl.Builder urlBuilder = HttpUrl.parse(URL_STRING).newBuilder();
        urlBuilder.addQueryParameter("id", "765421");
        final String finalUrl = urlBuilder.build().toString();
        Request.Builder requestBuilder = new Request.Builder()
        .url(finalUrl).method("GET", null)
        .addHeader("application-name", "application-java");
        Request request = requestBuilder.build();
        try(Response response = client.newCall(request).execute()){
            out.println(response.code());
            if(response.body() != null){
                out.println(response.body().string());
            }else{
                out.println("La respuesta es: null");
            }
        }catch(IOException ioex){
            err.printf("Excepcion: %s\n", ioex.getMessage());
        }

    }

}

En esta clase creamos un cliente gracias a la librería okhttp3 y en específico a la clase ``OkHttpClient``. Indicamos la URL del servicio (hecho en Node JS). Indicamos el valor a mandar (id) y el nombre de la aplicación en las cabeceras (header).

Compilamos la aplicación:

$ mvn clean compile

Reusaremos el servicio creado en el post anterior.

index.js

import express from 'express';


const app = express();
const port = 3000;

// Parsear JSON
app.use(express.json());

app.get('/', (req, res) => {
    res.send('Hola, mundo desde Node JS y Express.');
});



app.get('/api/saludo', (req, res) => {
  const id = req.query.id || 'desconocido';
  const appName = req.headers['application-name'] || 'sin nombre';

  res.json({
    mensaje: `¡Hola! Recibí tu ID: ${id}`,
    origen: `Aplicación: ${appName}`
  });
});



app.listen(port, () => {
    console.log(`Escuchando desde el puerto: http://localhost:${port}`);
});

Ejecutamos el proyecto node e iniciará el servicio en la url: http://localhost:3000

$ npm start

Ejecutamos la aplicación Java con Maven, pero antes debemos hacer unos ajustes al ``pom.xml``

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.inforhomex.app</groupId>
  <artifactId>proyecto-okhtpp</artifactId>
  <version>1.0</version>

  <name>proyecto-okhtpp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.release>17</maven.compiler.release>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.junit</groupId>
        <artifactId>junit-bom</artifactId>
        <version>5.11.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

      <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp-bom</artifactId>
        <version>5.2.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <scope>test</scope>
    </dependency>
    <!-- Optionally: parameterized tests support -->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-params</artifactId>
      <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.squareup.okhttp/okhttp -->
    <dependency>
      <groupId>com.squareup.okhttp3</groupId>
      <artifactId>okhttp-jvm</artifactId>
      <version>5.1.0</version>
    </dependency>

    <dependency>
      <groupId>com.squareup.okhttp3</groupId>
      <artifactId>mockwebserver3</artifactId>
    </dependency>

    <dependency>
      <groupId>com.squareup.okhttp3</groupId>
      <artifactId>logging-interceptor</artifactId>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement>
      <plugins>

        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>exec-maven-plugin</artifactId>
          <version>1.4.0</version>
          <configuration>
            <mainClass>com.inforhomex.app.App</mainClass>
          </configuration>
        </plugin>


        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.4.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.3.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.13.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>3.3.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.4.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>3.1.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>3.1.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.12.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.6.1</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

Esto nos permitirá agregar las librerías y ejecutar la aplicación con Maven:

$ mvn exec:java

Si todo es correcto, veremos en consola el resultado:

         [ Consumiendo una API con okhttp ]
200
{"mensaje":"¡Hola! Recibí tu ID: 765421","origen":"Aplicación: application-java"}

¡Hemos consumido un servicio Node JS con Java y la librería okhttp!

Más ejemplos en próximas entregas.

Enlaces:

https://square.github.io/okhttp/


Programando en C# no. 11 (consumiendo una API)

En está ocasión veremos cómo consumir una API desde una aplicación hecha con C#.

Se tratará de una aplicación sencilla y sin usar un framework web.

Tendremos una aplicación Cliente y otra Servidor.

En este caso el cliente lo haremos con C# y la aplicación servidor con Node JS.

Comencemos.

1. Creamos una aplicación C# con dotnet.

$ mkdir proyecto-api
$ cd proyecto-api
$ dotnet new webapi

2. Modificamos el programa principal:

Program.cs

using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;

class Program
{
    static async Task Main(string[] args)
    {
        using (var client = new HttpClient())
        {
            var query = System.Web.HttpUtility.ParseQueryString(string.Empty);
            query["id"] = "1234";
            var uriBuilder = new UriBuilder("http://localhost:3000/api/saludo");
            uriBuilder.Query = query.ToString();
            var request = new HttpRequestMessage
            {
                Method = HttpMethod.Get,
                RequestUri = uriBuilder.Uri
            };
            request.Headers.Add("application-name", "Aplicacion .NET");
            var response = await client.SendAsync(request);
            var responseBody = await response.Content.ReadAsStringAsync();
            Console.WriteLine(responseBody);
        }
    }
}

Este será nuestro programa cliente que accederá a un servicio de Node Js. Le mandaremos un id y el nombre de la aplicación (este en los encabezados). Colocaremos la URL del servicio y el método HTTP a usar, en este caso será el método GET, pues queremos obtener un resultado.

Ahora el servicio con Node JS.

1. Creamos el proyecto:

$ mkdir proyecto-rest
$ cd proyecto-rest
$ npm init -y

Esto nos generará un package.json. Lo editaremos más adelante. Ahora es necesario instalar Express JS en caso de no tenerlo.

$ npm install express

2. Creamos un archivo JS que será nuestro programa servidor.

index.js

import express from 'express';


const app = express();
const port = 3000;

// Parsear JSON
app.use(express.json());

app.get('/', (req, res) => {
    res.send('Hola, mundo desde Node JS y Express.');
});



app.get('/api/saludo', (req, res) => {
  const id = req.query.id || 'desconocido';
  const appName = req.headers['application-name'] || 'sin nombre';

  res.json({
    mensaje: `¡Hola! Recibí tu ID: ${id}`,
    origen: `Aplicación: ${appName}`
  });
});



app.listen(port, () => {
    console.log(`Escuchando desde el puerto: http://localhost:${port}`);
});

Nuestro servicio estará expuesto en la URL: http://localhost:3000/saludo

3. Editamos el archivo ``package.json``

{
  "name": "proyecto-rest",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "Codemonkey Junior",
  "license": "ISC",
  "description": "Un sencillo servicio con Node JS",
  "type": "module",
  "dependencies": {
    "express": "^5.1.0"
  }
}

Ahora podremos ejecutar el proyecto Node JS con este comando:

$ npm start

Y ejecutamos el cliente:

$ dotnet build
$ dotnet run

Si todo va bien veremos esto en la consola:

{"mensaje":"¡Hola! Recibí tu ID: 1234","origen":"Aplicación: Aplicacion .NET"}

Con esto hemos creado nuestra aplicación que consume una sencilla API de Node JS.

Enlaces:

https://alquimistadecodigo.blogspot.com/2025/09/node-consumiendo-una-api-publica.html


domingo, 5 de octubre de 2025

Creando un proyecto backend con C#

Si, soy un oso, pero también un programador C#

En está ocasión veremos cómo crear un proyecto backend con C#.

Debemos tener instalado Dotnet. En caso de no tenerlo, lo puedes descargar desde este sitio: https://dotnet.microsoft.com/en-us/download

Abrimos una terminal y tecleamos:

$ dotnet new webapi -n proyecto-backend
$ cd proyecto-backend

Esto nos creará un proyecto llamado ``proyecto-backend``. La estructura será similar a esto:

proyecto-backend/
  appsettings.Development.json
  appsettings.json
  bin/
  obj/
  Program.cs
  Properties/
  proyecto-backend.csproj
  proyecto-backend.http
  proyecto-backend.sln

Veamos el programa principal. El cual se trata de una API de descripciones climáticas.

Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

var summaries = new[]
{
    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

app.MapGet("/weatherforecast", () =>
{
    var forecast =  Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi();

app.Run();

record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

Ahora echemoslo a andar:

$ dotnet build
$ dotnet run

Abrimos el navegador en la ruta: http://localhost:5071/weatherforecast

Nos mostrará un JSON:

[
{
"date": "2025-10-06",
"temperatureC": 7,
"summary": "Freezing",
"temperatureF": 44
},
{
"date": "2025-10-07",
"temperatureC": -3,
"summary": "Hot",
"temperatureF": 27
},
{
"date": "2025-10-08",
"temperatureC": 11,
"summary": "Freezing",
"temperatureF": 51
},
{
"date": "2025-10-09",
"temperatureC": 29,
"summary": "Warm",
"temperatureF": 84
},
{
"date": "2025-10-10",
"temperatureC": -5,
"summary": "Mild",
"temperatureF": 24
}
]

Ahora creemos otra sencilla API con C#.

Creando una sencilla API con C#

Crearemos un servicio sencillo que nos permita generar un JSON con la siguiente estructura:

[
{
	"animal": "gato",
	"raza:":"felino",
	"nombre":"Don Panther",
	"id": 1
},

{
	"animal": "gato",
	"raza:":"felino",
	"nombre":"El Guererais",
	"id": 2
},

{
	"animal": "gato",
	"raza:":"felino",
	"nombre":"Caramelo",
	"id": 3
}

]

Crearemos una capeta ``model`` donde tendremos dos clases:

  • Felino.cs 
  • Gato.cs (que hereda de Felino.cs)

Felino.cs

using System;

namespace model
{
    public class Felino
    {


        private long id;
        private string nombre;
        private string raza;



        public void comer()
        {
            Console.WriteLine("El felino come");
        }

        public long Id
        {
            get; set;
        }

        public string Nombre
        {
            get; set;
        }
        
        public string Raza
        {
            get; set;
        }

    }
}

Gato.cs

using System;

namespace model
{
    public class Gato : Felino
    {


        public Gato(long id, string nombre, string raza)
        {
            this.Id = id;
            this.Nombre = nombre;
            this.Raza = raza;
        }


        public void comer()
        {
            Console.WriteLine("El gato come");
        }

    }
}

Ahora el programa principal lucirá así:

Program.cs

using model;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

var gatos = new List<Gato>
{
    new Gato(1, "Don Panther", "felino"),
    new Gato(2, "El Guererais", "felino"),
    new Gato(3, "Caramelo", "felino")
};

app.MapGet("/gatos", () =>
{
    var resultado = gatos.Select(g => new {
        raza = g.Raza,
        nombre = g.Nombre,
        id = g.Id
    });

    return Results.Json(resultado);
})
.WithName("GetGatos")
.WithOpenApi();

app.Run();

Construyamos y ejecutemos la aplicación:

$ dotnet build
$ dotnet run

Abrimos el navegador en la ruta: http://localhost:5071/gatos

Nos mostrará nuestro JSON:

[
{
"raza": "felino",
"nombre": "Don Panther",
"id": 1
},
{
"raza": "felino",
"nombre": "El Guererais",
"id": 2
},
{
"raza": "felino",
"nombre": "Caramelo",
"id": 3
}
]

Si queremos ver la página de Swagger de nuestra aplicación abrimos la siguiente URL: http://localhost:5071/swagger/index.html


¡Hemos creado una sencilla API con C#!

Continuaremos con este tema en próximas entregas

Enlaces:

https://dotnet.microsoft.com/


Jai un lenguaje de programación inspirado en C++

Hoy hablaremos de un nuevo lenguaje de programación llamado Jai . Se trata de un lenguaje de programación que está desarrolland...

Etiquetas

Archivo del blog