we want to check permissions / scopes in our code....
# getting-started
f
we want to check permissions / scopes in our code. The scope names are defined externally, e.g.
spreadsheets:read.all
We would use is e.g. as
requireScope("spreadsheets:read.all")
I like plain text here over using constants like
SPREADSHEETS_READ_ALL
because it stays in the domain language of the scope, rather than using the kotlin constant. But it would be great to have some sort of compile time check here so you cannot have a typo in the scope string. (They are all known ahead). Any ideas?
j
I don't understand why you prefer strings, what does it mean to "stay in the domain language of the scope"? The reason people prefer constants is exactly because they are checked by the compiler (and also provide auto-complete).
I don't see much difference between the hardcoded strings and the constants in terms of readability/expressivity. But I do see a lot of difference in convenience and safety when using constants: • you get compile time checking (no risk of typos) • you get auto-complete - no need to copy-paste, less risk of pasting the wrong one • it gives you the option to search for all actual code usages of a scope through your IDE instead of full-text search, so you can avoid seeing usages in docs/text and declaration sites
If you don't treat those strings as opaque, you could also allow to build scopes with type-safe code, like
Scope.spreadsheets.readAll()
Either way, I would also suggest using a
value class
to represent the scopes instead of the string type, to avoid mixing up with other strings
m
Create one or more enums that mimic your permissions format, so you can have both a visual hint and type safety. For example:
Copy code
import Scopes.Spreadsheets
...

Spreadsheets.ReadAll
f
Using package/class hierarchies to at least mimic the separation of the original parts of the scopes makes sense.
Spreadsheets.ReadAll
looks better than
SPREADSHEETS_READ_ALL
. Thanks for the suggestions. Not 100% what I prefer but a fair trade-of
👌 1
m
you could have the enums build the original string representation in their toString(), as well as a parsing function if those strings come from a configuration or else, I don’t know the details
Best of both worlds, since you said “The scope names are defined externally” you could generate the enum source code from those definitions. That way you have an external single source of truth in simple text (if you like that), while the generated enums are a commodity that provides type-safety to your code and avoids repetition and manual errors