<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="369156" data-post-id="369156">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lud" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lud/120/14382_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lud
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hello,</p>
<p>I just released a new version for <a href="https://forum.elixirforum.com/t/jsv-json-schema-validation-library-for-elixir-with-support-for-2020-12/68502" rel="nofollow">JSV</a></p>
<p>As mentioned in the <a href="https://forum.elixirforum.com/t/jsv-0-8-0-new-build-api/71398" rel="nofollow">previous version thread</a> I wanted to change the functional API used to define schemas, mostly because it was kind of useless for that type of data.</p>
<p>Basically I have deprecated building schemas like this…</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">object() 
|&gt; properties(foo: integer()) 
|&gt; required(:foo)
</code></pre>
<p>…because there were no additional value from that syntax, and only a performance cost.</p>
<p>New helpers are available, there is less of them for now, and they are not composable (not pipeable) but they are more readable given the extra attributes (like `description “foo…”) are always the last argument.</p>
<p>I believe this will lead to simpler code given schemas are static data 99% of the time.</p>
<p>More information in the docs <a href="https://hexdocs.pm/jsv/api-changes-v0-9.html" class="inline-onebox" rel="noopener nofollow ugc">jsv v0.20.0 — Documentation</a></p>
<p>I’m also happy to see that the <a href="https://hex.pm/packages/vaux" rel="nofollow">Vaux</a> library uses JSV for attribute validation in HTML components, which is quite cool!</p>
<h2><a name="p-369156-h-090-2025-07-05-1" class="anchor" href="#p-369156-h-090-2025-07-05-1" aria-label="Heading link" rel="nofollow"></a>[0.9.0] - 2025-07-05</h2>
<h3><a name="p-369156-features-2" class="anchor" href="#p-369156-features-2" aria-label="Heading link" rel="nofollow"></a><img src="https://forum.elixirforum.com/images/emoji/apple/rocket.png?v=15" title=":rocket:" class="emoji" alt=":rocket:" loading="lazy" width="20" height="20"> Features</h3>
<ul>
<li>Provide a schema representing normalized validation errors</li>
<li>Deprecated the schema composition API in favor of presets</li>
</ul>
<h3><a name="p-369156-bug-fixes-3" class="anchor" href="#p-369156-bug-fixes-3" aria-label="Heading link" rel="nofollow"></a><img src="https://forum.elixirforum.com/images/emoji/apple/bug.png?v=15" title=":bug:" class="emoji" alt=":bug:" loading="lazy" width="20" height="20"> Bug Fixes</h3>
<ul>
<li>Emit a build error with empty oneOf/allOf/anyOf</li>
<li>Reset errors when using a detached validator</li>
<li>Ensure casts are applied after all validations</li>
<li>Revert default normalized error to atoms</li>
</ul>
<aside class="onebox allowlistedgeneric" data-onebox-src="https://jsv.hexdocs.pm/api-changes-v0-9.html">
  <header class="source">

      <a href="https://jsv.hexdocs.pm/api-changes-v0-9.html" target="_blank" rel="noopener nofollow ugc">jsv.hexdocs.pm</a>
  </header>

  <article class="onebox-body">
    

<h3><a href="https://jsv.hexdocs.pm/api-changes-v0-9.html" target="_blank" rel="noopener nofollow ugc">jsv v0.20.0 — Documentation</a></h3>



  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>
 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369156" data-batch-url="/posts/batch_likers">
                        6
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/jsv-json-schema-validation-library-for-elixir-with-support-for-2020-12/68502/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-369156" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369156"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="369474" data-post-id="369474">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lud" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lud/120/14382_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lud
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hello, sorry to be spammy but I love working on <a href="https://forum.elixirforum.com/t/jsv-json-schema-validation-library-for-elixir-with-support-for-2020-12/68502" rel="nofollow">JSV</a>, my JSON Schema Validator library.</p>
<p>This is a small release with three important things:</p>
<ul>
<li>
<p>Module-based schemas now need to export a <code>json_schema/0</code> function instead of a <code>schema/0</code> function. This makes more sense since we are starting to export json_schemas from other modules like Ecto schema modules. A generic <code>schema/0</code> function is confusing in that case. Codebases using the old callback will still work, but a warning will be emitted.</p>
<p>Example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule ItemModule do
  def json_schema do
    %{type: :string}
  end
end

schema = %{type: :array, items: ItemModule} 

data = ["foo", "bar"]
</code></pre>
<p>Modules using <code>JSV.defschema/1</code> will automatically export the new function as well as the old one, with a deprecation warning.</p>
</li>
<li>
<p>That <code>defschema</code> macro now supports passing the properties as a list directly.<br>
So instead of this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule MyApp.UserSchema do
  use JSV.Schema

  defschema %{
    type: :object,
    properties: %{
      name: %{type: :string},
      age: %{type: :integer, default: 0}
    }
  }
end
</code></pre>
<p>You can do this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule MyApp.UserSchema do
  use JSV.Schema

  defschema name: %{type: :string},
            age: %{type: :integer, default: 0}
end
</code></pre>
<p>And because <code>use JSV.Schema</code> imports the new schema definition helpers, it can be as short as this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule MyApp.UserSchema do
  use JSV.Schema

  defschema name: string(),
            age: integer(default: 0)
end
</code></pre>
</li>
<li>
<p>Finally, I’ve added the <code>defschema/3</code> macro that works like <code>defschema/1</code> but also defines a module:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule MyApp.Schemas do
  use JSV.Schema

  defschema User, 
    name: string(),
    age: integer(default: 0)

  defschema Admin,
    """
    With a schema description and @moduledoc
    """,
    user: User,
    privileges: array_of(string())
end
</code></pre>
<p>I think it’s nice to have this when defining some responses schemas directly in controllers or message queue consumers, à la Pydantic.</p>
</li>
</ul>
<p>And that’s it <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> Thanks for reading!</p>
<h2><a name="p-369474-h-0100-2025-07-10-1" class="anchor" href="#p-369474-h-0100-2025-07-10-1" aria-label="Heading link" rel="nofollow"></a>[0.10.0] - 2025-07-10</h2>
<h3><a name="p-369474-features-2" class="anchor" href="#p-369474-features-2" aria-label="Heading link" rel="nofollow"></a><img src="https://forum.elixirforum.com/images/emoji/apple/rocket.png?v=15" title=":rocket:" class="emoji" alt=":rocket:" loading="lazy" width="20" height="20"> Features</h3>
<ul>
<li>Define and expect schema modules to export json_schema/0 instead of schema/0</li>
<li>Allow to call defschema with a list of properties</li>
<li>Added the defschema/3 macro to define schemas as submodules</li>
</ul>
<h3><a name="p-369474-bug-fixes-3" class="anchor" href="#p-369474-bug-fixes-3" aria-label="Heading link" rel="nofollow"></a><img src="https://forum.elixirforum.com/images/emoji/apple/bug.png?v=15" title=":bug:" class="emoji" alt=":bug:" loading="lazy" width="20" height="20"> Bug Fixes</h3>
<ul>
<li>Ensure defschema with keyword syntax supports module-based properties</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369474" data-batch-url="/posts/batch_likers">
                        9
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/jsv-json-schema-validation-library-for-elixir-with-support-for-2020-12/68502/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-369474" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369474"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="369069" data-post-id="369069">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="gtcode" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gtcode/120/234_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  gtcode
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>That’s a commitment to quality</p>
<p><img src="https://forum.elixirforum.com/uploads/default/original/3X/6/a/6a9a77d67faf3739a7382055a01f8ec485d42c68.png" alt="image" data-base62-sha1="fd3yC25GTkad4BxgSyGkivAwpcY" width="513" height="66"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369069" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/jsv-json-schema-validation-library-for-elixir-with-support-for-2020-12/68502/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-369069" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369069"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="369070" data-post-id="369070">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lud" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lud/120/14382_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lud
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Haha !</p>
<p>The truth is that I generate many tests from the official JSON schema test suite. All generated tests are in 3 versions:</p>
<ul>
<li>one with raw schemas (string keys)</li>
<li>one with atom keys, most of the time using the JSV.Schema struct (only <code>const</code> is not in the struct so I use bare maps with atoms)</li>
<li>one using Decimal structs instead of numbers in the test values.</li>
</ul>
<p>And as I use two suites, Draft 7 and 2020-12, you get a huge amount of tests!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369070" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/jsv-json-schema-validation-library-for-elixir-with-support-for-2020-12/68502/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-369070" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369070"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="369072" data-post-id="369072">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="gtcode" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gtcode/120/234_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  gtcode
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>heh.</p>
<p>at first, I tried to believe the tests were built by hand. then, I asked re: <code>jsv</code>:</p>
<p><a href="https://github.com/nshkrdotcom/jsv/blob/main/guides/misc/TEST_GUIDE.md" class="onebox" target="_blank" rel="noopener nofollow ugc">https://github.com/nshkrdotcom/jsv/blob/main/guides/misc/TEST_GUIDE.md</a></p>
<p>got some useful hints from your work. thanks</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369072" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/jsv-json-schema-validation-library-for-elixir-with-support-for-2020-12/68502/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-369072" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369072"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="369083" data-post-id="369083">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lud" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lud/120/14382_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lud
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Looking at you files it appears those are LLM generated right? I think it did a pretty good job (though it should have stopped at some point in that test guide, at the end it’s making things up). What did you use?</p>
<p>I tried to use Exdantic with JSV but we have an incompatibility. JSV expects raw data with binary keys while Exdantic seem to expect atom keys only:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Mix.install([
  {:jsv, "~&gt; 0.10"},
  {:exdantic, "~&gt; 0.0.2"}
])

defmodule UserSchema do
  use Exdantic, define_struct: true

  schema "User account information" do
    field :name, :string do
      required()
      min_length(2)
      description("User's full name")
    end

    field :email, :string do
      required()
      format(~r/^[^\s@]+@[^\s@]+\.[^\s@]+$/)
      description("Primary email address")
    end

    field :age, :integer do
      optional()
      gt(0)
      lt(150)
      description("User's age in years")
    end

    field :active, :boolean do
      default(true)
      description("Whether the account is active")
    end

    # Cross-field validation
    model_validator(:validate_adult_email)

    # Computed field derived from other fields
    computed_field(:display_name, :string, :generate_display_name)

    config do
      title("User Schema")
      strict(true)
    end
  end

  def validate_adult_email(input) do
    if input.age &amp;&amp; input.age &gt;= 18 &amp;&amp; String.contains?(input.email, "example.com") do
      {:error, "Adult users cannot use example.com emails"}
    else
      {:ok, input}
    end
  end

  def generate_display_name(input) do
    display =
      if input.age do
        "#{input.name} (#{input.age})"
      else
        input.name
      end

    {:ok, display}
  end

  use JSV.Schema

  def json_schema do
    JSV.Schema.with_cast([__MODULE__, :from_jsv])
  end

  defcast from_jsv(data) do
    validate(data)
  end

  def format_error("from_jsv", [exdantic_error | _], _) do
    Exdantic.Error.format(exdantic_error)
  end
end

root = JSV.build!(UserSchema) |&gt; dbg()
data = %{"name" =&gt; "alice", "email" =&gt; "foo@bar.com"}

JSV.validate!(data, root)


</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369083" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/jsv-json-schema-validation-library-for-elixir-with-support-for-2020-12/68502/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-369083" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369083"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="369123" data-post-id="369123">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="gtcode" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gtcode/120/234_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  gtcode
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I just used Claude Code. Yeah, Claude likes being “helpful”, whether hallucinating ideas or running <code>git reset --hard</code> after you ask it to not lose uncommitted work! (!!)</p>
<p>Thanks for looking at that integration doc with <code>JSV</code>. It was just brainstorms, really. Will look when time allows.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369123" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/jsv-json-schema-validation-library-for-elixir-with-support-for-2020-12/68502/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-369123" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369123"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #17"></div>
  </section>
</div>
    <div class="postbit" id="369136" data-post-id="369136">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="gtcode" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gtcode/120/234_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  gtcode
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Haven’t given <code>exdantic</code> (previously a fork of <code>elixact</code>) enough attention. It’s been on the shelf for weeks, awaiting integration.</p>
<p>Thanks for looking at this. You should be able to just disable <code>strict</code> mode.</p>
<p>It might be good for me to deprecate <code>strict</code> mode entirely from <code>exdantic</code>, as it’s not clear yet if it’s needed.  Maybe? IDK.</p>
<pre data-code-wrap="bash"><code class="lang-bash">$ elixir strictModeDeprecation/strict_vs_nonstrict_analysis.exs
=== EXDANTIC STRICT vs NON-STRICT BEHAVIOR ANALYSIS ===

STRICT - Valid atom keys:
  Input: %{name: "Alice", email: "alice@example.com", age: 30}
  ✅ SUCCESS: %StrictSchema{age: 30, email: "alice@example.com", name: "Alice"}

NON-STRICT - Valid atom keys:
  Input: %{name: "Alice", email: "alice@example.com", age: 30}
  ✅ SUCCESS: %NonStrictSchema{age: 30, email: "alice@example.com", name: "Alice"}

---
STRICT - Valid string keys:
  Input: %{"age" =&gt; 25, "email" =&gt; "bob@example.com", "name" =&gt; "Bob"}
  ❌ ERROR: [%Exdantic.Error{path: [], code: :additional_properties, message: "unknown fields: [\"age\", \"email\", \"name\"]"}]

NON-STRICT - Valid string keys:
  Input: %{"age" =&gt; 25, "email" =&gt; "bob@example.com", "name" =&gt; "Bob"}
  ✅ SUCCESS: %NonStrictSchema{age: 25, email: "bob@example.com", name: "Bob"}

---
STRICT - Mixed keys:
  Input: %{"age" =&gt; 35, "email" =&gt; "charlie@example.com", "name" =&gt; "Charlie"}
  ❌ ERROR: [%Exdantic.Error{path: [], code: :additional_properties, message: "unknown fields: [\"age\", \"email\", \"name\"]"}]

NON-STRICT - Mixed keys:
  Input: %{"age" =&gt; 35, "email" =&gt; "charlie@example.com", "name" =&gt; "Charlie"}
  ✅ SUCCESS: %NonStrictSchema{age: 35, email: "charlie@example.com", name: "Charlie"}

---
STRICT - Extra fields (atom keys):
  Input: %{active: true, name: "David", email: "david@example.com", age: 40, role: "admin"}
  ❌ ERROR: [%Exdantic.Error{path: [], code: :additional_properties, message: "unknown fields: [:active, :role]"}]

NON-STRICT - Extra fields (atom keys):
  Input: %{active: true, name: "David", email: "david@example.com", age: 40, role: "admin"}
  ✅ SUCCESS: %NonStrictSchema{age: 40, email: "david@example.com", name: "David"}

---
STRICT - Extra fields (string keys):
  Input: %{"age" =&gt; 28, "created_at" =&gt; "2024-01-01", "email" =&gt; "eve@example.com", "name" =&gt; "Eve", "role" =&gt; "user"}
  ❌ ERROR: [%Exdantic.Error{path: [], code: :additional_properties, message: "unknown fields: [\"age\", \"created_at\", \"email\", \"name\", \"role\"]"}]

NON-STRICT - Extra fields (string keys):
  Input: %{"age" =&gt; 28, "created_at" =&gt; "2024-01-01", "email" =&gt; "eve@example.com", "name" =&gt; "Eve", "role" =&gt; "user"}
  ✅ SUCCESS: %NonStrictSchema{age: 28, email: "eve@example.com", name: "Eve"}

---
STRICT - Missing required field:
  Input: %{name: "Frank"}
  ❌ ERROR: [%Exdantic.Error{path: [:email], code: :required, message: "field is required"}]

NON-STRICT - Missing required field:
  Input: %{name: "Frank"}
  ❌ ERROR: [%Exdantic.Error{path: [:email], code: :required, message: "field is required"}]

---
STRICT - Invalid email:
  Input: %{name: "Grace", email: "invalid-email", age: 32}
  ❌ ERROR: [%Exdantic.Error{path: [:email], code: :format, message: "failed format constraint"}]

NON-STRICT - Invalid email:
  Input: %{name: "Grace", email: "invalid-email", age: 32}
  ❌ ERROR: [%Exdantic.Error{path: [:email], code: :format, message: "failed format constraint"}]

---
STRICT - Nested extra data:
  Input: %{"age" =&gt; 45, "email" =&gt; "henry@example.com", "metadata" =&gt; %{"source" =&gt; "api", "version" =&gt; "v2"}, "name" =&gt; "Henry", "profile" =&gt; %{"bio" =&gt; "Software engineer", "skills" =&gt; ["elixir", "rust"]}}
  ❌ ERROR: [%Exdantic.Error{path: [], code: :additional_properties, message: "unknown fields: [\"age\", \"email\", \"metadata\", \"name\", \"profile\"]"}]

NON-STRICT - Nested extra data:
  Input: %{"age" =&gt; 45, "email" =&gt; "henry@example.com", "metadata" =&gt; %{"source" =&gt; "api", "version" =&gt; "v2"}, "name" =&gt; "Henry", "profile" =&gt; %{"bio" =&gt; "Software engineer", "skills" =&gt; ["elixir", "rust"]}}
  ✅ SUCCESS: %NonStrictSchema{age: 45, email: "henry@example.com", name: "Henry"}

---
=== REAL-WORLD JSON API SCENARIO ===

Typical JSON from API:
{
  "name": "API User",
  "email": "user@api.com",
  "age": 29,
  "id": "12345",
  "created_at": "2024-01-15T10:30:00Z",
  "updated_at": "2024-01-15T10:30:00Z",
  "metadata": {
    "source": "registration",
    "ip_address": "192.168.1.1"
  }
}

Parsed JSON: %{"age" =&gt; 29, "created_at" =&gt; "2024-01-15T10:30:00Z", "email" =&gt; "user@api.com", "id" =&gt; "12345", "metadata" =&gt; %{"ip_address" =&gt; "192.168.1.1", "source" =&gt; "registration"}, "name" =&gt; "API User", "updated_at" =&gt; "2024-01-15T10:30:00Z"}

STRICT - Real API JSON:
  Input: %{"age" =&gt; 29, "created_at" =&gt; "2024-01-15T10:30:00Z", "email" =&gt; "user@api.com", "id" =&gt; "12345", "metadata" =&gt; %{"ip_address" =&gt; "192.168.1.1", "source" =&gt; "registration"}, "name" =&gt; "API User", "updated_at" =&gt; "2024-01-15T10:30:00Z"}
  ❌ ERROR: [%Exdantic.Error{path: [], code: :additional_properties, message: "unknown fields: [\"age\", \"created_at\", \"email\", \"id\", \"metadata\", \"name\", \"updated_at\"]"}]

NON-STRICT - Real API JSON:
  Input: %{"age" =&gt; 29, "created_at" =&gt; "2024-01-15T10:30:00Z", "email" =&gt; "user@api.com", "id" =&gt; "12345", "metadata" =&gt; %{"ip_address" =&gt; "192.168.1.1", "source" =&gt; "registration"}, "name" =&gt; "API User", "updated_at" =&gt; "2024-01-15T10:30:00Z"}
  ✅ SUCCESS: %NonStrictSchema{age: 29, email: "user@api.com", name: "API User"}

=== PERFORMANCE IMPLICATIONS ===

Performance (1000 validations):
  Strict mode (valid data): 1.59ms
  Non-strict mode (valid data): 1.26ms
  Strict mode (extra fields): 5.49ms
  Non-strict mode (extra fields): 1.56ms

=== KEY INSIGHTS ===
1. Strict mode ONLY works with atom keys in practice
2. Non-strict mode handles both atom and string keys gracefully
3. Real-world JSON APIs always have extra fields
4. String keys are the norm for external data
5. Strict mode limits interoperability significantly
</code></pre>
<p><a href="https://github.com/nshkrdotcom/exdantic/blob/main/strictModeDeprecation/strict_vs_nonstrict_analysis.exs" class="onebox" target="_blank" rel="noopener nofollow ugc">https://github.com/nshkrdotcom/exdantic/blob/main/strictModeDeprecation/strict_vs_nonstrict_analysis.exs</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369136" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/jsv-json-schema-validation-library-for-elixir-with-support-for-2020-12/68502/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-369136" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369136"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #18"></div>
  </section>
</div>
    <div class="postbit" id="386029" data-post-id="386029">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lud" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lud/120/14382_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lud
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hello everyone,</p>
<p>The library is fairly stable and mostly complete now. I would like to prepare a v1.0.0 release.</p>
<p>I would like to collect feedback from the users of the library:</p>
<ul>
<li>What is your main use case with it,</li>
<li>what do you like,</li>
<li>what could be improved,</li>
<li>any problems you have (bugs, inconsistencies, etc).</li>
</ul>
<p>Thank you <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="386029" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/jsv-json-schema-validation-library-for-elixir-with-support-for-2020-12/68502/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-386029" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="386029"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>