raze
raze copied to clipboard
Custom State class
Hey Sam, really been enjoying using Raze so far.
I wondered if you would humor the idea, for the future of Raze, to remove the existing ctx.state
hash for a user-defined Raze::State
. While the hash works, for more complicated applications it's not fun to work with ctx.state
since the hash contains many additional added types via add_context_storage_type
, and you have to do additional type reductions, i.e.
user_model = ctx.state["user"] #=> Nil, String, Int32, Int64, Float64, Bool.... and User
user_model.email # Won't compile
if user_model.is_a?(UserModel) # or .responds_to?(:email), etc
# Type is reduced in here, but the programmer already knows this.. feels like "boilerplate"
user_model # UserModel
user_model.email # OK!
end
If we could define our own State
for our app with its own property
, combined with using assertions / other validation in middleware, the above code inside a route (after all middleware) could be simplified to ctx.state.user.email
, since we can guarantee the User
.
# in some middleware..
ctx.state.user = UserModel.maybe_find_user(name: "z64")
halt unless ctx.state.user
ctx.state.user.not_nil!
done.call
This is already possible by not using ctx.state
at all and using my own methods to track state.. but this is of course coding around the library instead of using it :)
Thoughts? To me, the state hash feels like something brought over from Ruby frameworks that doesn't work well in Crystal (except for small apps that only use these primitive types, I guess).
Perhaps the add_context_storage_type
macro could simply reopen Raze::State
(an empty class) and add whatever property
;
module Raze
class State
end
macro add_state_property(prop)
class State
property {{prop}}
end
end
add_state_property int : Int32 = 0
p State.new.int # 0
end
This sound like a fantastic idea. I look into your merge request and see what we can do.
Great! :heart: Take your time.