Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Elixir

Una introducción a las aplicaciones de Elixir

by
Length:LongLanguages:

Spanish (Español) translation by Naudys Angulo (you can also view the original English article)

En mis artículos anteriores, hemos discutido varios términos de Elixir y hemos escrito una gran cantidad de código. Lo que no hemos discutido, sin embargo, es cómo estructurar y organizar su código para que sea fácil de mantener y liberar.

Las Aplicaciones son muy comunes para Erlang y Elixir y son utilizadas para construir componentes reutilizables que se comportan como unidades independientes. Una aplicación puede tener su propio árbol de supervisión y configuración, y puede confiar en otras aplicaciones que están disponibles localmente o en algún servidor remoto. En general, trabajar con aplicaciones no es tan complejo, y las personas que han venido, por ejemplo, del mundo de Ruby encontrarán muchos conceptos familiares.

En este artículo aprenderá qué aplicaciones son, cómo pueden ser creadas, cómo especificar e instalar dependencias y cómo proporcionar valores de entorno. Al final del artículo practicaremos y crearemos una calculadora basada en la web.

Utilizaré Elixir 1.5 en este artículo (fue lanzado hace un par de meses), pero todos los conceptos explicados deberían aplicarse también a la versión 1.4.

¿Aplicaciones?

Algunos podrían argumentar que el término "aplicación" no es muy apropiado porque en Erlang y Elixir realmente significa un componente, o algún código que tiene un montón de dependencias. La aplicación en sí misma también se puede usar como una dependencia --en el mundo de Ruby lo llamaríamos una "gema".

En general, las aplicaciones son muy comunes en Elixir y le permiten crear componentes reutilizables a la vez que proporciona una gestión de dependencia fácil. Ello Consiste en uno o varios módulos con cero o más dependencias y están descritos por el archivo de recursos de la aplicación. Este archivo contiene información sobre el nombre de la aplicación, su versión, sus módulos, dependencias y algunas otras cosas. Puede crear el archivo de recursos manualmente, pero es mucho más fácil hacerlo con la herramienta de mezcla que también preparará una estructura de carpetas correcta para usted.

¡Veamos cómo podemos crear una nueva aplicación Elixir!

Nueva Aplicación

Para crear una nueva aplicación, todo lo que usted necesita hacer es ejecutar el siguiente comando:

También podemos proporcionar el indicador o bandera --sup para crear un supervisor vacío para nosotros. Vamos a crear una nueva aplicación llamada Sample de esta manera:

Este comando creará un directorio de muestra para usted con un puñado de archivos y carpetas dentro. Permítame guiarle rápidamente a través de ellos:

  • La carpeta config contiene un único archivo config.exs que, como puede suponer, proporciona la configuración para la aplicación. Inicialmente tiene algunos comentarios útiles, pero ninguna configuración. Tenga en cuenta, por cierto, que la configuración proporcionada en este archivo solo está restringida a la aplicación en sí. Si está cargando la aplicación como una dependencia, su config.exs se ignorará de manera efectiva.
  • lib es la carpeta principal de la aplicación que contiene un archivo sample.ex y una carpeta de muestra con un archivo application.ex. application.ex define un módulo de devolución de llamada con una función start/2 que crea un supervisor vacío.
  • test es la carpeta que contiene pruebas automatizadas para la aplicación. No discutiremos las pruebas automatizadas en este artículo.
  • mix.exs es el archivo que contiene toda la información necesaria sobre la aplicación. Aquí hay múltiples funciones. Dentro de la función del project, usted proporciona el nombre de la aplicación (como un átomo), versión y entorno. La función aplication contiene información sobre la devolución de llamada del módulo aplication y las dependencias de tiempo de ejecución. En nuestro caso, Sample.Application se configura como el módulo de aplication para la devolución de llamada (que se puede tratar como el punto de entrada principal), y tiene que definir una función start/2. Como ya se mencionó anteriormente, esta función ya fue creada por la herramienta mix. Por último, la función deps enumera las dependencias de tiempo de compilación.

Dependencias

Es bastante importante distinguir entre las dependencias de tiempo de ejecución y tiempo de compilación. Las dependencias de tiempo de compilación son cargadas por la herramienta mix durante la compilación y son básicamente compiladas en su aplicación.

Se pueden obtener de un servicio como GitHub, por ejemplo, o del sitio web hex.pm, un administrador de paquetes externo que almacena miles de componentes para Elixir y Erlang. Las dependencias de tiempo de ejecución se inician antes de que se inicie la aplicación. Ya están compilados y disponibles para nosotros.

