Lob Litmus Save

Data schema validation in Elixir

Project README

Litmus

Hex.pm Build Docs Build Status

Data validation in Elixir

Installation

The package can be installed by adding litmus to your list of dependencies in mix.exs:

def deps do
  [
    {:litmus, "~> 1.0.2"}
  ]
end

Usage

Litmus validates data against a predefined schema with the Litmus.validate/2 function.

If the data is valid, the function returns {:ok, data}. The data returned will be coerced according to the provided schema.

If the data passed does not follow the rules defined in the schema, the function returns {:error, error_message}. It will also return an error when receiving a field that has not been specified in the provided schema.

schema = %{
  "id" => %Litmus.Type.Any{
    required: true
  },
  "username" => %Litmus.Type.String{
    min_length: 6,
    required: true
  },
  "pin" => %Litmus.Type.Number{
    min: 1000,
    max: 9999,
    required: true
  },
  "new_user" => %Litmus.Type.Boolean{
    truthy: ["1"],
    falsy: ["0"]
   },
  "account_ids" => %Litmus.Type.List{
    max_length: 3,
    type: :number
  },
  "remember_me" => %Litmus.Type.Boolean{
    default: false
  }
}

params = %{
  "id" => 1,
  "username" => "user@123",
  "pin" => 1234,
  "new_user" => "1",
  "account_ids" => [1, 3, 9]
}

Litmus.validate(params, schema)
# => {:ok,
#      %{
#        "id" => 1,
#        "new_user" => true,
#        "pin" => 1234,
#        "username" => "user@123",
#        "account_ids" => [1, 3, 9],
#        "remember_me" => false
#      }
#    }

Litmus.validate(%{}, schema)
# => {:error, "id is required"}

Supported Types

Litmus currently supports the following types.

  • Litmus.Type.Any
  • Litmus.Type.Boolean
  • Litmus.Type.DateTime
  • Litmus.Type.List
  • Litmus.Type.Number
  • Litmus.Type.String

Plug Integration

Litmus comes with a Plug for easy integration with Plug's built-in router. You can automatically validate query parameters and body parameters by passing the litmus_query and litmus_body private options to each route. When declaring the plug you must include a on_error/2 function to be called when validation fails. It is recommended that you initialize this Plug between the :match and :dispatch plugs. If you want processing to stop on a validation error, be sure to halt the request with Plug.Conn.halt/1.

Example

defmodule MyRouter do
  use Plug.Router

  plug(Plug.Parsers, parsers: [:urlencoded, :multipart])

  plug(:match)

  plug(Litmus.Plug, on_error: &__MODULE__.on_error/2)

  plug(:dispatch)

  @schema %{
    "id" => %Litmus.Type.Number{
      required: true
    }
  }

  get "/test", private: %{litmus_query: @schema} do
    Plug.Conn.send_resp(conn, 200, "items")
  end

  post "/test", private: %{litmus_body: @schema} do
    Plug.Conn.send_resp(conn, 200, "items")
  end

  def on_error(conn, error_message) do
    conn
    |> Plug.Conn.send_resp(400, error_message)
    |> Plug.Conn.halt()
  end
end
Open Source Agenda is not affiliated with "Lob Litmus" Project. README Source: lob/litmus
Stars
34
Open Issues
2
Last Commit
2 years ago
Repository
License
MIT

Open Source Agenda Badge

Open Source Agenda Rating