domingo, 5 de abril de 2020

Cómo usar Git y GitHub


Git es un repositorio distribuido. Esto quiere decir que cada desarrollador tiene un repositorio instalado en local. Además hay un repositorio común donde compartir el código, en el caso que nos ocupa el repo común será un proyecto en GitHub.

El proyecto GitHub tiene una rama principal llamada master, esta va a contener la última versión del código funcionando. Se pueden crear ramas para distintos desarrollos pero en esta forma de uso solo se va a trabajar con la rama master.

Pasos a seguir para trabajar con Git y GitHub en el proyecto politicagitgithub:


Primera vez. Para crear el repositorio local git y descargar el contenido del repositorio de GitHub a local

-     Instalar Git. Para ello descargar un fichero ejecutable desde https://git-scm.com/downloads, el fichero a descargar depende del sistema operativo en el que queremos instalar Git. Se ejecuta y para asegurar la correcta instalación, ir a una pantalla de comandos y ejecutar el comando git --versión,  el sistema muestra la versión de Git instalada.

-          Para contener el repositorio local del proyecto se crea una carpeta en el sistema de archivos. En esta carpeta se crea el repositorio local con git clone de la siguiente manera:

1.       Acceder a la URL https://github.com/MarisaAfuera/politicagitgithub.
2.       Pulsar  el botón  "Clone or download"y entonces se muestra la pantalla:

 
3.     Copiar la URL y abrir una ventana de git bash que se habrá instalado con git. Situarse en la carpeta del proyecto yejecutar el comando:

git clone https://github.com/MarisaAfuera/aficionbaloncesto.git


Para el trabajo del día a día

Cuando un desarrollador va a empezar un trabajo sobre el código, lo primero que hace es traer (pull) a su repo local la última versión que hay en la rama master de GitHub. Para ello utilizar el  comando git pull origin master.

Después en local (su equipo) crea una rama para empezar a desarrollar lo que corresponda. Para crear la rama en la que va a trabajar usa el comando git checkout –b .

Trabaja añadiendo, modificando y borrando código en la rama creada en local. Cuando acaba ejecuta los comandos:


  •  git add . Este comando añade al repositorio local en la rama actual los ficheros nuevos, elimina los borrados y cambia los modificados.
  •  git commit –m “<motivo de los cambios>”. Este comando compromete (los da por buenos)  los cambios en local y los marca con el mensaje que escribimos en “motivo de los cambios”.
Ahora hay que integrar los cambios con el código de los demás desarrolladores llevando los cambios al repositorio remoto, en este caso GitHub. Para ello se  comunica al equipo que se va a realizar un “merge” a master de GitHub. El objetivo es que mientras se hace este merge, ningún otro integrante del equipo interfiera haciendo cambios a master. Para integrar los cambios realizados con el código que hay actualmente en master se ejecutan los siguientes comandos:

  •  git checkout master. Para volver a master del repo local.
  •  git pull origin master. Para traer al repo local los últimos cambios a master del repo compartido en GitHub.
  •  git merge nombre-de-rama. Para mezclar los cambios de la rama del repo local con el código en master.  Pueden surgir conflictos que se deben resolver para realizar el merge, algunos conflictos tendrán que ser resueltos en colaboración con otros integrantes del equipo.
  •  git push origin master. Para llevar los cambios a master de GitHub.

Conclusión

Esta es una posible forma de uso de Git y GitHub para el control de versiones del código y la documentación de un proyecto. Esta en una forma muy sencilla de uso de estas herramientas. La política de uso que se emplee en cada caso será algo que los equipos de desarrollo deben acordar cuando aborden un proyecto de desarrollo.
 

lunes, 16 de marzo de 2020

Diseñando Inversion de control e injección de dependencias


Invertir el control consiste en cambiar el sentido de las "invocaciones"entre módulos. Es decir, si el módulo A llama o invoca al módulo B, hacer que B sea el que llame o invoque a A. En los lenguajes bajo el paradigma de orientación a objetos, esta inversión es posible gracias a los módulos de tipo interface o prototipo. Estos módulos permiten definir contratos de comportamiento, de forma que no contienen la implementación de dicho comportamiento. Solo contienen los argumentos necesarios para llevar a cabo el comportamiento y marcan el tipo de resultado que se va a obtener después de realizar ese comportamiento.

El siguiente ejemplo escrito en java muestra lo explicado

