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

Введение в приложения на Elixir

by
Length:LongLanguages:

Russian (Pусский) translation by Marat Amerov (you can also view the original English article)

В моих предыдущих статьях мы обсуждали различные термины Elixir и писали много кода. Однако мы не обсуждали, как структурировать и упорядочить ваш код, чтобы его было легко поддерживать и релизить.

Приложения очень распространены для Erlang и Elixir и используются для создания повторно используемых компонентов, которые ведут себя как автономные юниты. Одно приложение может иметь свое собственное дерево супервизоров и конфигурацию, и оно может полагаться на другие приложения, доступные либо локально, либо на каком-то удаленном сервере. В целом, работа с приложениями не такая сложная, и люди, которые пришли, скажем, из мира Ruby, найдут много знакомых концептов.

В этой статье вы узнаете, что такое приложения, как они могут быть созданы, как определять и устанавливать зависимости, и как предоставлять значения среды. В конце статьи мы сделаем некоторую практику и создадим веб-калькулятор.

В этой статье я буду использовать Elixir 1.5 (он был выпущен пару месяцев назад), но все объясненные концепции должны применяться и к версии 1.4.

Приложения?

Некоторые могут возразить, что термин "приложение" не очень подходит, потому что в Erlang и Elixir он фактически означает компонент или какой-то код, который имеет кучу зависимостей. Само приложение также может быть использовано в качестве зависимости. В мире Ruby мы бы назвали это "гемом".

В общем, приложения очень распространены в Elixir и позволяют создавать повторно используемые компоненты, а также обеспечивают легкое управление зависимостями. Они состоят из одного или нескольких модулей с нулевыми или более зависимостями и описываются файлом ресурсов приложения. Этот файл содержит информацию о имени, версии приложения, его модулях, зависимостях и некоторых других материалах. Вы можете создать файл ресурсов вручную, но гораздо проще сделать это с помощью инструмента mix, который также подготовит для вас правильную структуру папок.

Итак, давайте посмотрим, как мы можем создать новое приложение Elixir!

Новое приложение

Чтобы создать новое приложение, все, что вам нужно сделать, это запустить следующую команду:

Мы также можем предоставить флаг --sup для создания пустого супервизора. Давайте создадим новое приложение Sample:

Эта команда создаст каталог sample с несколькими файлами и папками внутри. Позвольте мне быстро ознакомить вас с ними:

  • config содержит единственный файл config.exs, который, как вы можете догадаться, обеспечивает конфигурацию приложения. Первоначально он имеет некоторые полезные комментарии, но не имеет конфигурации. Кстати, обратите внимание, что конфигурация, представленная в этом файле, ограничивается только самим приложением. Если вы загружаете приложение как зависимость, его config.exs будет игнорироваться.
  • lib — основная папка приложения, содержащая файл sample.ex и папку sample с файлом application.ex. application.ex определяет модуль обратного вызова с функцией start/2, которая создает пустой супервайзер.
  • test — это папка, содержащая автоматические тесты для приложения. Мы не будем обсуждать тесты в этой статье.
  • mix.exs — это файл, содержащий всю необходимую информацию о приложении. Здесь есть несколько функций. Внутри функции project вы указываете имя приложения (как атом), версию и среду. Функция application содержит информацию о зависимостях обратного вызова и рантайма. В нашем случае Sample.Application устанавливается как обратный вызов модуля приложения (который можно рассматривать как главную точку входа), и он должен определить функцию start/2. Как уже упоминалось выше, эта функция была создана для нас инструментом mix. Наконец, функция deps отображает зависимости сборки.

Зависимости

Очень важно различать зависимости рантайма и сборки. Зависимости сборки загружаются инструментом mix во время компиляции и в основном скомпилированы в ваше приложение.

Они могут быть получены из сервисов, например, GitHub или с сайта hex.pm — внешнего менеджера пакетов, который хранит тысячи компонентов для Elixir и Erlang. Зависимости рантайма запускаются до запуска приложения. Они уже собраны и доступны для нас.

