Prototype Repository Code Structure - evomimic/map-proto1 GitHub Wiki
The folders hierarchy within the map-proto1 github repository reflects the prototype architecture and holochain repository conventions (largely following the Holochain Open Development repository conventions.
There are a number of packaging considerations:
- Git structuring elements: repositories, branches, directories Rust packaging elements: workspaces, packages, crates (library and binary), modules, and sub-modules
- Holochain packaging elements: hApps, DNAs, Zomes (Integrity and Coordination), hApps
- Architectural principles: separation of concerns, modularity, avoiding circular dependencies, evolvability, independent releasability
- Understandability: how intuitive is the overall repo structure? Does it follow common conventions and idioms?
- Fast refactoring vs. Modularity : Prematurely imposing a highly modular structure (though beneficial in the long haul) can make re-factoring the structure difficult and time-consuming. While in early prototyping phases, the architecture is very fluid. On the other hand, the viability of a modular structure is only understood when we actually try it out. It's hard to make micro services out of a monolith. Experimenting with architectural alternatives for the MAP is one of the goals of the prototype
Folders:
- .github/workflows -- standard github workflow stuff
- crates -- all Zome code
- coordinator_zomes (contains library crates that comply with Holonchain HDI rules regarding coordinator zomes)
- apis - folder containing all (and only) api crates
- cz1-api - folder containing the definition of the API Crate for coordinator zome cz1 (substitute the actual zome name for cz1).
- src -- contains all source code
- tests -- contains unit test code for this zome
- Cargo.toml -- Rust package manifest
- README.md -- standard README documentation for this zome
- cz2-api - folder containing definition of the API Crate for coordinator zome cz2 (has some underlying structure as -api).
- cz1-api - folder containing the definition of the API Crate for coordinator zome cz1 (substitute the actual zome name for cz1).
- impls - folder containing all (and only) crates containing implementations of the API's defined in the api crates
- cz1-impl - folder containing definition of the impl Crate for coordinator zome cz1 (substitute the actual zome name for cz1).
- src -- contains all source code
- tests -- contains unit test code for this zome
- Cargo.toml -- Rust package manifest
- README.md -- standard README documentation for this zome
- cz2-api - folder containing definition of the API Crate for coordinator zome cz2 (has some underlying structure as -api)
- cz1-impl - folder containing definition of the impl Crate for coordinator zome cz1 (substitute the actual zome name for cz1).
- apis - folder containing all (and only) api crates
- integrity_zomes (contains library crates that comply with Holonchain HDI rules regarding integrity zomes)
- iz1 - folder containing the definition of the Crate for integrity zome iz1 (substitute the actual zome name for iz1).
- src -- contains all source code
- tests -- contains unit test code for this zome
- Cargo.toml -- Rust package manifest
- README.md -- standard README documentation for this zome
- iz1 - folder containing the definition of the Crate for integrity zome iz1 (substitute the actual zome name for iz1).
- coordinator_zomes (contains library crates that comply with Holonchain HDI rules regarding coordinator zomes)
- docs -- documentation in markdown under github version control
- nix
- ui -- all client code
- workdir -- contains DNA and hApp manifests that reference various zomes
Files
Cargo.toml -- Rust workspace manifest
(other files)
NOTES:
- All prototype functionality will be bundled into a single DNA and a single hAPP. Going forward, we will likely split holonspace, metaspace and vspace out into separate repos and separate hApps (each with their own DNA).
- Zomes are decoupled from DNAs and hApps.
- Crates are segregated into integrity and coordinator types
- Coordinator zomes have separate crates for their interface (api) and their implementation (impl)
- Integrity zomes contain only struct and enum definitions, so separate crates are not required for api and impl
The proposed structured was derived from the following packaging principles:
- Each holochain zome is realized as a Rust Library Crate.
- All code must (ultimately) live in a zome, but independent library crates can be pulled into zomes.
- A single zome may be included in more than one DNA -- i.e., DNA's are associated with zomes, but they don't aggregate them. So zomes, probably shouldn't be placed hierarchically under a particular DNA folder.
- DNA's and hApps are defined in .yaml files in a
workdirfolder. - Integrity zome code (and the library crates they include) must not be mixed with coordinator zome code.
- Coordinator zomes depend upon integrity zomes, but not the other way around. So path expressions in coordinator zome code are more sensitive to their place in the Rust packaging hierarchy.
- Each coordinator zome is typically fairly strongly coupled with a particular integrity zome, so the path to that integrity zome should be fairly stable.
- Clean separation of interfaces from implementation is an essential aspect of multiple design patterns (e.g., Strategy, Decorator, Chain of Responsibility). To avoid inadvertent dependencies on implementation code, separate crates are required for api vs. implementation.
The proposed structure provides a clean separation of interfaces (traits) and implementations. Factories (based on either the Abstract Factory Pattern or Factory Method Pattern) are used to instantiate implementations for traits.
The following diagram illustrates the allowable dependencies. Strict adherence to the dependencies shown is essential to avoid circular dependencies.
