we get rid of canvases and then only have package functions and types. But then, how do we write functions which use DBs or secrets?
We previously thought that perhaps we would have the idea of a “context”, and a context would contain a mapping between an “abstract DB” such as “Users” and a concrete DB, such as the Users Datastore on my canvas with the TLID 23723497823.
We couldn't quite figure out this mopping, especially from a security perspective. Would anyone be allowed have a “Users” abstract DB, and if so, how do we ensure that only the callers that was supposed to get access to? It got access to it and not any package that use the abstract DB “Users”.
Part of the problem here is that we can't quite don't quite have an idea of what it means to have these abstract DBs. Not only is the security model not well understood, but also it’s a bit hard for users to map.
Instead of having DB names in the code, only have DB values (DB values would be parametrized on their type, eg DB<StripeUser>
). That way if anyone wants to call something on a DB, they need to have it passed in as an argument. eg:
let findUserByName (userDB : DB<StripeUser>) (name : string) =
DB.query userDB \\u -> u.name == name
At a top level then, the /users/:name
handler in your canvas can map to MyModule.findUsersByName MyUserDB
(similar for secrets, workers, etc)
Some functions will need multiple DBs or secrets passed to them, and some modules might make a type shared by all the functions in that module containing the various things they need to make a call. In that case, we’d like the user to be able to easily have a “name” for a value of that type so they can use it easily. In a standard repo that would be a function that returns the values, but if we don’t provide a way to