Существует несколько способов указать зависимости  сборки в файле mix.exs. Если вы хотите использовать приложение с сайта hex.pm, просто скажите:

Первый аргумент — это всегда атом, представляющий имя приложения. Второй — это требование, которое вы хотите использовать, — оно анализируется модулем Version. В этом примере ~> означает, что мы хотим загрузить хотя бы версию 0.0.1 или выше, но менее 0,1.0. Если мы объявляем  ~> 1.0, это означает, что мы хотели бы использовать версию, большую или равную 1.0, но менее 2.0. Существуют также операторы типа ==,>, <,>= и <=.

Также возможно прямо указать параметры :git или :path:

Существует также сокращение :github, которое позволяет нам предоставлять только имя владельца и репо:

Чтобы загрузить и скомпилировать все зависимости, запустите:

Эта команда установит клиент Hex, если у вас его нет, а затем проверит, нужно ли обновлять какие-либо из зависимостей. Например, вы можете указать Poison — решение для синтаксического анализа JSON как зависимость:

Затем выполните:

Вы увидите аналогичный результат:

Poison теперь скомпилирован и доступен на вашем ПК. Более того, файл mix.lock будет создан автоматически. Этот файл предоставляет точные версии зависимостей, которые будут использоваться при загрузке приложения.

Чтобы узнать больше о зависимостях, выполните следующую команду:

Поведение

Приложения - это поведение, как и GenServer и супервизоры, о которых мы говорили в предыдущих статьях. Как я уже упоминал выше, мы предоставляем модуль обратного вызова внутри файла mix.exs следующим образом:

Sample.Application — это имя модуля, тогда как [] может содержать список аргументов для передачи в функцию start/2. Функция start/2 должна быть реализована для правильной загрузки приложения.

application.ex содержит модуль обратного вызова, который выглядит так:

Функция start/2 должна либо возвращать {:ok, pid} (с необязательным состоянием в качестве третьего элемента), либо {:error, reason}.

Еще одна вещь, о которой стоит упомянуть, заключается в том, что на самом деле, приложениям вообще не нужен модуль обратного вызова. Это означает, что функция application внутри файла mix.exs может стать минималистичной:

Такие приложения называются библиотечными приложениями. У них нет никакого дерева супервизоров, но их все еще можно использовать в качестве зависимостей для других приложений. Одним из примеров библиотечных приложений будет Poison, который мы указали как зависимость в предыдущем разделе.

Запуск приложения

Самый простой способ запустить приложение — запустить следующую команду:

Вы увидите результат, похожий на этот:

В папке sample будет создан каталог _build. Он будет содержать файлы .beam, а также некоторые другие файлы и папки.

Если вы не хотите запускать оболочку Elixir, необходимо запустить другой вариант:

Проблема, однако, в том, что приложение остановится, как только функция start завершит свою работу. Поэтому вы можете предоставить ключ --no-halt, чтобы приложение работало столько, сколько необходимо:

То же самое можно сделать с помощью команды elixir:

Обратите внимание, однако, что приложение остановится, как только вы закроете терминал, в котором эта команда была выполнена. Этого можно избежать, запустив приложение в отдельном режиме:

Окружение приложения

Иногда вам может потребоваться, чтобы пользователь приложения установил некоторый параметр до того, как приложение действительно загрузилось. Это полезно, когда, например, пользователь должен иметь возможность контролировать, какой порт должен прослушивать веб-сервер. Такие параметры могут быть указаны в среде приложения, которая представляет собой простое хранилище ключей для хранения в памяти.

Чтобы прочитать некоторый параметр, используйте функцию fetch_env/2, которая принимает приложение и ключ:

Если ключ не найден, возвращается атом :error. Также есть функция fetch_env!/2, которая вызывает ошибку, get_env/3, которая может предоставлять значение по умолчанию.

Чтобы сохранить параметр, используйте put_env/4:

Четвертое значение содержит параметры и не является обязательным.

Наконец, чтобы удалить ключ, используйте функцию delete_env/3:

Как мы предоставляем значение для среды при запуске приложения? Такие параметры задаются с помощью ключа --erl следующим образом:

Затем вы можете легко получить значение:

Что делать, если пользователь забывает указать параметр при запуске приложения? Ну, скорее всего, нам нужно предоставить значение по умолчанию для таких случаев. Есть два возможных места, где вы можете сделать это: внутри config.exs или внутри файла mix.exs.

Первый вариант является предпочтительным, потому что config.exs — это файл, который на самом деле предназначен для хранения различных параметров конфигурации. Если ваше приложение имеет множество параметров среды, вы обязательно должны придерживаться config.exs:

Однако для более мелкого приложения вполне нормально указывать значения среды непосредственно в mix.exs, настраивая функцию application:

Пример: создание веб-сервера CalcServer

Хорошо, чтобы увидеть приложения в действии, давайте изменим пример, который уже обсуждался в моих статьях о GenServer и Supervisors. Это простой калькулятор, который позволяет пользователям выполнять различные математические операции и легко получать результат.

Я хочу сделать этот калькулятор веб-сайтом, чтобы мы могли отправлять POST-запросы для выполнения вычислений и GET-запрос для получения результата.

Создайте новый файл lib/calc_server.ex со следующим содержимым:

Мы добавим поддержку операции add. Все остальные математические операции могут быть введены таким же образом, поэтому я не буду перечислять их здесь, чтобы сделать код более компактным.

CalcServer использует GenServer, поэтому мы автоматически получаем child_spec и можем запустить его из функции обратного вызова следующим образом:

0 вот исходный результат. Он должен быть числом, иначе CalcServer немедленно прервется.

Теперь вопрос в том, как мы добавляем поддержку веба? Для этого нам понадобятся две сторонние зависимости: Plug, который будет действовать как библиотека абстракции, и Cowboy, который будет действовать как реальный веб-сервер. Конечно, нам нужно указать эти зависимости внутри файла mix.exs:

Теперь мы можем запустить приложение Plug под нашим собственным деревом супервайзеров. Подкорректируйте функцию start следующим образом:

Здесь мы предоставляем child_spec и устанавливаем Sample.Router для ответа на запросы. Этот модуль будет создан через мгновение. Однако мне не нравится, что номер порта жестко зашит, что не очень удобно. Я могу настроить его при запуске приложения, поэтому давайте вместо этого сохраним его в среде:

Теперь укажите значение порта по умолчанию в файле config.exs:

Великолепно!

Как насчет маршрутизатора? Создайте новый файл lib/router.ex со следующим содержимым:

Теперь нам нужно определить пару маршрутов для выполнения добавления и получения результата:

Мы используем макросы get и post для определения маршрутов /result и /add. Эти макросы установят для нас объект conn.

ok и fetch_number являются приватными функциями, определяемыми следующим образом:

fetch_query_params/2 возвращает объект со всеми параметрами запроса. Нас интересует только тот номер, который отправляет нам пользователь. Все параметры изначально являются строками, поэтому нам нужно преобразовать их в целое число.

send_resp/3 отправляет ответ клиенту с предоставленным кодом состояния и телом. Мы не будем проверять здесь ошибки, поэтому код всегда будет 200, что означает, что все в порядке.

И это все! Теперь вы можете запустить приложение любым из перечисленных выше способов (например, набрав iex -S mix) и использовать инструмент curl для выполнения запросов:

Заключение

В этой статье мы обсудили приложения Elixir и их назначение. Вы узнали, как создавать приложения, предоставлять различные типы информации и перечислять зависимости внутри файла mix.exs. Вы также видели, как сохранить конфигурацию внутри среды приложения и узнали несколько способов запуска приложения. Наконец, мы видели приложения в действии и создали простой веб-калькулятор.

Не забывайте, что на сайте hex.pm представлено множество сотен сторонних приложений, готовых для использования в ваших проектах, поэтому обязательно просмотрите каталог и выберите подходящее вам решение!

Надеюсь, вы нашли эту статью полезной и интересной. Я благодарю вас за то, что оставались со мной! Еще увидимся.

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.