Hay un par de maneras de especificar dependencias de tiempo de compilación en un archivo mix.exs. Si desea utilizar una aplicación del sitio web hex.pm, simplemente diga:

El primer argumento es siempre un átomo que representa el nombre de la aplicación. El segundo es el requisito, una versión que desea usar--lo analiza el módulo Versión. In this example, ~> means that we wish to download at least version 0.0.1 or higher but less than 0.1.0. Si decimos ~> 1.0, significa que nos gustaría usar una versión mayor o igual a 1.0 pero menor que 2.0. También hay operadores como ==,>, <,> = y<= disponibles.

También es posible especificar directamente a la opción: :git o a : path

También hay un acceso directo a :github que nos permite proporcionar solo el nombre del propietario y el de un repositorio:

Para descargar y compilar todas las dependencias, ejecute:

Esto instalará un cliente Hex si usted no tiene uno y luego verifica si alguna de las dependencias necesita ser actualizada. Por ejemplo, puede especificar Poison --una solución para analizar JSON-- como una dependencia como esta:

Luego ejecute:

Verá una salida similar:

Poison ahora está compilado y disponible en tu PC. Lo que es más, un archivo mix.lock se creará automáticamente. Este archivo proporciona las versiones exactas de las dependencias para usar cuando se inicia la aplicación.

Para obtener más información sobre las dependencias, ejecute el siguiente comando:

De nuevo Comportamiento

Las aplicaciones son comportamientos, al igual que GenServer y supervisors, de lo que hablamos en los artículos anteriores. Como ya mencioné anteriormente, proporcionamos un módulo de devolución de llamada dentro del archivo mix.exs de la siguiente manera:

Sample.Application es el nombre del módulo, mientras que [] puede contener una lista de argumentos para pasar a la función start / 2. La función start/2 debe implementarse para que la aplicación se inicie correctamente.

La aplicación.ex contiene el módulo de devolución de llamada que se ve así:

La función start/2 debe devolver {: ok, pid} (con un estado opcional como tercer elemento) o {: error, reazon}.

Otra cosa que vale la pena mencionar es que las aplicaciones realmente no requieren el módulo de devolución de llamada. Significa que la función de la aplicación dentro del archivo mix.exs puede volverse realmente minimalísta:

Tales aplicaciones se llaman aplicaciones de biblioteca. No tienen ningún árbol de supervisión, pero todavía pueden ser utilizados como dependencias por otras aplicaciones. Un ejemplo de una aplicación de biblioteca sería Poison, la cual especificamos como una dependencia en la sección anterior.

Iniciar una Aplicación

La forma más fácil de iniciar su aplicación es ejecutar el siguiente comando:

Verás un resultado similar a este:

Se creará un directorio _build dentro de la carpeta sample. Contendrá archivos .beam y otros archivos y carpetas.

Si no desea iniciar un shell Elixir, otra opción es ejecutar:

El problema, sin embargo, es que la aplicación se detendrá tan pronto como la función start termine su tarea. Por lo tanto, puede proporcionar la clave --no-halt para mantener la aplicación en ejecución durante el tiempo que sea necesario:

Lo mismo se puede lograr usando el comando elixir:

Sin embargo, tenga en cuenta que la aplicación se detendrá tan pronto como se cierre el terminal donde se ejecutó este comando. Esto se puede evitar iniciando la aplicación en modo desconectado:

Entorno de Aplicación

En ocasiones, es posible que desee que el usuario de una aplicación establezca algún parámetro antes de que la aplicación se inicie realmente. Esto es útil cuando, por ejemplo, el usuario debe poder controlar qué puerto debe escuchar un servidor web. Dichos parámetros se pueden especificar en el entorno de la aplicación que es un simple almacenamiento de clave-valor en memoria.

Para leer algunos parámetros, use la función fetch_env/2 que acepta una aplicación y una clave:

Si no se puede encontrar la clave, un átomo :error es devuelto. También hay una función fetch_env!/2 que genera un error en su lugar y get_env/3 que puede proporcionar un valor por omisión.

Para almacenar un parámetro, use put_env/4:

El cuarto valor contiene opciones y no requiere ser configurado.

Por último, para eliminar una clave, emplee la función delete_env/3:

¿Cómo proporcionamos un valor para el ambiente al iniciar una aplicación? Bueno, tales parámetros se establecen usando la tecla --erl de la siguiente manera:

