On CLIs
90% of application domain development is deciding what are nouns and verbs of the solution (do not believe this number). Nouns are the state applications will ingest and produce. Verbs are actions the app will take to achieve this. Designing a CLI forces us to answer those questions. We can decide what language the application domain actually speaks. This is an invaluable property when explaining how an application works to your colleagues. It helps to improve application maintainability by providing a simple interface to use. It also prepares us for designing an API around the application if it's ever needed.
There are repeatable patterns in design of CLI applications that are not about solving problems in the application domain. We can call those aspects “infrastructure of CLI applications”. Common elements are:
We should have appropriate solution strategies and libraries (where appropriate) to deal with each of those challenges. This way each new CLI does not need to implement those from scratch. Those infrastructure libraries essentially create an application tech stack on which pure problem domain solutions can be built.
There are repeatable patterns in design of CLI applications that are not about solving problems in the application domain. We can call those aspects “infrastructure of CLI applications”. Common elements are:
- Layout of application source files and various coding conventions.
- Managing state with Resources: CRUD operations can be applied to Resources and the application specifies how it interacts with them.
- Role Based Access Controls: Define what entity is executing computation and what permissions it has to interact with Resources.
- Storage of state to persistent storage.
- What are outside systems an application depends on, how to connect to them?
- How to deal with failure outcomes?
- How to organize observability of the application: where do logs go, how to make them useful?
- How to deal with multiple deployment environments the application can be running in?
We should have appropriate solution strategies and libraries (where appropriate) to deal with each of those challenges. This way each new CLI does not need to implement those from scratch. Those infrastructure libraries essentially create an application tech stack on which pure problem domain solutions can be built.