public interface Sport {
    void practice();
}

public class Basketball implements Sport {
    @Override
    public void practice() {
        doIt();
    }

El módulo Sport es una módulo de tipo interface. El módulo Basketball implementa esta interface y por ello está obligado a implementar el método practice() que no recibe argumentos y devuelve void como así prescribe la interfaz. Al implementar una interface es obligatorio implementar los métodos prescritos, usando el nombre, argumentos y tipo de retorno establecido.

¿Para qué es esto útil y como se relaciona con la inversión de control? Imaginemos que se requiere construir una app que gestiona partidos de diferentes deportes, su objetivo es llevar el calendario de eventos deportivos. El sistema debe tratar los eventos (Match), de los distintos deportes (Football y Basketball), por ejemplo se puede plantear el siguiente escenario:



El tipo Match crea y usa objetos de tipo Sport. Sport que es una interface, declara que todos los tipos que lo implementen tienen que tener un método practice(). En el ejemplo estos dos tipos obligados por la interfaz a implementar practice() son Football y Basketball.

En una primera instancia se podría haber pensado en el siguiente diseño:


Este diseño puede parecer más sencillo, pero establece un acoplamiento fuerte entre Match y los distintos deportes que se vayan a gestionar en la App. Es decir cada vez que se añada un deporte nuevo habrá que modificar Match. Además como no está regulada la implementación por ningún tipo de interfaz cada deporte se puede comportar de forma distinta, de manera que el tratamiento de cada deporte será diferente.

Para ilustrar esto veamos como queda la implementación de Match en el diseño con interfaz:

 public class Match {

    private final List sports;

    public Match(List sports) {
        this.sports = sports;
    }

    public void implement() {
    sports.forEach(s -> {
            s.practice();
        });
    }
}

Se observa que los deportes se tratan de forma uniforme independientemente de su tipo. Siempre se usa practice().

En este ejemplo queda por ver que tipo es responsable de crear los deportes. Y ese tipo es App, que tiene la siguiente implementación:

public class App {

