# Basic Project Structure AaC is unopinionated about project structures, so they can be very flexible. However, we do suggest storing models in an organized project directory structure, such as maintaining all AaC files under a top, or near-top level directory `src/`. An example project might look like: ``` src ├── system │ └── system.yaml ├── external | ├── external_actors.yaml │ └── external_interface_messages.yaml ├── service_one | ├── service_one.yaml │ └── service_one_misc.yaml └── service_two └── service_two.yaml Because AaC does not require your models to be located within the same directory, you can house your model files however is necessary and logical for your project needs. An example of this might look like: ``` system └── system.yaml external ├── external_actors.yaml └── external_interface_messages.yaml service_one ├── service_one.yaml └── service_one_misc.yaml service_two └── service_two.yaml ## Anatomy of an AaC file Since AaC leverages YAML for its DSL, there are very few restrictions on how to store and organize AaC files and AaC definitions. The main consideration is that every AaC definition must be defined in its own YAML document _or_ YAML file. YAML provides a keyword/symbol `---` to denote a logical document separator for multiple YAML documents within a YAML file. This means that if we store multiple AaC definitions in the same file, they must be separated using the `---` symbol. If they aren't separated correctly then the AaC file will not be recognized as a valid AaC definition. These two examples are equivalent and both valid: _schemas.yaml_ ```yaml schema: name: Schema1 fields: - name: integer type: int --- schema: name: Schema2 fields: - name: string type: string ``` _schema1.yaml_ ```yaml schema: name: Schema1 fields: - name: integer type: int ``` _schema2.yaml_ ```yaml schema: name: Schema2 fields: - name: string type: string ``` ## Referencing AaC Structures Across Files Another consideration when deciding how to organize AaC definitions is which definitions reference each other. If `definition A` references `definition B`, then both definitions will need to be either declared in the same AaC file or `definition A` will need to define an `import` including the absolute or relative path to the file containing `definition B`. For this example, `schemaA` references `schemaB`, and both definitions are in separate files, as a result `schemaA` is importing the file containing `schemaB`. Additionally, while it's possible to have multiple `import` definitions in a file, good style would suggest using a single `import` list per file. An example of a relative path import is: _schemaA.yaml_ ```yaml import: files: - ./schemaB.yaml --- schema: name: schemaA fields: - name: sub-datastructure type: schemaB - name: integer type: int ``` _schemaB.yaml_ ```yaml schema: name: schemaB fields: - name: string type: string ``` An example of a an absolute path import is: _schemaA.yaml_ ```yaml import: files: - C:/src/external/external_actors/schemaB.yaml --- schema: name: schemaA fields: - name: sub-datastructure type: schemaB - name: integer type: int ``` _schemaB.yaml_ ```yaml schema: name: schemaB fields: - name: string type: string ``` ## Embedding AaC files alongside your implementation Because AaC can be used to generate code, users may find themselves with a project repository consisting of: 1. AaC files that describe the architecture and drive code-stub generation 2. Version-controlled implementation files that compliment the stub/interface code files generated by AaC There is no requirement to maintain these files in any sort of relationship or directory structure as long as the AaC files can reference each other. The best practice would be to have your VCS ignore the generated/stubbed files and leverage automated workflows and user/developer environments to generate the stub/interface files as fresh artifacts every time they're used -- this helps prevent configuration drift between what is defined in your AaC files and the downstream artifacts. ## Creating a User Library for your project Because of the extensibility and reusability goals of AaC, a plugin can also be designed as a library for a project. By making a plugin to function more as a library, it exposes itself as a tool to be utilized in a larger context throughout the AaC space. For more information on making a User Library, view [Creating a User Library](user_library).