Translate

miércoles, 11 de enero de 2023

Pattern matching: las expresiones is y switch, y los operadores and, or y not en C#


Las siguientes expresiones e instrucciones de C# admiten pattern matching:

  • la expresión is 
  • la sentencia switch 
  • y la expresión switch 

En esas construcciones, se puede hacer coincidir una expresión de entrada con cualquiera de los siguientes patrones:

  • Patrón de declaración: para verificar el tipo de tiempo de ejecución de una expresión y, si una coincidencia tiene éxito, asignar un resultado de expresión a una variable declarada.
  • Patrón de tipo: para comprobar el tipo de tiempo de ejecución de una expresión. 
  • Patrón constante: para probar si el resultado de una expresión es igual a una constante especificada.
  • Patrones relacionales: para comparar el resultado de una expresión con una constante especificada. 
  • Patrones lógicos: para probar si una expresión coincide con una combinación lógica de patrones. 
  • Patrón de propiedad: para probar si las propiedades o campos de una expresión coinciden con patrones anidados.
  • Patrón posicional: para deconstruir un resultado de expresión y probar si los valores resultantes coinciden con patrones anidados.
  • patrón var: para hacer coincidir cualquier expresión y asignar su resultado a una variable declarada.
  • Patrón de descarte: para que coincida con cualquier expresión.
  • Patrones de lista: para probar si los elementos de secuencia coinciden con los patrones anidados correspondientes. 
Los patrones lógicos, de propiedad, posicionales y de lista son patrones recursivos. Es decir, pueden contener patrones anidados.

Patrones de tipo y declaración

Se utiliza patrones de declaración y tipo para verificar si el tipo de tiempo de ejecución de una expresión es compatible con un tipo dado. Con un patrón de declaración, también se puede declarar una nueva variable local. Cuando un patrón de declaración coincide con una expresión, a esa variable se le asigna un resultado de expresión convertida, como muestra el siguiente ejemplo:

object greeting = "Hello, World!";
if (greeting is string message)
{
    Console.WriteLine(message.ToLower());  // output: hello, world!
}

Un patrón de declaración con tipo T coincide con una expresión cuando el resultado de una expresión no es nulo y cualquiera de las siguientes condiciones es verdadera:

  • El tipo de tiempo de ejecución de un resultado de expresión es T.
  • El tipo de tiempo de ejecución de un resultado de expresión se deriva del tipo T, implementa la interfaz T o existe otra conversión de referencia implícita a T. El siguiente ejemplo muestra dos casos en los que esta condición sean verdadera:

var numbers = new int[] { 10, 20, 30 };
Console.WriteLine(GetSourceLabel(numbers));  // output: 1

var letters = new List<char> { 'a', 'b', 'c', 'd' };
Console.WriteLine(GetSourceLabel(letters));  // output: 2

static int GetSourceLabel<T>(IEnumerable<T> source) => source switch
{
    Array array => 1,
    ICollection<T> collection => 2,
    _ => 3,
};

En el ejemplo anterior, en la primera llamada al método GetSourceLabel, el primer patrón coincide con un valor de argumento porque el tipo de tiempo de ejecución del argumento int[] se deriva del tipo Array. En la segunda llamada al método GetSourceLabel, el tipo List<T> en tiempo de ejecución del argumento no se deriva del tipo Array pero implementa la interfaz ICollection<T>.

  • El tipo de tiempo de ejecución de un resultado de expresión es un tipo de valor que acepta valores NULL con el tipo T subyacente.
  • Existe una conversión boxing o unboxing del tipo de tiempo de ejecución de un resultado de expresión al tipo T.
El siguiente ejemplo demuestra las dos últimas condiciones:

int? xNullable = 7;
int y = 23;
object yBoxed = y;
if (xNullable is int a && yBoxed is int b)
{
    Console.WriteLine(a + b);  // output: 30
}

Si desea verificar solo el tipo de una expresión, puede usar un descarte _ en lugar del nombre de una variable, como muestra el siguiente ejemplo:

public abstract class Vehicle {}
public class Car : Vehicle {}
public class Truck : Vehicle {}

public static class TollCalculator
{
    public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
    {
        Car _ => 2.00m,
        Truck _ => 7.50m,
        null => throw new ArgumentNullException(nameof(vehicle)),
        _ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
    };
}

A partir de C# 9.0, para ello puede utilizar un patrón de tipo, como muestra el siguiente ejemplo:

public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
{
    Car => 2.00m,
    Truck => 7.50m,
    null => throw new ArgumentNullException(nameof(vehicle)),
    _ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};


Al igual que un patrón de declaración, un patrón de tipo coincide con una expresión cuando el resultado de una expresión no es nulo y su tipo de tiempo de ejecución satisface cualquiera de las condiciones enumeradas anteriormente.

Para verificar si no es nulo, puede usar un patrón constante nulo negado, como muestra el siguiente ejemplo:

if (input is not null)
{
    // ...
}

Bueno, hasta acá con la declaración, en post posteriores seguire con los demas puntos. 


lunes, 9 de enero de 2023

¿Cuál es la diferencia entre openSUSE Leap y Tumbleweed?


En un post posterior, voy a contarles que estoy probando OpenSuse, lo que sucedio es que a la hora de bajarlo, me preguntaba cual quería si Leap o Tumbleweed. Y que se yo? no tenia idea en que radicaba la diferencia. Por lo tanto, decidí investigar un poco y dejo lo que encontré aquí, 

La principal diferencia entre los dos es el calendario de lanzamiento. openSUSE Leap lanza una nueva versión cada pocos años en un horario establecido, similar a Ubuntu y Fedora. Tumbleweed, por otro lado, es una versión móvil que, como Arch o Void, sigue el ciclo de desarrollo de openSUSE.

