Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Let me first start by saying that this crate is awesome. I think its what the
tower
environment is all about; creating abstraction that compose seamlessly together.However, I think at its core this crate is much too restrictive, and this is why I decided to do my best at providing what I think this abstraction should look like. It is by no means correct, and what I want is simply to start a discussion.
The Changes
I think the best way to describe my view on the design is to talk about the changes I brought in this PR.
A strongly typed
Record
The most flagrant thing that should be added to this crate is the ability to have a strongly typed
Record
. Clearly, what is idiomatic in Rust is to make all abstractions opt-in, rather than opt-out. I think this crate has it in reversed; It requires us to build an abstraction over aKey
-Value
store in order to have some type information. The way it should work is that, by default, users should have a concrete type to work with. They can set this type to beHashMap<K, V>
if they like, but this runtime cost should not be imposed onto them. This PR solves this by adding a generic type to theSessionStore<R>
trait. This generic typeR
is the record.Suppose I wanted to implement a
SessionStore
for some form of storage, and I need the record to be serializable/deserializable, then I as the implementor, am the one to restrictMyStore
:The user of
MyStore
can then use any type they like, as long as it respects the trait bounds.I think this is a good alternative to what was proposed in this discussion thread.
Removal of
async_trait
The new traits now use async functions in traits, which was stabilized in Rust 1.75. The only issue currently is that the user cannot name the output type (the opaque
Future
returned). This will be solved with Return Type Notation which is hopefully close to stabilization (The only thing left I think is this). Then, we will be able to remove allSend
andSync
bounds on theSessionStore
trait (which is simply lovely).It is worth noting that even though this would likely bump up the
msrv
, version 1.75 has been out for more than 9 months now, andaxum
have been considering moving away fromasync_trait
towards this for a while now.Ids are Solely Controlled by the
Store
Various nonsense (collisions, lifetime extension, etc.) can arise if we let both the
Store
and the handler create and changeId
s. Therefore, this PR changes the semantics session by only allowing theStore
to set and modifyId
s.Id
s should not be even instantiable by the handler.This is not fully implemented yet, because right now there is no way of constructing an
Id
(except from the middleware parsing it from a cookie). What I plan on doing is adding a feature flag that theSessionStore
implementor should set in order to have access toId
constructors.Much, much Simpler
Session
sAs a result of all the above, the session type is now much simpler. It is this:
You can do as much as you could then by simply calling methods on directly
store
.Agnostic over
Expiry
This feature is not fully fleshed out yet, but I think it is much better not to impose on users the choice of the
time
crate.Instead of having a concrete
Expiry
type, we could have anExpires
trait that should be implemented for the record typeR
, but I'm not sure yet what it should look like.What is Missing
This PR is very much an
MVP
, it does not have tests, does not have very good docs, etc. A bunch of things are missing, and I haven't got to working on thetower-session
crate yet. Here are some of the missing features:As I said previously, I want to discuss these changes, and please do not hesitate to be highly critical of this PR.