Trying to get developers to agree on a single definition of a good API is mission impossible. But this does not mean that we should stop trying ;) Here are three things that we learned about the Ansible module's API design while developing Ansible Collections for more than a year.
Each module should address a relatively well-defined use case that will guide the development process. Just wrapping an underlying API is not the best option because they are often too low-level for end users.
The module's API should describe the operation's result, not the procedure itself. Such APIs drastically reduce the need for conditional processing in Ansible playbooks and make it easier to reason about the managed system's state.
If the Ansible module talks to a remote service, it should have its connection options separated from the rest of the parameters that describe the task's result. Alternatively, the module can use a custom Ansible connection plugin and ignore connection options entirely.