Conclusión si te interesa tener lo ultimo que salio rápidamente Tumbleweed y si te interesa la estabilidad Leap. 

Y eso es todo... 

sábado, 7 de enero de 2023

Foldable y Traverse parte 4

Cada método en Foldable está disponible en forma de sintaxis a través de cats.syntax.foldable. En cada caso, el primer argumento del método en Foldable se convierte en el receptor de la llamada al método:


import cats.syntax.foldable._ // for combineAll and foldMap

List(1, 2, 3).combineAll

// res12: Int = 6

List(1, 2, 3).foldMap(_.toString)

// res13: String = "123"


Recuerde que Scala solo usará una instancia de Foldable si el método no está explícitamente disponible en el receptor. Por ejemplo, el siguiente código usará la versión de foldLeft definida en List:


List(1, 2, 3).foldLeft(0)(_ + _)

// res14: Int = 6


mientras que el siguiente código genérico utilizará Foldable:


def sum[F[_]: Foldable](values: F[Int]): Int = values.foldLeft(0)(_ + _)


Por lo general, no necesitamos preocuparnos por esta distinción. ¡Es una característica! Llamamos al método que queremos y el compilador usa un Foldable cuando es necesario para garantizar que nuestro código funcione como se espera. Si necesitamos una implementación segura de pila de foldRight, usar Eval como acumulador es suficiente para obligar al compilador a seleccionar el método de Cats.


viernes, 6 de enero de 2023

Probando linux zorin

Sigo probando linux y ahora estoy probando Zorin y para ser sincero, no me gusto. No encuentro mucha diferencias con ubuntu, es más no entiendo porque una persona elegiría esta distro, no aporta casi nada nuevo. Ojo estoy probando la versión gratuita. 

Es decir, es linda distro, esta bueno el menú, los temas y las demás aplicaciones pero no brinda un salto a algo diferente, se queda con retoques a ubuntu y nada más. 

Pero bueno, véanlo por ustedes mismos: 









Dejo link: https://zorin.com/os/


miércoles, 4 de enero de 2023

Uso de Roslyn C# Completion Service programáticamente


Roslyn es un compilador C# como servicio seria CaaS 

El CompletionService de Roslyn inicialmente no estaba disponible públicamente, y la única forma de lograr mediante programación una experiencia similar a Intellisense era utilizar el servicio de recomendación bastante limitado. CompletionService finalmente se expuso públicamente en Roslyn 1.3.0.

Vamos a hacer un ejemplo para ver lo poderoso que puede ser esto. Para empezar, necesitaremos hacer referencia a 2 paquetes de Roslyn Nuget, como se muestra a continuación (nuestro archivo csproj de prueba):


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>

    <OutputType>Exe</OutputType>

    <LangVersion>latest</LangVersion>

    <TargetFramework>netcoreapp2.1</TargetFramework>

  </PropertyGroup>


  <ItemGroup>

    <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="2.10.0" />

    <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="2.10.0" />

  </ItemGroup>

</Project>


Y necesitamos algún código para probar nuestras funciones, el siguiente ejemplo sirve: 


using System;


public class MyClass

{

    public static void MyMethod(int value)

    {

        Guid.

    }

}


Entonces, si imaginamos la experiencia del usuario aquí, nos ponemos en el lugar del usuario, escribimos Guid, presionamos un . carácter y ahora están esperando todos los métodos relevantes en este contexto particular.

En Visual Studio/Visual Studio Code (a través de OmniSharp), esta lista se mostraría automáticamente. En caso de que se haya cerrado, por ejemplo, al presionar la tecla ESC, siempre puede volver a activarlo presionando ctrl+j (VS) o ctrl/cmd+espacio (VS Code).

Para empezar, conectemos los servicios MEF de Roslyn, ya que deben completarse para que los servicios del lenguaje C# funcionen correctamente.

La forma más fácil es simplemente usar el conjunto predeterminado:

var host = MefHostServices.Create(MefHostServices.DefaultAssemblies);