Usted luego puede obtener fácilmente el valor:

¿Qué sucede si un usuario olvida especificar un parámetro al iniciar la aplicación? Bueno, lo más probable es que necesitemos proporcionar un valor predeterminado para tales casos. Hay dos lugares posibles donde puede hacer esto: dentro de config.exs o dentro del archivo mix.exs

La primera opción es la preferida porque config.exs es el archivo que está destinado a almacenar varias opciones de configuración. Si su aplicación tiene muchos parámetros de entorno, definitivamente debe seguir con config.exs:

Para una aplicación más pequeña, sin embargo, está bastante bien proporcionar valores de entorno dentro de mix.exs ajustando la función de la aplicación:

Ejemplo: Creación de un ServidorCalc basado en Web

De acuerdo, para ver las aplicaciones en acción, modifiquemos el ejemplo que ya se discutió en mis artículos GenServer y Supervisors. Esta es una calculadora simple que permite a los usuarios realizar diversas operaciones matemáticas y obtener el resultado con bastante facilidad.

Lo que quiero hacer es hacer que esta calculadora se base en la web, de modo que podamos enviar solicitudes POST para realizar cálculos y una solicitud GET para obtener el resultado.

Cree un nuevo archivo lib/calc_server.ex con los siguientes contenidos:

Solo agregaremos soporte para la operación add. Todas las demás operaciones matemáticas se pueden introducir de la misma manera, por lo que no las incluiré aquí para hacer que el código sea más compacto.

CalcServer utiliza GenServer, por lo que obtenemos child_spec automáticamente y podemos iniciarlo desde la función de devolución de llamada de la siguiente manera:

0 aquí está el resultado inicial. Debe ser un número, de lo contrario, CalcServer finalizará inmediatamente.

Ahora la pregunta es ¿cómo podemos agregar soporte web? Para hacer eso, necesitaremos dos dependencias de terceros: Plug, que actuará como una biblioteca de abstracción, y Cowboy, que actuará como un servidor web real.  Por supuesto, necesitamos especificar estas dependencias dentro del archivo mix.exs:

Ahora podemos iniciar la aplicación Plug bajo nuestro propio árbol de supervisión. Ajustar la función start de esta manera:

Aquí estamos proporcionando child_spec y configuramos Sample.Router para responder a las solicitudes. Este módulo se creará en un momento.  Lo que no me gusta de esta configuración, sin embargo, es que el número de puerto está codificado, lo cual no es realmente conveniente. Es posible que desee modificarlo al iniciar la aplicación, así que en lugar de almacenarlo en el entorno:

Ahora proporcione el valor de puerto predeterminado dentro del archivo config.exs:

¡Estupendo!

¿Qué hay del enrutador? Cree un nuevo archivo lib/router.ex con los siguientes contenidos:

Ahora tenemos que definir un par de rutas para realizar la adición y obtener el resultado:

Estamos utilizando las macros get y post para definir las rutas /result y /add. Esas macros establecerán el objeto conn para nosotros.

ok y fetch_number son funciones privadas definidas de la siguiente manera:

fetch_query_params/2 devuelve un objeto con todos los parámetros de consulta. Solo estamos interesados ​​en el número que el usuario nos envía. Todos los parámetros inicialmente son cadenas, por lo que debemos convertirlo a entero.

send_resp/3 envía una respuesta al cliente con el código de estado proporcionado y un cuerpo. No realizaremos ninguna comprobación de errores aquí, por lo que el código siempre será 200, lo que significa que todo está bien.

Y, esto es! Ahora puede iniciar la aplicación de cualquiera de las formas mencionadas anteriormente (por ejemplo, escribiendo iex -S mix) y usar la herramienta curl para realizar las solicitudes:

Conclusión

En este artículo, hemos discutido las aplicaciones de Elixir y su propósito. Usted ha aprendido cómo crear aplicaciones, proporcionar diversos tipos de información y enumerar dependencias dentro del archivo mix.exs. También ha visto cómo almacenar la configuración dentro del entorno de la aplicación y aprendió un par de maneras de iniciar su aplicación. Por último, hemos visto aplicaciones en acción y hemos creado una calculadora simple basada en la web.

No olvide que el sitio web de hex.pm enumera cientos de aplicaciones de terceros listas para usar en sus proyectos, así que asegúrese de examinar el catálogo y elegir la solución que más le convenga.

Con suerte, este artículo te pareció útil e interesante. Te agradezco por quedarte conmigo y hasta la próxima vez.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.