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

Programando en C# no.10 (usando xUnit)

Las pruebas unitarias nos ayudan a validar el funcionamiento de nuestro código. Se basan en el TDD o desarrollo basado en pruebas.

La filosofía del TDD se basa en:

  1. Escribir pruebas que fallen, se le da un color rojo. 
  2. Escribir pruebas que pasen, en color verde. 
  3. Refactorización, en azul.

Nosotros usaremos xUnit.

xUnit.net es una herramienta de prueba unitaria gratuita y de código abierto para .NET Framework (que se puede usar para C#, F# o Visual Basic).

Es similar a JUnit, pero para proyectos .NET.

Podemos hacer una breve comparativa.

Concepto xUnit (.NET/C#) JUnit (Java)
Lenguaje  C#  Java
Anotación de prueba [Fact] [Theory] @Test
Assert  Assert.Equal(), Assert.True()  Assertions.assertEquals(), etc.
Setup/Teardown  Constructor, IDisposable  @BeforeEach, @AfterEach
Organización  Por clase y métodos públicos  Por clase y métodos anotados
Ejecución  dotnet test  mvn test, gradle test, etc.

Instalamos algunos paquetes necesarios con Nuget (solo en caso de no tenerlos):

$ dotnet add package xunit
$ dotnet add package xunit.runner.visualstudio
$ dotnet add package Microsoft.NET.Test.Sdk

Comenzemos con una prueba sencilla. Una clase tiene un método para sumar dos números enteros. Crearemos una sencilla prueba para probar ese método.

1. Crear directorio del proyecto y ubicarnos en el.

$ mkdir Calculadora
$ cd Calculadora

2. Crear una solución con este comando:

$ dotnet new sln

3. Crear un proyecto de biblioteca:

$ dotnet new classlib -n Calculadora.Core

En este crearemos una clase llamada ``Calculadora.cs`` que tendrá el método de la suma de dos números enteros (y que posteriormente pondremos a prueba).

namespace Calculadora.Core;

public class Calculadora
{
    public int Sumar(int a, int b)
    {
        return a + b;
    }
}

4. Crear un proyecto de pruebas:

$ dotnet new xunit -n Calculadora.Tests

En este crearemos una clase ``CalculadoraTests.cs`` donde escribiremos dos métodos para probar el método de suma de la clase anterior.

using Xunit;
using Calculadora.Core; 

namespace Calculadora.Tests;

public class CalculadoraTests
{
    [Fact]
    public void Sumar_DosNumerosEnteros_RetornaSumaCorrecta()
    {
        // Arrange
        var calculadora = new Calculadora.Core.Calculadora(); 
        int a = 3;
        int b = 5;
        int esperado = 8;

        // Act
        int resultado = calculadora.Sumar(a, b);

        // Assert
        Assert.Equal(esperado, resultado);
    }

    [Fact]
    public void Sumar_NumerosNegativos_RetornaSumaCorrecta()
    {
        // Arrange
        var calculadora = new Calculadora.Core.Calculadora(); 
        int a = -2;
        int b = -3;
        int esperado = -5;

        // Act
        int resultado = calculadora.Sumar(a, b);

        // Assert
        Assert.Equal(esperado, resultado);
    }
}

Para los programadores Java que han usado JUnit esto les parecerá familiar.

5. Agregamos ambos proyectos a la solución:

$ dotnet sln add Calculadora.Core/Calculadora.Core.csproj
$ dotnet sln add Calculadora.Tests/Calculadora.Tests.csproj

6. Agregamos una referencia del proyecto Calculadora.Core al proyecto de pruebas Calculadora.Tests:

$ cd Calculadora.Tests
$ dotnet add reference ../Calculadora.Core/Calculadora.Core.csproj

7. Nos ubicamos en la raíz del proyecto (Calculadora):

Calculadora/
├── Calculadora.Core/
│   ├── Calculadora.cs
│   └── Calculadora.Core.csproj
├── Calculadora.Tests/
│   ├── CalculadoraTests.cs
│   └── Calculadora.Tests.csproj
└── Calculadora.sln

8. Abrimos una terminal y ejecutamos la prueba:

$ dotnet test

Salida:

Iniciando la ejecución de pruebas, espere...
1 archivos de prueba en total coincidieron con el patrón especificado.

Correctas! - Con error:     0, Superado:     2, Omitido:     0, Total:     2, Duración: 8 ms - Calculadora.Tests.dll (net8.0)

¡Hemos creado nuestras primeras pruebas unitarias con xUnit!

Si tienes problemas ejecuta estos comandos uo por uno para limpiar, compilar y ejecutar el proyecto:

$ dotnet clean
$ dotnet restore
$ dotnet build
$ dotnet test

Enlaces:

https://learn.microsoft.com/es-es/dotnet/core/testing/unit-testing-csharp-with-xunit
https://es.wikipedia.org/wiki/XUnit
https://xunit.net/?tabs=cs
https://dev.to/maadcode/introduccion-a-xunit-una-poderosa-herramienta-para-unit-testing-en-net-34b0

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/


domingo, 28 de septiembre de 2025

Ktor: un framework para aplicaciones asincrónicas

Ktor es un framework para aplicaciones asincrónicas del lado del servidor y del lado del cliente. Su lenguaje de programación base es Kotlin.

Nos permite crear microservicios hasta todo tipo de aplicaciones cliente HTTP multiplataforma. Veamos un ejemplo de código en Ktor:

fun main() {
	embeddedServer(Netty, port = 8000) {
		routing {
			get ("/") {
				call.respondText("Hola, mundo!")
			}
		}
	}.start(wait = true)
}

¿Cómo comenzar? Simple, iremos al sitio: https://start.ktor.io/

En el Project Artifact colocaremos: com.inforhomex.ktor-helloword

El sitio te permite colocar plugins y ver un preview del proyecto a descargar:

Damos clic en el botón Download para descargar el proyecto. Lo descomprimimos y lo colocamos en algún directorio de nuestra máquina.

Es importante tener Gradle instalado. Pues con este construiremos el proyecto y echaremos a andar.

Abrimos la clase principal del proyecto creado

Application.kt

package com.inforhomex

import io.ktor.server.application.*

fun main(args: Array<String>) {
    io.ktor.server.netty.EngineMain.main(args)
}

fun Application.module() {
    configureRouting()
}

Editamos la clase ``Routing.kt``

package com.inforhomex

import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*

fun Application.configureRouting() {
    routing {
        get("/") {
            call.respondText("Hola, mundo!")
        }
    }
}

Podemos usar Visual Studio Code:

Compilando y ejecutando el proyecto.

Abrimos una terminal y nos ubicamos en el proyecto:

$ gradle build

Con esto construimos el proyecto y ahora lo ejecutamos:

$ gradle run

Si todo va bien, abrimos un navegador en la ruta: http://127.0.0.1:8080

Salida:

Hola, mundo!

¡Hemos creado nuestra primera aplicación sencilla con Ktor!

Continuaremos con este tema en próximas entregas.

Enlaces:

https://ktor.io/


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 ...

Etiquetas

Archivo del blog