A Slight Delight - Compile-time checking things
2020-01-06Underjord is a tiny, wholesome team doing Elixir consulting and contract work. If you like the writing you should really try the code. See our services for more information.
This was a short-but-sweet thing that struck me while working with a client code-base. It was trivial but both useful and delightful and it is a type of thing I haven't been able to do in Python, PHP and Javascript in quite the same way.
Initially, the code was something like this:
defmodule MyApp.Schemas do
alias ExJson.Schema
def my_schema do
%{
"properties" => %{
"email" => %{
"type": "string",
},
"password" => %{
"type": "string",
}
}
} |> Schema.resolve()
end
end
So for this JSON schema library the Schema.resolve
function verifies that your JSON schema is defined in
a
valid manner and lives up to the JSON schema specification. So it doesn't do anything related to user-provided data
or parsing JSON data. While familiarizing myself with the library I saw that you should probably avoid calling
resolve repeatedly. Which makes sense, if the schema doesn't change, why call it again. Some previous developer
probably missed that. It happens.
What I ended up doing was:
defmodule MyApp.Schemas do
alias ExJson.Schema
@my_schema Schema.resolve(%{
"properties" => %{
"email" => %{
"type": "string",
},
"password" => %{
"type": "string",
}
}
})
def my_schema do
@my_schema
end
end
So what does this give us? Well, module attributes are resolved at compile-time. This is why
@my_secret System.get_env("MY_SECRET")
often leads to unwanted behavior. But in this case, our schemas
are part of our code and will not change at run-time or between environments. So we can shift the resolution to
happen at compile-time and never have to do it at run-time.
- The cost of calling
Schema.resolve
is paid up front at compile-time. - Errors in defining JSON schemas show up at compile-time rather than run-time when you attempt to validate something.
Having put much less time into compiled languages this was delightful. Being able to shift some checks back to compile-time is incredibly useful. I've also had a reason to write some macros which was fun.
If you have some suggestions, corrections or thoughts on this let me know at lars@underjord.io.
Underjord is a 4 people team doing Elixir consulting and contract work. If you like the writing you should really try the code. See our services for more information.
Note: Or try the videos on the YouTube channel.