Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ElixirConf EU 2021 Domo - library for automatic...

Ivan Rublev
September 09, 2021

ElixirConf EU 2021 Domo - library for automatic models validation in the microservice setting

Domo is a tool to:
* Keep model consistency across Applications and Microservices by sharing the constraints declared with type specs and attached precondition functions
* Ensure that incoming data from network, database, file, and application state is within constraints at compile and run time
* Support Phoenix hot reload
* Integrates with Ecto

Ivan Rublev

September 09, 2021
Tweet

More Decks by Ivan Rublev

Other Decks in Technology

Transcript

  1. DOMO 1.3 - AUTOMATIC MODELS VALIDATION IN THE MICROSERVICE SETTING

    ELIXIR CONF EU 2021 Ivan Rublev github.com/IvanRublev twitter.com/@levvibraun
  2. DOMO 1.3 ▸ Network input ▸ Database and file input

    ▸ Application itself due 
 to errors in logic
 SOURCES OF APPLICATIONS INVALID STATES AT RUNTIME PURCHASING APP defmodule Order do defstruct … end DELIVERY APP defmodule Address do defstruct … end ??? ???
  3. DOMO 1.3 HOW TO CHECK THAT APP’S STATE STRUCT IS

    VALID? PURCHASING APP defmodule Order do use Domo defstruct [id, customer_id, items, …] end DELIVERY APP defmodule Address do use Domo defstruct [id, customer_id, city, …] end ▸ Declare a schema with @type spec ▸ Share types for consistency ▸ Declare value range precondition function for types ▸ Have a function to validate struct data matching the type spec! @type t :: %_MODULE_{ customer_id: customer_id(), … } @type t :: %_MODULE_{ customer_id: customer_id(), … } defmodule Values do type customer_id :: String.t() 
 end @type t :: %_MODULE_{ customer_id: String.t(), … } @type t :: %_MODULE_{ customer_id: String.t(), … } Address.ensure_type(address) :: {:ok, address} | {:error, msg}
 Order.ensure_type(order) :: {:ok, order} | {:error, msg} precond customer_id:
 String.match?(value, 
 ~r/^CC-\d{4,5}$/)
  4. DOMO 1.3 COMPILE TIME BENEFITS ▸ Gathers struct type specs

    across the project and library modules via custom compiler ▸ Sticks precondition functions to the types for value ranges checks ▸ Supports custom error messages from precondition functions ▸ Validates struct default values! defmodule ExampleAvialia.SharedKernel do @moduledoc """ Shared types and preconditions """ import Domo @type flight_number ::: String.t() precond flight_number: &validate_flight_number/1 def validate_flight_number(<<<"ALA-", _:::8*4>>>), do: :ok def validate_flight_number(_), do: {:error, "Flight number \ should be of ALA-xxxx format."} end === Compilation error in file lib/order.ex:55 === *** A default value given via defstruct/1 in Order module mismatches the type. "Invalid value nil for field :flight of %Order{}. 
 Flight number should be of ALA-xxxx format."
  5. DOMO 1.3 RUNTIME BENEFITS ▸ Adds new!/1, new_ok/1, ensure_type!/1, ensure_type_ok/2

    functions to struct ▸ Integrates to Ecto for changeset validation ▸ Supports precondition functions for strcut t() type to validate struct value as a whole to fulfil domain model invariants
  6. DOMO 1.3 ▸ Domo is a tool to ▸ Keep

    model consistency across Applications and Microservices by sharing the constraints declared with type specs and attached precondition functions ▸ Ensure that incoming data from network, database, file, and application state is within constraints at compile and run time ▸ Supports Phoenix hot reload ▸ Integrates with Ecto ▸ More info ▸ https://hex.pm/packages/domo ▸ Example with Ecto integration https://github.com/IvanRublev/Domo/tree/master/example_avialia ▸ https://elixirforum.com/tag/domo THANKS!