Los siguientes asemblies están incluidos en el conjunto predeterminado:

  • “Microsoft.CodeAnalysis.Workspaces”,
  • “Microsoft.CodeAnalysis.CSharp.Workspaces”,
  • “Microsoft.CodeAnalysis.VisualBasic.Workspaces”,
  • “Microsoft.CodeAnalysis.Features”,
  • “Microsoft.CodeAnalysis.CSharp.Features”,
  • “Microsoft.CodeAnalysis.VisualBasic.Features”
  • Si tiene alguna extensión para Roslyn o características personalizadas de Roslyn de terceros que le gustaría incluir, deberá pasar esos ensamblajes adicionales manualmente.

    Una vez que los servicios de MEF están conectados, el siguiente paso es crear un espacio de trabajo. En esta demostración, solo usaremos un AdHocWorkspace.

    Para escenarios más complicados, como, por ejemplo, poder proporcionar inteligencia completa a una solución del mundo real o proyecto (s) de csproj, deberíamos de usar Microsoft.CodeAnalysis.Workspaces.MSBuild 

    Así que para nosotros el código será bastante simple:

    var workspace = new AdhocWorkspace(host);

    Una vez que el espacio de trabajo está allí, debemos crear un documento que contenga nuestro código y luego un proyecto al que agregaremos nuestro documento (o documentos, si tenemos más). Luego, el proyecto debe agregarse al espacio de trabajo. Nuevamente, en el caso de MsBuildWorkspace, esto se puede hacer automáticamente leyendo los archivos del proyecto y su estructura.

    En nuestro ejemplo, las cosas se verían así:


    var code = @"using System;


    public class MyClass

    {

        public static void MyMethod(int value)

        {

            Guid.

        }

    }";


    var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "MyProject", "MyProject", LanguageNames.CSharp).

       WithMetadataReferences(new[]

       { 

           MetadataReference.CreateFromFile(typeof(object).Assembly.Location)

       });

    var project = workspace.AddProject(projectInfo);

    var document = workspace.AddDocument(project.Id, "MyFile.cs", SourceText.From(code));


    Para crear un proyecto, primero creamos un ProjectInfo, donde debemos pasar cosas como el nombre del proyecto, el nombre del ensamblado (en nuestro caso, "MyProject"), el tipo de lenguaje y un par de cosas más relevantes para la compilación, principalmente las MetadataReferences necesarias para que se construya nuestro código. En nuestro caso, es realmente solo el corlib, o en otras palabras, el ensamblaje del objeto.

    Se crea una instancia de Proyecto para nosotros como resultado de agregar ProjectInfo al espacio de trabajo. De manera similar, también se crea una instancia de documento para nosotros cuando solicitamos que se agregue un código basado en cadenas determinado al área de trabajo, en el contexto de una ID de proyecto determinada.

    Una vez que tenemos el Documento que es parte del Área de trabajo, podemos comenzar a usar el Servicio. Tiene un método de fábrica que podemos usar, y solo necesitamos pasar en la posición relevante en el código (para nosotros Guid.) para que las terminaciones comiencen a aparecer:


    // position is the last occurrence of "Guid." in our test code

    // in real life scenarios the editor surface should inform us

    // about the current cursor position

    var position = code.LastIndexOf("Guid.") + 5;

    var completionService = CompletionService.GetService(document);

    var results = await completionService.GetCompletionsAsync(document, position);


    En ese punto obtenemos nulo si no hay finalizaciones que tengan sentido para el compilador, o una buena lista de elementos de finalizaciones que podemos inspeccionar y mostrar al usuario.

    Los elementos se agrupan en diferentes categorías, representadas por etiquetas. Esto puede ayudar al editor a visualizar con qué tipo de elemento de finalización se trata. Estos podrían ser, por ejemplo, el tipo de símbolo (campo, método, etc.), el nivel de accesibilidad (público, interno, etc.) o cualquier otra información (¿es una palabra clave del lenguaje? ¿Quizás por un parámetro en el ámbito dado? etc.).

    Cada elemento de finalización se nos proporciona con DisplayText, que el editor debe usar para presentar la sugerencia al usuario, y SortText, que se puede usar para clasificar, así como otros metadatos útiles adicionales.

    Cada elemento de finalización se origina en un determinado CompletionProvider, porque el propio servicio de finalización en realidad agrega los resultados de un conjunto de esos proveedores que están conectados al host MEF. Algunos de ellos son muy especializados, por ejemplo, OverrideCompletionProvider, que permite proporcionar terminaciones cuando el usuario escribe anular.

    Dado que CompletionProvider es público, también puede implementar el suyo propio y personalizar completamente el proceso de finalización en Roslyn.

    De todos modos, por ahora, imprimamos lo que obtuvimos de Roslyn en esta configuración de demostración en particular. 


    foreach (var i in results.Items)

    {

        Console.WriteLine(i.DisplayText);


        foreach (var prop in i.Properties)

        {

            Console.Write($"{prop.Key}:{prop.Value}  ");

        }


        Console.WriteLine();

        foreach (var tag in i.Tags)

        {

            Console.Write($"{tag}  ");

        }


        Console.WriteLine();

        Console.WriteLine();

    }


    Si ejecutamos nuestro programa ahora, la salida debería verse así:


    Empty

    ContextPosition:166  SymbolKind:6  InsertionText:Empty  Provider:Microsoft.CodeAnalysis.CSharp.Completion.Providers.SymbolCompletionProvider  SymbolName:Empty

    Field  Public


    Equals

    ContextPosition:166  SymbolKind:9  InsertionText:Equals  Provider:Microsoft.CodeAnalysis.CSharp.Completion.Providers.SymbolCompletionProvider  SymbolName:Equals

    Method  Public


    NewGuid

    ContextPosition:166  SymbolKind:9  InsertionText:NewGuid  Provider:Microsoft.CodeAnalysis.CSharp.Completion.Providers.SymbolCompletionProvider  SymbolName:NewGuid

    Method  Public


    Parse

    ContextPosition:166  SymbolKind:9  InsertionText:Parse  Provider:Microsoft.CodeAnalysis.CSharp.Completion.Providers.SymbolCompletionProvider  SymbolName:Parse

    Method  Public


    ParseExact

    ContextPosition:166  SymbolKind:9  InsertionText:ParseExact  Provider:Microsoft.CodeAnalysis.CSharp.Completion.Providers.SymbolCompletionProvider  SymbolName:ParseExact

    Method  Public


    ReferenceEquals

    ContextPosition:166  SymbolKind:9  InsertionText:ReferenceEquals  Provider:Microsoft.CodeAnalysis.CSharp.Completion.Providers.SymbolCompletionProvider  SymbolName:ReferenceEquals

    Method  Public


    TryParse

    ContextPosition:166  SymbolKind:9  InsertionText:TryParse  Provider:Microsoft.CodeAnalysis.CSharp.Completion.Providers.SymbolCompletionProvider  SymbolName:TryParse

    Method  Public


    TryParseExact

    ContextPosition:166  SymbolKind:9  InsertionText:TryParseExact  Provider:Microsoft.CodeAnalysis.CSharp.Completion.Providers.SymbolCompletionProvider  SymbolName:TryParseExact

    Method  Public


    Tenga en cuenta que obtenemos todos los métodos/propiedades/campos relevantes que esperaríamos. Cada elemento de finalización tiene la información adicional en las etiquetas. Además, hay algunos metadatos adicionales en el diccionario de propiedades, como por ejemplo el tipo de proveedor que se usó para proporcionar esta finalización (aunque en nuestro caso, todos terminan siendo de SymbolCompletionProvider).

    Hasta ahora, el enfoque se basaba en código C# completo. Esto funciona para la mayoría de los escenarios, sin embargo, para situaciones en las que no se trata de proyectos de C# completos o archivos de código, sino que le gustaría completar fragmentos ligeros, no sería aplicable.

    Imagine que queremos obtener exactamente el mismo conjunto de resultados de finalización que el anterior, pero ya cuando el usuario simplemente escribió:

    Guid.

    Entonces, sin clase, sin método, sin usos, solo 5 caracteres. Esto es especialmente atractivo para experiencias similares a REPL o pequeños fragmentos de código incrustados en alguna parte.

    Resulta que este nivel de finalización también se puede lograr con Roslyn, cuando pasamos a su modo de "guión".

    Fundamentalmente, nuestro código sería el mismo, crearíamos el host MEF y el espacio de trabajo de la misma manera. Sin embargo, al crear el Proyecto y el Documento, debemos decirle al compilador que analice nuestro código como el llamado SourceCodeKind.Script. Esto se muestra a continuación:


    var scriptCode = "Guid.N";


    var compilationOptions = new CSharpCompilationOptions(

       OutputKind.DynamicallyLinkedLibrary,

       usings: new[] { "System" });

                       

    var scriptProjectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "Script", "Script", LanguageNames.CSharp, isSubmission: true)

       .WithMetadataReferences(new[] 

       { 

           MetadataReference.CreateFromFile(typeof(object).Assembly.Location) 

       })

       .WithCompilationOptions(compilationOptions);


    var scriptProject = workspace.AddProject(scriptProjectInfo);

    var scriptDocumentInfo = DocumentInfo.Create(

        DocumentId.CreateNewId(scriptProject.Id), "Script",

        sourceCodeKind: SourceCodeKind.Script,

        loader: TextLoader.From(TextAndVersion.Create(SourceText.From(scriptCode), VersionStamp.Create())));

    var scriptDocument = workspace.AddDocument(scriptDocumentInfo);


    // cursor position is at the end

    var position = scriptCode.Length - 1;


    var completionService = CompletionService.GetService(scriptDocument);

    var results = await completionService.GetCompletionsAsync(scriptDocument, position);


    Las API que llamamos son en su mayoría las mismas, con las mismas pequeñas diferencias que son las siguientes:

    – necesitamos crear una versión personalizada de CSharpCompilationOptions, que luego pasamos a nuestro ProjectInfo. Esto es necesario para que configuremos un proyecto con un conjunto global de instrucciones de uso. En nuestro caso, es solo System (para que el usuario no tenga que escribir System.Guid.), pero podría ser más para permitir esta experiencia de finalización sin importación para una gama más amplia de tipos.

    – al crear nuestro Documento, configuramos un DocumentInfo extra. La relación entre ellos es la misma que entre Project y ProjectInfo. Esto será necesario para pasar del analizador C# normal al script. Nos permitirá procesar nuestro código sintácticamente relajado sin encontrarnos con los errores del compilador que de otro modo nos bloquearían.

    Y eso es todo: el resultado aquí es exactamente el mismo que antes, excepto que logramos proporcionar las terminaciones utilizando la entrada de C# de una sola línea, liviana y de poca ceremonia, que creo que es bastante impresionante.

    Espero que esto haya sido interesante, y tal vez incluso un poco útil. Avíseme si desea profundizar en este tema o conocer otros componentes básicos de Roslyn, especialmente en el área de servicios de lenguaje C#.

    martes, 3 de enero de 2023

    Echo, Framework web de alto rendimiento, extensible y minimalista para Golang


    Echo, es un framework web para golang que nos brinda : 

    • Enrutador HTTP altamente optimizado con asignación de memoria dinámica cero que prioriza rutas de manera inteligente.
    • Creación de un API RESTful robusta y escalable, fácilmente organizada en grupos.
    • Se puede instalar automáticamente certificados TLS de Let's Encrypt.
    • La compatibilidad con HTTP/2 mejora la velocidad y proporciona una mejor experiencia de usuario.
    • Muchos middleware integrados para usar o definir el suyo propio. El middleware se puede configurar a nivel de raíz, grupo o ruta.
    • Enlace de datos para la carga útil de la solicitud HTTP, incluidos JSON, XML o datos de formulario.
    • API para enviar una variedad de respuestas HTTP, incluidos JSON, XML, HTML, archivo, adjunto, en línea, flujo o blob.
    • Representación de plantillas utilizando cualquier motor de plantillas
    • Manejo de errores HTTP central personalizado. API fácilmente extensible.


    Muy lindo todo pero la idea es hacer un hola mundo, veamos. 


    Para instalar se requiere Echo Go v1.13 o superior. Go v1.12 tiene soporte limitado y algunos middlewares no estarán disponibles. Asegúrese de que la carpeta de su proyecto esté fuera de su $GOPATH.


    $ mkdir myapp && cd myapp

    $ go mod init myapp

    $ go get github.com/labstack/echo/v4


    Si está trabajando con Go v1.14 o anterior, use:


    $ GO111MODULE=on go get github.com/labstack/echo/v4

    Veamos exponer un servicio enel golang : 

    package main

    import (
    "net/http"
    "github.com/labstack/echo/v4"
    )

    func main() {
    e := echo.New()
    e.GET("/", func(c echo.Context) error {
    return c.String(http.StatusOK, "Hello, World!")
    })
    e.Logger.Fatal(e.Start(":1323"))
    }

    Y lo corremos de esta manera : 

    $ go run server.go

    Dejo link: https://echo.labstack.com/

    sábado, 31 de diciembre de 2022

    Feliz Navidad y buen año para todos!!

     


    Como todos los años les deseo una feliz navidad y un buen 2022. Ojo me quedaron unos post por terminar, así que vengan antes de enero... No me voy de vacaciones :D

    Fue un año duro, pero que trajo buenos cambios... 


    Gracias por leerme! 

    viernes, 30 de diciembre de 2022

    ¿Cuáles son los mejores frameworks para hacer una API REST con Golang?


    Se puede crear una API REST sin framework, pero los framework son herramientas poderosas, creadas para ofrecer al usuario formas simplificadas de hacer las cosas, en este caso: API REST. Un framework es esencialmente una herramienta creada para un propósito con funciones y bibliotecas. Como está preconstruido, también puede estar seguro de que funciona y elimina la necesidad de hacer codigo repetitivo uno mismo. 

    La mayoría de los proyectos eligen el frameworks adecuado en algún momento. Dado que Go es igualmente adecuado para proyectos empresariales y pequeños, solo tiene que elegir una biblioteca coincidente para crear una API tranquila con Golang. La elección puede ser un desafío, ya que Go ha existido lo suficiente como para tener numerosas soluciones disponibles. Veamos algunas de las opciones más populares.


    Gin: Framework rápido para construir REST API con Go

    Gin Web Framework permite crear aplicaciones web y microservicios en Golang. Se basa en una API similar a la de Martini, pero afirma ser 40 veces más rápida. 

    La biblioteca de Gin es minimalista y solo admite las funciones más esenciales, lo que la hace ligera y apropiada incluso para sistemas con potencia limitada.

    Gin es rápido, ya que utiliza el enrutamiento basado en árboles radix para acelerar las cosas. También puede agrupar diferentes rutas, es decir, diferentes versiones de API. Esto se puede hacer infinitamente sin ninguna degradación en el rendimiento.

    El soporte de middleware también es crucial porque permite que varios middleware manejen una solicitud HTTP entrante. Por lo tanto, es posible usar primero el registrador, luego la autorización y, al final, manejar la solicitud en sí. Crear su propio middleware también es un trabajo fácil.

    Empezar a usar Gin es mucho más sencillo con su completa documentación. Gracias a esto, incluso los principiantes pueden aprender a usarlo rápidamente, y el manejo de errores/problemas es mucho más simple.

    Formatos de datos admitidos: JSON, XML y HTML.

    Gin es genuinamente minimalista, y para extenderlo, tendrías que usar soluciones de terceros. Está bien si puede encontrar algunos que estén bien respaldados y sean confiables, pero en general, este es un aspecto complicado.


    Beego – Framework web de Golang enfocado en alto rendimiento y modularidad

    Beego es un framework de código abierto que ofrece una amplia gama de características cuando el código base se mantiene relativamente pequeño. Está construido teniendo en cuenta la modularidad, lo que significa que contiene 8 módulos acoplados libremente que se pueden usar de forma independiente o como un conjunto. También sigue una arquitectura MVC.

    Estos 2 factores lo hacen perfecto para aplicaciones empresariales que necesitan flexibilidad y limitar sus dependencias de recursos de terceros.

    Beego ofrece numerosas funciones. Incluye registradores, almacenamiento en caché o incluso una herramienta de línea de comandos. Pero no solo eso, también es compatible con un ORM listo para usar. El uso de ORM hace que la integración de una base de datos con sesiones o funciones de registro sea mucho más fácil. Además, puede monitorear su QPS junto con el uso de CPU y memoria.

    El uso del paquete Go HTTP nativo lo hace rápido y eficiente. Gracias a esto, una aplicación creada con Beego puede manejar un tráfico tremendo. Es otra variable que lo hace adecuado para proyectos de gran envergadura.

    ¿Y si encuentra algún problema? No es para preocuparse. Beego tiene un gran apoyo de la comunidad y, por lo tanto, es fácil encontrar una solución a un error.

    Beego puede ser simplemente demasiado grande y tiene demasiadas funciones para que un principiante las aprenda. Por lo tanto, está destinado a programadores de Golang más avanzados.

    Desafortunadamente, este marco puede ser una exageración para un proyecto pequeño: el requisito de la arquitectura MVC y el avance general de este marco Golang podrían ser demasiado para una API REST simple.


    Echo: un marco tranquilo simple pero extensible para Go

    Echo framework es minimalista en su esencia, pero también es fácilmente extensible. Por lo tanto, este marco es escalable y se puede utilizar para proyectos pequeños y grandes.

    La cualidad más considerable de Echo es un enrutador HTTP refinado sin asignación de memoria dinámica. El enrutador es excelente para priorizar rutas de manera inteligente.

    Una funcionalidad interesante de Echo es la instalación automática de certificados TSL de Let's Encrypt. El uso de plantillas es otro: esta función le permite utilizar cualquier motor de plantillas para representar plantillas con Echo.

    Aparte de eso, Echo es compatible con HTTP/2, lo que mejora la velocidad y brinda una mejor experiencia de usuario. Contiene una gran cantidad de middleware útil listo para usar para que sea más útil. Además, permite a los desarrolladores escribir los suyos propios.

    Los desarrolladores de Echo cuidan mucho la documentación; este aspecto siempre es una excelente combinación para proyectos grandes o pequeños. Una buena documentación significa que debería ser más fácil resolver cualquier problema o error.

    Formatos de datos admitidos: JSON, XML, HTML, Archivo, Adjunto, En línea, Stream o Blob.


    Chi: cree una API REST que se adapte a sus requisitos

    Chi es un enrutador liviano para construir API RESTful. Su objetivo principal es admitir grandes servicios de API REST y ser componible para crecer.

    Chi funciona con net/HTTP. Puede utilizar cualquier paquete HTTP o middleware compatible con net/HTTP. Esto viene con otro activo: no se requieren dependencias externas, ya que Chi se basa en el paquete Go stdlib + net/HTTP. De esta manera, no corre el riesgo de tener problemas causados por la falta de soporte de implementaciones de terceros.

    Chi fue diseñado para API modulares/componibles. Puede agregar y usar middlewares, middlewares en línea, grupos de rutas y montaje de subenrutadores.

    Al usar todas las funciones anteriores, Chi le permite generar documentación API a través de docgen (un subpaquete de Chi). Genera documentación de enrutamiento desde la fuente a JSON o Markdown. ¡Automáticamente!

    Su enrutamiento puede ser mucho más flexible, ya que Chi admite variables en rutas de URL y patrones de ruta de expresiones regulares. Y cuando se trata de rutas, es imposible dejar de lado la capacidad de agrupar rutas que usan el mismo middleware. Ayuda a mantener el código limpio y administrar rutas en aplicaciones más extensas.

    Hay un factor a considerar al construir una API pública. Chi no configura automáticamente un encabezado. Otra desventaja es la compatibilidad con versiones anteriores. Claramente, no es una prioridad para los desarrolladores de Chi: es algo a tener en cuenta al elegir Chi para un proyecto de larga duración.

    Estas son las opciones que conozco, ustedes me pueden ayudar con otras? Que framework usan??  

    jueves, 29 de diciembre de 2022

    Probando linux deepin

     Hace rato que no pruebo distros de linux y deepin ya la probé hace tiempo y me gusto. Es más la use varios años y ahora voy a probar su ultima versión que me gusto mucho. 

    Pero bueno, véanlo por ustedes mismos: 










    [eBook] Add Security to Your Amazon EKS with NGINX

     

    EBOOK

    [eBook] Add Security to Your Amazon EKS with NGINX

    Hi Emanuel,

    Keeping applications secure can be one of the most daunting—and critical—challenges for any enterprise to figure out. Attempts to breach security happen thousands of times a day. The speed at which applications are now developed comes with a challenge: how can you keep up with the need to check apps when developers outnumber security pros 500:1?

    Discover how you can prevent security breaches with NGINX and AWS. Learn how to protect your apps in an Amazon Elastic Kubernetes Service (Amazon EKS) deployment from a range of threats, including the OWASP Top 10 and beyond.

    In this eBook you will learn:

    • Five ways NGINX Plus can help your organization mitigate vulnerabilities faster and easier 
    • How NGINX App Protect easily integrates with the NGINX Ingress Controller to secure your Kubernetes apps at scale
    • Why moving a WAF closer to the modern apps it protects can prevent a security breach

    miércoles, 28 de diciembre de 2022

    Resty, un cliente rest simple para Golang

     


    Resty, es un cliente simple para consultar Apis http. Tiene muchas características :

    • Todos los métodos http: GET, POST, PUT, DELETE, HEAD, PATCH, OPTIONS, etc.
    • Métodos simples y encadenables para configuraciones y solicitudes.
    • El cuerpo de la solicitud puede ser una cadena, [] byte, estructura, mapa, segmento e io.Reader también detecta automáticamente el tipo de contenido
    • Procesamiento sin búfer para io.Reader
    • Se puede acceder a la instancia *http.Request nativa durante la ejecución del middleware y la solicitud a través de Request.RawRequest
    • El cuerpo de la solicitud se puede leer varias veces a través de Request.RawRequest.GetBody()
    • Acceso como matriz de []bytes - respuesta.Cuerpo() O Acceso como cadena - respuesta.Cadena()
    • Clasificación y desclasificación automáticas para el tipo de contenido JSON y XML
    • El valor predeterminado es JSON, si proporciona estructura/mapa sin encabezado Content-Type
    • Compatible con RFC7807: application/problem+json & application/problem+xml
    • Resty proporciona una opción para anular JSON Marshal/Unmarshal y XML Marshal/Unmarshal
    • Fácil de cargar uno o más archivos a través de multipart/form-data
    • Detecta automáticamente el tipo de contenido del archivo
    • Solicitud de parámetros de ruta de URL (también conocidos como parámetros de URI)
    • Mecanismo de reintento de retroceso con referencia de función de condición de reintento
    • Middleware de solicitud y respuesta HTTP y REST del cliente Resty
    • Solicitud.SetContext compatible
    • Opción de autorización de BasicAuth y Bearer token
    • Establecer el valor de ContentLength de solicitud para todas las solicitudes o solicitudes en particular
    • Certificados raíz personalizados y certificados de cliente
    • Descargue/guarde la respuesta HTTP directamente en el archivo, como el indicador curl -o. Consulte SetOutputDirectory y SetOutput.
    • Cookies para su solicitud y soporte de CookieJar
    • Solicitud basada en registro SRV en lugar de URL de host
    • Configuración del cliente como Tiempo de espera, RedirectPolicy, Proxy, TLSClientConfig, Transporte, etc.
    • Opcionalmente, permite la solicitud GET con carga útil
    • Admite el registro de la biblioteca JSON externa en Resty
    • Expone el lector de respuestas sin leer la respuesta (sin desarme automático) si es necesario
    • Opción para especificar el tipo de contenido esperado cuando falta el encabezado del tipo de contenido de respuesta. 
    • Admite la implementación de http.RoundTripper
    • seguridad concurrente con goroutine
    • Seguimiento podemos usar Client.EnableTrace y Request.EnableTrace
    • Desde v2.4.0, la información de seguimiento contiene un valor de RequestAttempt y el objeto Request contiene un atributo de intento.
    • Modo de depuración
    • Funciona con HTTP/2 y HTTP/1.1
    Puf un monton y si llegaste hasta aca leyendo, te felicito. Ahora vamos a ver un ejemplo, imprimir datos de la api de github : 

    package main

    import (
    "bufio"
    "fmt"
    "github.com/go-resty/resty/v2"
    "os"
    "strings"
    )

    func main() {
    fmt.Println("Ingrese el usuario de github : ")

    reader := bufio.NewReader(os.Stdin)
    user, _ := reader.ReadString('\n')
    user = strings.ReplaceAll(user, "\n", "")

    url := "https://api.github.com/users/" + user

    // Create a Resty Client
    client := resty.New()

    resp, err := client.R().
    EnableTrace().
    Get(url)

    if err != nil {
    fmt.Println(err.Error())
    } else {
    fmt.Println("  Status Code:", resp.StatusCode())
    fmt.Println("  Status     :", resp.Status())
    fmt.Println("  Proto      :", resp.Proto())
    fmt.Println("  Time       :", resp.Time())
    fmt.Println("  Received At:", resp.ReceivedAt())
    fmt.Println("  Body       :\n", resp)
    fmt.Println()
    // Explore trace info
    fmt.Println("Request Trace Info:")
    ti := resp.Request.TraceInfo()
    fmt.Println("  DNSLookup     :", ti.DNSLookup)
    fmt.Println("  ConnTime      :", ti.ConnTime)
    fmt.Println("  TCPConnTime   :", ti.TCPConnTime)
    fmt.Println("  TLSHandshake  :", ti.TLSHandshake)
    fmt.Println("  ServerTime    :", ti.ServerTime)
    fmt.Println("  ResponseTime  :", ti.ResponseTime)
    fmt.Println("  TotalTime     :", ti.TotalTime)
    fmt.Println("  IsConnReused  :", ti.IsConnReused)
    fmt.Println("  IsConnWasIdle :", ti.IsConnWasIdle)
    fmt.Println("  ConnIdleTime  :", ti.ConnIdleTime)
    fmt.Println("  RequestAttempt:", ti.RequestAttempt)
    fmt.Println("  RemoteAddr    :", ti.RemoteAddr.String())
    }

    }

    Y si ingresamos emanuelpeg por ejemplo obtendremos : 

    Ingrese el usuario de github : 

    emanuelpeg

      Status Code: 200

      Status     : 200 OK

      Proto      : HTTP/2.0

      Time       : 365.365001ms

      Received At: 2022-12-28 16:25:37.481908946 -0300 -03 m=+9.137266439

      Body       :

     {"login":"emanuelpeg","id":1281319,"node_id":"MDQ6VXNlcjEyODEzMTk=","avatar_url":"https://avatars.githubusercontent.com/u/1281319?v=4","gravatar_id":"","url":"https://api.github.com/users/emanuelpeg","html_url":"https://github.com/emanuelpeg","followers_url":"https://api.github.com/users/emanuelpeg/followers","following_url":"https://api.github.com/users/emanuelpeg/following{/other_user}","gists_url":"https://api.github.com/users/emanuelpeg/gists{/gist_id}","starred_url":"https://api.github.com/users/emanuelpeg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/emanuelpeg/subscriptions","organizations_url":"https://api.github.com/users/emanuelpeg/orgs","repos_url":"https://api.github.com/users/emanuelpeg/repos","events_url":"https://api.github.com/users/emanuelpeg/events{/privacy}","received_events_url":"https://api.github.com/users/emanuelpeg/received_events","type":"User","site_admin":false,"name":"Emanuel","company":"assembly","blog":"http://emanuelpeg.blogspot.com/","location":"Crespo","email":null,"hireable":null,"bio":null,"twitter_username":null,"public_repos":51,"public_gists":19,"followers":15,"following":9,"created_at":"2011-12-23T03:12:26Z","updated_at":"2022-12-12T19:06:19Z"}


    Request Trace Info:

      DNSLookup     : 33.874537ms

      ConnTime      : 165.492638ms

      TCPConnTime   : 48.333281ms

      TLSHandshake  : 83.032505ms

      ServerTime    : 199.757211ms

      ResponseTime  : 274.029µs

      TotalTime     : 365.365001ms

      IsConnReused  : false

      IsConnWasIdle : false

      ConnIdleTime  : 0s

      RequestAttempt: 1

      RemoteAddr    : 20.201.28.148:443


    Process finished with the exit code 0


    Y Listo!! 


    martes, 27 de diciembre de 2022

    Foldable y Traverse parte 3

     Foldable define foldRight de manera diferente a foldLeft, en términos de la mónada Eval:


    def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B]


    El uso de Eval significa que el plegado siempre es seguro para la pila, incluso cuando la definición predeterminada de foldRight de la colección no lo es. Por ejemplo, la implementación predeterminada de foldRight para LazyList no es segura a nivel de pila. Cuanto más larga sea la lista perezosa, mayores serán los requisitos de pila para el pliegue. Una lista perezosa lo suficientemente grande provocará un StackOverflowError:


    import cats.Eval

    import cats.Foldable

    def bigData = (1 to 100000).to(LazyList)

    bigData.foldRight(0L)(_ + _)

    // java.lang.StackOverflowError ...


    El uso de Foldable nos obliga a usar operaciones seguras de pila, lo que corrige la excepción de desbordamiento:


    import cats.instances.lazyList._ // for Foldable

    val eval: Eval[Long] =

        Foldable[LazyList].

            foldRight(bigData, Eval.now(0L)) { (num, eval) =>

                eval.map(_ + num)

            }

    eval.value

    // res3: Long = 5000050000L


    Foldable nos proporciona una gran cantidad de métodos útiles definidos en la parte superior de foldLeft. Muchos de estos son facsímiles de métodos familiares de la biblioteca estándar: find, exist, forall, toList, isEmpty, nonEmpty, etc.

    Además de estos métodos familiares, Cats proporciona dos métodos que hacen uso de Monoids:

    • combineAll (y su alias fold) combina todos los elementos en la secuencia usando su Monoid;
    • foldMap mapea una función proporcionada por el usuario sobre la secuencia y combina los resultados usando un Monoid.

    Por ejemplo, podemos usar combineAll para sumar sobre List[Int]:


    import cats.instances.int._ // for Monoid

    Foldable[List].combineAll(List(1, 2, 3))

    // res8: Int = 6


    Alternativamente, podemos usar foldMap para convertir cada Int en un String y concatenarlos:


    import cats.instances.string._ // for Monoid

    Foldable[List].foldMap(List(1, 2, 3))(_.toString)

    // res9: String = "123"


    Finalmente, podemos componer Foldables para admitir un recorrido profundo de secuencias anidadas:


    import cats.instances.vector._ // for Monoid

    val ints = List(Vector(1, 2, 3), Vector(4, 5, 6))

    (Foldable[List] compose Foldable[Vector]).combineAll(ints)

    // res11: Int = 21


    lunes, 26 de diciembre de 2022

    Foldable y Traverse parte 2

    Foldable en cats es un type class que contiene el método foldLeft y foldRight. Las instancias de Foldable definen estos dos métodos y heredan una serie de métodos derivados. Cats proporciona instancias listas para usar de Foldable para un puñado de tipos de datos de Scala: List, Vector, LazyList y Option.

    Podemos invocar instancias como de costumbre usando Foldable.apply y llamar directamente a sus implementaciones de foldLeft. Aquí hay un ejemplo usando List:


    import cats.Foldable

    import cats.instances.list._ // for Foldable

    val ints = List(1, 2, 3)

    Foldable[List].foldLeft(ints, 0)(_ + _)

    // res0: Int = 6


    Otras secuencias como Vector y LazyList funcionan de la misma manera. Aquí hay un ejemplo usando Option, que se trata como una secuencia de cero o uno elementos:


    import cats.instances.option._ // for Foldable

    val maybeInt = Option(123)

    Foldable[Option].foldLeft(maybeInt, 10)(_ * _)

    // res1: Int = 1230



    sábado, 24 de diciembre de 2022

    Obtener un tipo desde un string en C#


    Post cortito, necesitaba por X motivo obtener un tipo desde un string y esto es tan fácil como hacer 


    var myType  = Type.GetType(string);


    Y luego con el tipo podes utilizar reflexión para saber si tiene constructores, si es una clase, etc. 


    Dejo link : https://learn.microsoft.com/en-us/dotnet/api/system.type.gettype?view=net-7.0

    martes, 20 de diciembre de 2022

    Foldable y Traverse

    La clase de tipo Foldable captura los métodos foldLeft y foldRight a los que estamos acostumbrados en secuencias como Lists, Vectors, y Streams. Usando Foldable, podemos escribir pliegues genéricos que funcionan con una variedad de tipos de secuencias. También podemos inventar nuevas secuencias y conectarlas a nuestro código.

    Foldable nos brinda excelentes casos de uso para Monoids y la mónada Eval.

    Comencemos con un resumen rápido del concepto general de plegado. Suministramos un valor acumulador y una función binaria para combinarlo con cada elemento de la secuencia:


    def show[A](list: List[A]): String =

        list.foldLeft("nil")((accum, item) => s"$item then $accum")

    show(Nil)

    // res0: String = "nil"

    show(List(1, 2, 3))

    // res1: String = "3 then 2 then 1 then nil"


    El método foldLeft funciona recursivamente en la secuencia. Nuestra función binaria se llama repetidamente para cada elemento, y el resultado de cada llamada se convierte en el acumulador de la siguiente. Cuando llegamos al final de la secuencia, el acumulador final se convierte en nuestro resultado final.

    Dependiendo de la operación que estemos realizando, el orden en el que plegamos puede ser importante. Debido a esto, hay dos variantes estándar de pliegue:

    • foldLeft atraviesa de "izquierda" a "derecha" (de principio a fin);
    • foldRight atraviesa de "derecha" a "izquierda" (de fin a principio).

    foldLeft y foldRight son equivalentes si nuestra operación binaria es asociativa.

    Por ejemplo, podemos sumar List[Int] doblando en cualquier dirección, usando 0 como nuestro acumulador y la suma como nuestra operación pero no podemos hacer lo mismo con la resta :


    List(1, 2, 3).foldLeft(0)(_ - _)

    // res4: Int = -6

    List(1, 2, 3).foldRight(0)(_ - _)

    // res5: Int = 2