Earlier this year I worked on bindings/wrappers for the Safe APIs in Node.js. I noticed I was struggling to use it ‘ergonomically’. Now that Safe is getting to a point where looking at the high-level APIs becomes relevant, I want to write down some of my reflections.
Currently we have a low-level API (client, safe_network::client
) and high-level API (app, sn_api
). The high-level API at the moment mostly functions as a way to support the CLI and does this by providing a function for each CLI command.
- Perhaps the high-level API is focused too narrowly on supporting the CLI, which is stateless.
- As a result, it seems most function calls stand on their own. For example, to put a value in a new register on the network, the register has to be created and written to, but with two different async calls that can not be combined into a single ‘action’.
- The low-level API does provide a way where there is separation of concerns. One can create a register, get the operations to upload and change it on the network, and execute those operations at once.
- Most functions require a flag for specifying a ‘dry run’. This doesn’t seem ergonomic, and would be better captured with separate functionality allowing to calculate addresses and costs.
- The high-level API can’t be used with the low-level API in tandem. This means the high-level API stands very much on its own. Which is enough for the CLI, but probably not for apps wanting to go deeper.
The high-level API can definitely be changed, but perhaps it needs quite an overhaul to make it more ergonomic to use for app developers. It at least needs to conform to the API guideluines in quite some places as a way to make it more friendly to be used.
A possibility that I also thought about is merging the two. I think the low-level API is actually very usable, is not that much different in terms of complexity and lines of code when using it. Merging will at least mean less maintenance to keep them in sync.
But, I understand the need for a high-level API that makes things more easy for developers. Though, Rust can be used in such a way to make use of sensible defaults, which still allows for a lot of control by the end developer.
Also, the high-level API provides Safe URLs and other helpful utilities and protocols, which is good to separate from the low-level part. Perhaps this needs to be put in a separate crate.
The end goal is to have a single API that allows the app developer to do everything the network is capable of, in an ergonomic way that reflects the powers of Safe. I’d love to get some input from the community and MaidSafe about this.