     public static void main(String[] args) {

       Football football = new Football();
       Basketball basketball = new Basketball();
       List sports = new ArrayList();
       sports.add(football);
       sports.add(basketball);
       Match m = new Match(sports);
       m.implement();

    } 

}


Esta clase crea los deportes y se los injecta a Match a través de su constructor. Y aquí está el ejemplo del segundo concepto anunciado en el título del post "injección de dependencias". Esto quiere decir que las dependencias no las crea directamente Match, es decir no hace ni new Football(); ni new Basketball();. Los objetos de tipo Football y Basketball son creados por App y enviados como argumentos en una lista al constructor de Match. En el caso de necesitar incorporar nuevos deportes se creará su tipo y se implementara practice() como sea oportuno para ese deporte. Luego lo que habrá que modificar será App, Match quedará inmutable.

Este tipo de diseños está encaminado a que las clases de alto nivel, en este caso Match, no dependan de las de bajo nivel, en este caso Football y Basketball. Con lo que se han invertido las invocaciones. En este caso no s Match el que invoca a Football y Bascketball, es App quien invoca a Match y le inyecta los deportes a través del constructor.

Conclusión

Las dependencias son un asunto de la máxima importancia cuando se trata de sistemas informáticos compuestos por multitud de módulos. Estos colaboran entre ellos para llevar a cabo la misión para la que se han construido y para colaborar necesitan establecer dependencias. A todo esto en ingeniería del software se le llama acoplamiento y cuanto menor sea el acoplamiento entre módulos mejor es el sistema. Esto se debe a que sistemas con módulos poco acoplados permiten hacer cambios de forma más sencilla debido a que un cambio en un módulo no provoca que haya que cambiar los módulos que dependen de él y/o los módulos que dependen de él son los mínimos posible. En el caso de este ejemplo es menor el acoplamiento entre Match y Football y Backetball haciendo uso del interface Sport.

El código completo de este ejemplo se puede descargar en https://github.com/MarisaAfuera/inversionofcontrol

sábado, 29 de febrero de 2020

Que es una REST API?

REpresentational State Transfer (REST) es un estilo arquitectónico que maneja la relación entre cliente y servidor, con el propósito de obtener velocidad y rendimiento utilizando componentes reutilizables.

REST cómo tecnología fue introducida en 2000 en la tesis doctoral de Roy Fielding. Hoy en día se ha implantado de tal forma que es preferida a la tecnología SOAP (Simple Object Access Protocol) ya que usa menos ancho de banda y es más simple y flexible para su uso en internet. Podemos usarlo para recoger o suministrar información desde un web service y se hace vía petición HTTP al API REST.

Qué es un API REST?

Un API REST es una forma de acceder a un servicio web sin tener exceso de procesamiento. Cada vez que se llama a un API REST, el servidor transfiere al cliente una representación del estado de recurso solicitado.

¡De hecho usamos API REST todos los días! Cuando buscamos videos sobre ciclismo en youtube. Tecleas "ciclismo" en el campo de búsqueda de youtube, al presionar enter y se ve una lista de videos sobre ciclismo. Esta es la forma en que trabaja un API REST. Buscamos algo y obtenemos una lista desde el servicion web con los resultados de la busqueda solicitada.

Un API(application programming interface) es un conjunto de reglas que permite a un programa comunicarse con otro. Un desarrollador crea un API en un servidor y permite a otros programas hablar con ella.
REST determina el aspecto del API. Esto es, las reglas que los desarrolladores siguen cuando crean el API y cuando lo utilizan. Una de estas reglas establece que deberías obtener unos datos determinados cuando enlazas con una URL. A esta URL se le llama punto de entrada.
La URL es llamada request (petición) y los datos devueltos se llaman response (respuesta).

Arquitectura RESTful

Las características fundamentales de un API REST, son:
  • Sin estado: Ningún dato del cliente se almacena en el servidor. Lo necesario para mantener la sesión entre cliente y servidor se almacena en el cliente, típicamente en sessión storage.
  • Client<->eServidor: Hay clara separación de lo que hace el cliente(front-end) y lo que hace el servidor(back-end). Estos operan independientemente y son reemplazables.
  • Cache: Los datos provenientes del servidor se cachean en el cliente, esto mejora la velocidad de obtención de datos.
  • Composición de la URL: Se usa un enfoque estándar para la composición de las URLs. Por ejemplo, una petición con método GET "http://servidor/ciudades" devuelve una lista de ciudades mientras que "http://servidor/ciudades/burgos" desvuelve los datos de la ciudad de Burgos. Las APIS REST también ejecutan acciones para añadir, modificar o borrar datos como se explica a continuación.

REST en acción

La petición se envía desde el cliente al servidor vía HTTP como una URL que enlaza con una web. Está petición usa los métodos http GET, POST, PUT o DELETE. Entonces la respuesta es enviada desde el servidor en forma de recurso que puede ser HTML, XML, imagen o JSON. JSON es el más popular.

HTTP tiene entre otros los métodos: POST, GET, PUT, y DELETE. Estos métodos corresponden con las operaciones crear(create), leer(read), actualizar (update) y borrar (delete). Estas son llamadas las operaciones CRUD y son muy habituales en los aplicativos. Cada uno de estos métodos opera de la siguiente manera:
  • POST: Este método se usa para crear un nuevo recurso. Si todo va bien devuelve un código 201 con una cabecera conteniendo el enlace al nuevo recurso.
  • GET: Este método se usa para recuperar un recurso. Si todo va bien GET devuelve por ejemplo un XML o JSON con los datos solicitados y un código de respuesta 200. Si algo va mal devuelve un código de error, por ejemplo 404 Not Found o 400 Bad Request.
  • PUT: Se usa principalmente para actualizar un recurso o en casos especiales para crearlo. Un update que se ejecuta con éxito retorna un 200 o 204 sino devuelve ningún contenido en el body. Si se usa para creación y acaba bien devuelve un 201.
  • DELETE: Borra un recurso, normalmente se suministra el identificador. Después de un borrado con éxito devuelve 200.
Las operaciones CRUD se envían desde el cliente al servidor escribiendo una URI en un browser o haciendo un fetch en un programa. En los servidores se instalan servicios que responden a estas peticiones mediante distintos puntos de entrada. Un ejemplo de como son habitualmente estos puntos de entrada es:

GET  /device-management/devices      : recupera todos los devices
POST  /device-management/devices      : crea un nuevo device
GET  /device-management/devices/{id} : recupera el device con identificador id
PUT  /device-management/devices/{id} : actualiza el device con identificador id
DELETE /device-management/devices/{id} : borra el device con identificador id

Trabajando con los datos del API REST

También es una práctica habitual que el API REST devuelva datos en formato JSON. El formato  JSON (JavaScript Object Notation), cuando se reciben datos de un API Rest tienen el siguiente aspecto:

{

¿Dónde se pueden encontrar APIs REST? ¡¡¡Por todos los lados!!! Twitter. Google. Open Weather Map. YouTube.  La mayoría de los servicios más populares que se usan actualmente utilizan una arquitectura RESTful. Así que ¡adelante!, explorad el mundo de añadir funcionalidad de API a vuestros sitios WEB.

Conclusión

Hemos echado un vistazo a lo que es un API REST e indagado en lo que es arquitectura RESTful. Hemos visto como funciona un API REST a través de puntos de entrada y visto como es un fichero en formato JSON.


Este Post es una traducción e interpretación a mi entender del POST
https://itnext.io/javascript-fundamentals-an-introduction-to-rest-apis-7cbe8a809d3b

domingo, 23 de febrero de 2020

Qué es el "Chaos Monkey"


Chaos Monkey es una herramienta software que de forma aleatoria detiene instancias y contenedores que están ejecutándose en el entorno de producción. El objetivo es exponer a los sistemas a fallos para ayudar a los ingenieros a proveer servicios que sean capaces de reaccionar a caídas y otros problemas inesperados.

La herramienta es de uso libre y se puede descargar en https://github.com/Netflix/chaosmonkey

Gareth Bowles, antiguo empleado de Netflix, en su presentación de 2015  "I Don't Test Often ... But When I Do, I Test in Production" que se puede consultar en https://www.youtube.com/watch?v=xkP70Zhhix4 explica los motivos que condujeron a Netflix a desarrollar una herramienta basada en la ingeniería del caos.

Gareth explica que debido a las características del servicio que proporciona Netflix, se hacía muy difícil probar en un entorno que no fuese el de producción. A veces la cuota de internet que ocupan los clientes de Netflix supone hasta un 34% del total del tráfico de Internet. Simular esto en un entorno de pruebas era imposible.

Entonces se les ocurrió que podían hacer varias cosas:
  1. Chaos Monkey
  2. Coverage en producción
  3. Canary deployment

1. Chaos Monkey 

Es una herramienta software que provoca la caída de servicios en producción. De esta forma los ingenieros pueden experimentar las consecuencias de la caída y aprender a que hacer para preveer los efectos no deseados de la caída. Las caídas provocadas se hacen a horas de trabajo, donde todos los ingenieros están en la oficina y pueden ponerse manos a la obra para arreglar los problemas inmediatamente. Esto es una ventaja frente a caídas fuera de horas, que hacen que los desarrolladores y operadores tengan que salir corriendo y trabajar a deshoras o en jornadas interminables.

Cómo Chaos Monkey funcionó bien, se decidieron a desarrollar otros monkeys: Chaos Gorilla simula la caida de una zona completa de servidores y Chos Kong de una región que agrupa zonas. 

También idearon otros monkeys que por ejemplo degradan el tiempo de respuesta Latency Monkey o simulan que un servidor no cumple los estándares de configuración Conformity Monkey.

2. Coverage en producción

Es una forma de telemetría, en la que se mide que líneas de código se ejecutan en producción y cuantas veces se ejecutan.
Estas mediciones permiten saber cúal es la parte de código que se debe de probar más porque se ejercita más veces. Es decir, se pueden planificar, construir y ejecutar pruebas más efectivas.

3. Canary deployment


Se trata de desplegar software inicialmente en solo algunos servidores. Con este despliegue se comprueba si el nuevo software responde a las expectativas: funciona bien, no degrada el servicio, los usuarios lo encuentran útil, etc. El nombre de este tipo de despliegue proviene del uso de canarios en las minas para controlar la calidad del aire. En el caso de que el canario se viese afectado por la calidad del aire, las personas tenían tiempo de escapar antes de que la mala calidad del aire les afectase a ellos.

Una vez comprobado que el software cumple con las expectativas se procede a desplegarlo en el resto de los servidores. O no desplegarlo si no cumplió las expectativas.

Conclusión

Estas iniciativas han contribuido al éxito de Netflix que sin duda es una plataforma ampliamente utilizada. Por lo tanto aprendamos de ellos y quizás en otros ámbitos algunas de estas técnicas puedan usarse para ayudar a mejorar.