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

Elixir Berln Meetup #83 - Domo 1.3 Automatic mo...

Avatar for Ivan Rublev Ivan Rublev
November 11, 2021

Elixir Berln Meetup #83 - Domo 1.3 Automatic models validation in the microservice setting

Avatar for Ivan Rublev

Ivan Rublev

November 11, 2021
Tweet

More Decks by Ivan Rublev

Other Decks in Technology

Transcript

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

    ELIXIR BERLIN MEETUP 83# NOV 2021 Ivan Rublev github.com/IvanRublev twitter.com/@levvibraun
  2. DOMO 1.3 ▸ Network input ▸ Database and file input

    ▸ The Application itself due 
 to errors in logic
 SOURCES OF INVALID STATES OF APPLICATIONS AT RUNTIME PURCHASING APP defmodule Order do defstruct … end DELIVERY APP defmodule Address do defstruct … end ??? ???
  3. DOMO 1.3 INVALID STATE %PurchaseOrder{ id: 1000, approved_limit: 200, items:

    [ %LineItem{amount: 150} ] } ▸ Elixir structs can hold anything you might want and not want. %PurchaseOrder{ id: "@$$>?!||=", approved_limit: 2.00, items: [ %LineItem{amount: :"150"} ] }
  4. DOMO 1.3 DOMO ENSURES THAT STRUCT’S DATA MATCHES IT’S @TYPE

    SPEC AND PRECONDITIONS ▸ Adds the constructor and ensuring functions to the struct ▸ Validates struct’s field values against its @type spec ▸ Check values with precondition functions attached to types by `precond/1` new_ok(fields) :: {:ok, order} | {:error, msg}
 new!(fields) :: order
 ensure_type_ok(order) :: {:ok, order} | {:error, msg}
 ensure_type!(order) :: order
 defmodule PurchaseOrder do use Domo defstruct [id: 1000, approved_limit: 200, items: []] @type id ::: non_neg_integer() precond id: &(1000 <<= &1 and &1 <<= 5000) @type t ::: %___MODULE___{ id: id(), approved_limit: pos_integer(), items: [LineItem.t()] } # new!/1, new_ok/1, ensure_type!/1, ensure_type_ok/1 end
  5. DOMO 1.3 LIBRARY USAGE iex> {:ok, po} = PurchaseOrder.new_ok(id: 1000,

    approved_limit: 200) {:ok, %PurchaseOrder{id: 1000, approved_limit: 200, items: []}} iex> PurchaseOrder.new_ok(id: 500, approved_limit: 0) {:error, [ id: "Invalid value 500 for field :id of %PurchaseOrder{}. Expected the value matching the non_neg_integer() type. And a true value from the precondition function \"&(1000 <<= &1 and &1 <<= 5000)\" defined for PurchaseOrder.id() type.", approved_limit: "Invalid value 0 for field :approved_limit of %PurchaseOrder{}. Expected the value matching the pos_integer() type." ]} @type id ::: non_neg_integer() precond id: &(1000 <<= &1 and &1 <<= 5000) @type t ::: %___MODULE___{ id: id(), approved_limit: pos_integer(), items: [LineItem.t()] }
  6. DOMO 1.3 DOMO GENERATES TYPE ENSURER MODULES defmodule PurchaseOrder do

    use Domo @type t ::: %___MODULE___{.....} # new!/1, new_ok/1, # ensure_type!/1, ensure_type_ok/1 end defmodule PurchaseOrder.TypeEnsurer do ..... end Generated type ensurers code are in the following project’s subdirectory: “_build/ENV/domo_generated_code“
  7. DOMO 1.3 DOMO RECOMPILES TYPE ENSURERS ON DEPENDENCY CHANGE defmodule

    PurchaseOrder.TypeEnsurer do ..... end defmodule PurchaseOrder do use Domo @type t ::: %___MODULE___{.....} end defmodule PurchaseOrder.TypeEnsurer do ..... end defmodule LineItem do use Domo @type t ::: %___MODULE___{.....} end defmodule SharedKernel do @type amount ::: integer() end defmodule SharedKernel do @type amount ::: non_neg_integer() end defmodule PurchaseOrder.TypeEnsurer do ..... end defmodule PurchaseOrder.TypeEnsurer do ..... end
  8. DOMO 1.3 defmodule Model.Shipment do use Domo @type t :::

    %___MODULE___{.....} end DOMO VALIDATES MODELS ACROSS MICROSERVICES VIA SHARED TYPES Boardings microservice Cargos microservice defmodule Model.Shipment do use Domo @type t ::: %___MODULE___{.....} end defmodule SharedKernel do import Domo @type flight_number ::: String.t() precond flight_number: &validate_flight_number/1 ..... end defmodule Model.Passenger do use Domo @type t ::: %___MODULE___{.....} end defmodule Model.Passenger do use Domo @type t ::: %___MODULE___{.....} end
  9. DOMO 1.3 ▸ Domo library ▸ Validates Application models conform

    to type specs and attached precondition functions across Microservices ▸ Adds new!/1, new_ok/1, ensure_type!/1, ensure_type_ok/2, typed_fields/1, required_fields/1 functions to struct ▸ Supports custom error messages from precondition functions ▸ Validates struct default values at Compile Time! ▸ Integrates with Ecto for changeset validation ▸ Supports Phoenix hot reload ▸ More info ▸ Package https://hex.pm/packages/domo ▸ JSON parsing example https://github.com/IvanRublev/contentful-elixir-parse-example-nestru-domo ▸ Ecto integration example https://github.com/IvanRublev/Domo/tree/master/example_avialia ▸ Questions and help https://elixirforum.com/tag/domo THANKS!