|
| 1 | +# Code Generation Guide |
| 2 | + |
| 3 | +!!! note "Coming Soon" |
| 4 | + Code generation integration is under active development. This guide |
| 5 | + describes the planned capabilities. |
| 6 | + |
| 7 | +Synapify integrates with riddl-gen to transform your validated RIDDL models |
| 8 | +into implementation artifacts. Rather than manually translating designs into |
| 9 | +code, you generate a starting point that preserves your model's structure |
| 10 | +and intent. |
| 11 | + |
| 12 | +--- |
| 13 | + |
| 14 | +## Why Generate? |
| 15 | + |
| 16 | +A RIDDL model captures the essential design of your system—domains, contexts, |
| 17 | +entities, commands, events, and handlers. Code generation bridges the gap |
| 18 | +between this design and working software. |
| 19 | + |
| 20 | +**Benefits of generation:** |
| 21 | + |
| 22 | +- **Accelerate implementation** by producing boilerplate automatically |
| 23 | +- **Ensure consistency** between design and code structure |
| 24 | +- **Reduce translation errors** that occur with manual coding |
| 25 | +- **Maintain traceability** from requirements through implementation |
| 26 | +- **Enable iteration** by regenerating after model changes |
| 27 | + |
| 28 | +--- |
| 29 | + |
| 30 | +## How It Works |
| 31 | + |
| 32 | +Synapify connects to riddl-gen via HTTP requests. When you generate artifacts: |
| 33 | + |
| 34 | +1. **Synapify sends your validated model** to riddl-gen |
| 35 | +2. **You select target platforms and options** for generation |
| 36 | +3. **riddl-gen processes the model** and produces artifacts |
| 37 | +4. **Artifacts are returned** to Synapify or written to a specified location |
| 38 | +5. **You review and integrate** the generated code into your project |
| 39 | + |
| 40 | +Generation produces a starting point, not finished software. Human developers |
| 41 | +refine the generated code, implement business logic placeholders, and add |
| 42 | +infrastructure details. |
| 43 | + |
| 44 | +--- |
| 45 | + |
| 46 | +## Generation Targets |
| 47 | + |
| 48 | +riddl-gen supports multiple output formats. Initial targets focus on |
| 49 | +documentation and reactive microservices, with additional platforms planned. |
| 50 | + |
| 51 | +### Documentation |
| 52 | + |
| 53 | +Generate human-readable documentation from your model: |
| 54 | + |
| 55 | +| Format | Description | |
| 56 | +|--------|-------------| |
| 57 | +| **AsciiDoc** | Technical documentation suitable for PDF or HTML | |
| 58 | +| **Hugo** | Static site content for Hugo-based documentation sites | |
| 59 | + |
| 60 | +Documentation generation extracts: |
| 61 | + |
| 62 | +- Model structure and hierarchy |
| 63 | +- Definition descriptions (`briefly` and `described as` content) |
| 64 | +- Type definitions with field documentation |
| 65 | +- Message catalogs (commands, events, queries) |
| 66 | +- Glossary terms from `term` definitions |
| 67 | + |
| 68 | +### Akka/Scala |
| 69 | + |
| 70 | +Generate reactive microservice code targeting the Akka framework: |
| 71 | + |
| 72 | +| Artifact | Description | |
| 73 | +|----------|-------------| |
| 74 | +| **Entity classes** | Akka Persistence actors with command handlers | |
| 75 | +| **Message definitions** | Case classes for commands, events, queries | |
| 76 | +| **Type definitions** | Scala case classes matching RIDDL types | |
| 77 | +| **State classes** | Immutable state representations | |
| 78 | +| **API endpoints** | Akka HTTP routes for external interfaces | |
| 79 | + |
| 80 | +The generated Scala code follows Akka best practices: |
| 81 | + |
| 82 | +- Event sourcing for entity persistence |
| 83 | +- CQRS separation of commands and queries |
| 84 | +- Cluster sharding for entity distribution |
| 85 | +- Typed actors for compile-time safety |
| 86 | + |
| 87 | +### Quarkus/Java (Planned) |
| 88 | + |
| 89 | +Generate reactive microservice code targeting the Quarkus framework: |
| 90 | + |
| 91 | +| Artifact | Description | |
| 92 | +|----------|-------------| |
| 93 | +| **Entity classes** | Hibernate Reactive entities | |
| 94 | +| **Message definitions** | Java records for commands, events, queries | |
| 95 | +| **Type definitions** | Java records matching RIDDL types | |
| 96 | +| **API endpoints** | JAX-RS resources for external interfaces | |
| 97 | + |
| 98 | +--- |
| 99 | + |
| 100 | +## Using Generation |
| 101 | + |
| 102 | +### Prerequisites |
| 103 | + |
| 104 | +Before generating code: |
| 105 | + |
| 106 | +1. **Validate your model** - Generation requires a valid RIDDL model with no |
| 107 | + errors |
| 108 | +2. **Complete handlers** - Handlers with `???` placeholders generate stub |
| 109 | + implementations |
| 110 | +3. **Document thoroughly** - Descriptions become code comments and |
| 111 | + documentation |
| 112 | + |
| 113 | +### Generation Workflow |
| 114 | + |
| 115 | +1. **Open generation panel** in Synapify |
| 116 | +2. **Select target** (documentation format or code platform) |
| 117 | +3. **Configure options** for the selected target |
| 118 | +4. **Choose output location** (download or write to directory) |
| 119 | +5. **Generate** and review the results |
| 120 | +6. **Integrate** generated artifacts into your project |
| 121 | + |
| 122 | +### Configuration Options |
| 123 | + |
| 124 | +Each target has specific options: |
| 125 | + |
| 126 | +**Documentation:** |
| 127 | + |
| 128 | +- Output format (single file vs. multiple files) |
| 129 | +- Include/exclude specific sections |
| 130 | +- Diagram generation settings |
| 131 | + |
| 132 | +**Akka/Scala:** |
| 133 | + |
| 134 | +- Package naming conventions |
| 135 | +- Serialization format (JSON, Protobuf) |
| 136 | +- Test scaffold generation |
| 137 | +- Build file format (sbt, Mill) |
| 138 | + |
| 139 | +**Quarkus/Java:** |
| 140 | + |
| 141 | +- Package naming conventions |
| 142 | +- Build file format (Maven, Gradle) |
| 143 | +- Database configuration hints |
| 144 | + |
| 145 | +--- |
| 146 | + |
| 147 | +## Understanding Generated Code |
| 148 | + |
| 149 | +### Structure Mapping |
| 150 | + |
| 151 | +RIDDL definitions map to code artifacts: |
| 152 | + |
| 153 | +| RIDDL Definition | Generated Artifact | |
| 154 | +|------------------|-------------------| |
| 155 | +| Domain | Package/module namespace | |
| 156 | +| Context | Service boundary/module | |
| 157 | +| Entity | Actor/entity class with handlers | |
| 158 | +| Type | Data class/record | |
| 159 | +| Command | Inbound message class | |
| 160 | +| Event | Outbound message class | |
| 161 | +| Query | Request/response pair | |
| 162 | +| Handler | Method implementations | |
| 163 | + |
| 164 | +### Placeholder Implementation |
| 165 | + |
| 166 | +Handlers containing pseudocode (quoted strings) or `???` markers generate |
| 167 | +stub implementations: |
| 168 | + |
| 169 | +**RIDDL:** |
| 170 | +```riddl |
| 171 | +on command AddItem { |
| 172 | + "validate item exists in catalog" |
| 173 | + "add item to cart with specified quantity" |
| 174 | + send event ItemAdded to outlet Events |
| 175 | +} |
| 176 | +``` |
| 177 | + |
| 178 | +**Generated Scala:** |
| 179 | +```scala |
| 180 | +def handleAddItem(cmd: AddItem): Effect[Event, State] = { |
| 181 | + // TODO: validate item exists in catalog |
| 182 | + // TODO: add item to cart with specified quantity |
| 183 | + Effect.persist(ItemAdded(...)) |
| 184 | +} |
| 185 | +``` |
| 186 | + |
| 187 | +The structure is in place; developers fill in the implementation details. |
| 188 | + |
| 189 | +### What's Not Generated |
| 190 | + |
| 191 | +Generation produces structure, not complete applications. You still need to: |
| 192 | + |
| 193 | +- **Implement business logic** in handler placeholders |
| 194 | +- **Configure infrastructure** (databases, message brokers, etc.) |
| 195 | +- **Add authentication/authorization** appropriate to your environment |
| 196 | +- **Write tests** beyond the generated scaffolds |
| 197 | +- **Handle deployment** configuration and orchestration |
| 198 | + |
| 199 | +--- |
| 200 | + |
| 201 | +## Iterative Development |
| 202 | + |
| 203 | +Generation supports an iterative workflow where model and implementation |
| 204 | +evolve together. |
| 205 | + |
| 206 | +### Initial Generation |
| 207 | + |
| 208 | +Start with a basic model and generate initial scaffolding: |
| 209 | + |
| 210 | +1. Define domains, contexts, and core entities |
| 211 | +2. Add key commands and events |
| 212 | +3. Generate code to establish project structure |
| 213 | +4. Commit generated code as baseline |
| 214 | + |
| 215 | +### Incremental Updates |
| 216 | + |
| 217 | +As the model evolves: |
| 218 | + |
| 219 | +1. Add new definitions or modify existing ones |
| 220 | +2. Regenerate affected artifacts |
| 221 | +3. Merge generated changes with existing implementations |
| 222 | +4. Preserve custom code in designated areas |
| 223 | + |
| 224 | +### Handling Conflicts |
| 225 | + |
| 226 | +When regenerating after model changes: |
| 227 | + |
| 228 | +- **New definitions** generate new files (no conflict) |
| 229 | +- **Removed definitions** leave orphaned files (manual cleanup) |
| 230 | +- **Modified definitions** may conflict with customizations |
| 231 | + |
| 232 | +Strategies for managing conflicts: |
| 233 | + |
| 234 | +- **Separate generated and custom code** into distinct directories |
| 235 | +- **Use extension points** where generators provide hooks |
| 236 | +- **Review diffs carefully** before accepting regenerated code |
| 237 | + |
| 238 | +--- |
| 239 | + |
| 240 | +## Best Practices |
| 241 | + |
| 242 | +### Generate Early |
| 243 | + |
| 244 | +Run generation early in the design process, even with incomplete models. |
| 245 | +Seeing generated code reveals: |
| 246 | + |
| 247 | +- Whether naming conventions work in practice |
| 248 | +- How complex the implementation will be |
| 249 | +- Where the model needs more detail |
| 250 | + |
| 251 | +### Keep Models and Code Synchronized |
| 252 | + |
| 253 | +When implementation reveals design issues: |
| 254 | + |
| 255 | +1. Update the RIDDL model first |
| 256 | +2. Regenerate to get updated structure |
| 257 | +3. Merge implementation changes |
| 258 | + |
| 259 | +The model remains the source of truth. |
| 260 | + |
| 261 | +### Document for Generation |
| 262 | + |
| 263 | +Thorough documentation in your model produces better generated artifacts: |
| 264 | + |
| 265 | +- `briefly` descriptions become class/method comments |
| 266 | +- `described as` content becomes documentation sections |
| 267 | +- `term` definitions create glossaries |
| 268 | + |
| 269 | +### Version Generated Code |
| 270 | + |
| 271 | +Commit generated code to version control: |
| 272 | + |
| 273 | +- Track what was generated and when |
| 274 | +- Enable diff comparison after regeneration |
| 275 | +- Provide baseline for manual modifications |
| 276 | + |
| 277 | +--- |
| 278 | + |
| 279 | +## Target Platform Details |
| 280 | + |
| 281 | +### Akka/Scala Deep Dive |
| 282 | + |
| 283 | +The Akka generator produces idiomatic Scala code following these patterns: |
| 284 | + |
| 285 | +**Entity Implementation:** |
| 286 | +```scala |
| 287 | +object Product { |
| 288 | + // Commands |
| 289 | + sealed trait Command |
| 290 | + case class CreateProduct(...) extends Command |
| 291 | + case class UpdatePrice(...) extends Command |
| 292 | + |
| 293 | + // Events |
| 294 | + sealed trait Event |
| 295 | + case class ProductCreated(...) extends Event |
| 296 | + case class PriceUpdated(...) extends Event |
| 297 | + |
| 298 | + // State |
| 299 | + case class State(info: ProductInfo) |
| 300 | + |
| 301 | + // Behavior |
| 302 | + def apply(id: ProductId): Behavior[Command] = |
| 303 | + EventSourcedBehavior(...) |
| 304 | +} |
| 305 | +``` |
| 306 | + |
| 307 | +**Configuration generated:** |
| 308 | + |
| 309 | +- `application.conf` with Akka settings |
| 310 | +- Cluster sharding configuration |
| 311 | +- Serialization bindings |
| 312 | +- Persistence plugin setup |
| 313 | + |
| 314 | +### Documentation Deep Dive |
| 315 | + |
| 316 | +Documentation generation produces structured content: |
| 317 | + |
| 318 | +**AsciiDoc output:** |
| 319 | +```asciidoc |
| 320 | += OnlineRetail Domain |
| 321 | +:toc: |
| 322 | + |
| 323 | +== Overview |
| 324 | +The OnlineRetail domain encompasses all aspects of selling |
| 325 | +products to consumers through digital channels. |
| 326 | + |
| 327 | +== Contexts |
| 328 | + |
| 329 | +=== Catalog Context |
| 330 | +Product catalog and browsing experience. |
| 331 | + |
| 332 | +==== Entities |
| 333 | + |
| 334 | +===== Product Entity |
| 335 | +A product available for purchase. |
| 336 | + |
| 337 | +.Commands |
| 338 | +[cols="1,2"] |
| 339 | +|=== |
| 340 | +|Command |Description |
| 341 | +|CreateProduct |Creates a new product in the catalog |
| 342 | +|UpdatePrice |Changes the price of an existing product |
| 343 | +|=== |
| 344 | +``` |
| 345 | + |
| 346 | +--- |
| 347 | + |
| 348 | +## Related Documentation |
| 349 | + |
| 350 | +- [RIDDL Language Reference](../riddl/references/language-reference.md) - |
| 351 | + Complete language syntax |
| 352 | +- [Author's Guide](../riddl/guides/authors/index.md) - Writing effective |
| 353 | + models |
| 354 | +- [Implementor's Guide](../riddl/guides/implementors/index.md) - Working |
| 355 | + with generated code |
0 commit comments