[v3] RFC: Doing away with iterators
The original reason why jwx came with iterators was because we wanted to make the objects in jwx goroutine safe at any cost, while allowing a map-ish feel to its operations. This stems from the fact that in the very early days the samples that we examined mostly were glorified maps:
// Note exact implementation, but the "feel" of APIs that we were thinking back then.
token, _ := jwtlib.ParseBlahBlah(...)
for key, val := range token {
...
}
The next step in the evolution was to make this sort of feel available, but also protect jwx objects to from sloppy concurrent accesses:
for key, val := range token {
if val == something {
token.Set(key, newVal) // Is this legit?
}
}
For map-like constructs, we thought back then that the iterator design would have been "safer" because then it would already give you both the key and the value for simple cases, and for more interesting applications we would be able to use methods like Walk():
for iter.Next() {
pair := iter.Pair()
fmt.Printf("%s %s\n", pair.Key, pair.Value)
}
In hindsight it turned out that this API wasn't widely used, and when it was, it kind of threw users off, because it wasn't naturally Go-ish, as well as requiring context.Context. And then there were problems like this which really stemmed from the fact that other tools were discovering these structs and methods that really didn't have anything to do with handling jwx stuff, and yet it was causing problems.
So for v3, I think we should just get rid of all the iterators. Instead, we will provide a FieldNames() method (note: not Keys(), because that would clash with (jwk.Set).Keys()) that returns a list of all key names, and then the user can do what they please with, and that's it
for _, key := range token.FieldNames() {
var val interface{}
if err := token.Get(key, &val); err != nil {
return err
}
}
I believe there will be some code breakage because of this, but I also think that disruption caused by this change is minimal as the compiler will be able to loudly complain about the use of old API, which would be easy for users to detect.