Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix formatting and consistency in appmodel.md table of contents and e…
…xamples
  • Loading branch information
davidfowl committed Jul 12, 2025
commit 985910d2cc6913bb07ddf49a5b795afecdde095c
45 changes: 22 additions & 23 deletions docs/specs/appmodel.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@
- [Structured vs Literal Values](#structured-vs-literal-values)
- [Value Providers and Deferred Evaluation](#value-providers-and-deferred-evaluation)
- [Core Value Types (Expanded)](#core-value-types-expanded)
- [Publish and Run Phases](#publish-and-run-phases)
- [Core Value Types (Expanded)](#core-value-types-expanded)
- [ReferenceExpression](#referenceexpression)
- [Endpoint Primitives](#endpoint-primitives)
- [Context-Based Endpoint Resolution](#context-based-endpoint-resolution)
- [API Patterns](#api-patterns)
- [Full Examples](#full-examples)
- [Example: Derived Container Resource (Redis)](#example-derived-container-resource-redis)
- [Example: Custom Resource (Talking Clock)](#example-custom-resource-talking-clock)
- [Example: Custom Resource - Talking Clock](#example-custom-resource---talking-clock)
- [Glossary](#glossary)

---
Expand Down Expand Up @@ -258,9 +258,9 @@

Aspire integrates with .NET health checks to monitor the status of resources after they have started. The health check mechanism is tied into the resource lifecycle:

1. When a resource transitions to the `Running` state, Aspire checks if it has any associated health check annotations (typically added via `.WithHealthCheck(...)`).
2. **If health checks are configured:** Aspire begins executing these checks periodically. The resource is considered fully "ready" only after its health checks pass successfully. Once healthy, Aspire automatically publishes the `ResourceReadyEvent`.
3. **If no health checks are configured:** The resource is considered "ready" as soon as it enters the `Running` state. Aspire automatically publishes the `ResourceReadyEvent` immediately in this case.
1. When a resource transitions to the `Running` state, Aspire checks if it has any associated health check annotations (typically added via `.WithHealthCheck(...)`).
2. **If health checks are configured:** Aspire begins executing these checks periodically. The resource is considered fully "ready" only after its health checks pass successfully. Once healthy, Aspire automatically publishes the `ResourceReadyEvent`.
3. **If no health checks are configured:** The resource is considered "ready" as soon as it enters the `Running` state. Aspire automatically publishes the `ResourceReadyEvent` immediately in this case.

This automatic handling ensures that dependent resources (using mechanisms like `WaitFor`) only proceed when the target resource is truly ready, either by simply running or by passing its defined health checks.

Expand All @@ -287,7 +287,7 @@

See the Talking Clock example for a full implementation of a custom resource with logging.

> **Note:** A full example demonstrating custom resource logging with the Talking Clock resource can be found in the [Full Examples](#example-custom-resource-talking-clock) section.
> **Note:** A full example demonstrating custom resource logging with the Talking Clock resource can be found in the [Full Examples](#example-custom-resource---talking-clock) section.

#### Key APIs

Expand Down Expand Up @@ -573,13 +573,13 @@

*Publish manifest excerpt*

```
```env
HEALTH_URL=https://{api.bindings.http.host}:{api.bindings.http.port}/health
```

*Run‑time value*

```
```env
HEALTH_URL=https://localhost:5000/health
```

Expand Down Expand Up @@ -679,7 +679,7 @@

Use the `IsAllocated` property on an `EndpointReference` to check if an endpoint has been allocated before accessing its runtime values.

---
---

### Accessing Allocated Endpoints Safely

Expand Down Expand Up @@ -727,19 +727,19 @@
#### Output

- **Run Mode**:
```
```text
IsAllocated: True
Resolved Url: http://localhost:6379
```
- **Publish Mode**:
```
```text
IsAllocated: False
Error accessing Url: Endpoint has not been allocated.
```

**NOTE: The overloads of [WithEnvironment](https://learn.microsoft.com/en-us/dotnet/api/aspire.hosting.resourcebuilderextensions.withenvironment) that take a callback run after endpoints have been allocated.**

---
---

## Referencing Endpoints from Other Resources

Expand Down Expand Up @@ -857,8 +857,7 @@

`EndpointReferenceExpression` implements the same `IManifestExpressionProvider` / `IValueProvider` pair, so it can be embedded in a `ReferenceExpression` or resolved directly with `GetValueAsync()`.


---
---

## Context-Based Endpoint Resolution

Expand All @@ -872,7 +871,7 @@
| **Executable/Project** | **Container** | Host network (`localhost:port`). | `localhost:6379` |
| **Container** | **Executable/Project** | Host network (`host.docker.internal:port`). | `host.docker.internal:5000` |

---
---

#### Advanced Scenario: Dynamic Endpoint Resolution Across Contexts

Expand All @@ -882,7 +881,7 @@

Below example shows a project that is going to setup up grafana and keycloak. We need to give the project the address for container-to-container communication between grafana and keycloak even though the target resource is a project. The project isn’t directly talking to keycloak or grafana, it's a mediator that is just setting URLs in the appropriate configuration of each container.


Check failure on line 884 in docs/specs/appmodel.md

View workflow job for this annotation

GitHub Actions / lint

Multiple consecutive blank lines [Expected: 1; Actual: 2]
### Example: Cross-Context Communication

#### Code Example
Expand Down Expand Up @@ -929,7 +928,7 @@

This guide describes each pattern and shows a **verbatim Redis example** at the end. It also covers how to publish manifests via custom resources.

---
---

## Adding Resources with `AddX(...)`

Expand Down Expand Up @@ -999,7 +998,7 @@
| **Register** | `builder.AddResource(resource)` | Add resource to the application model |
| **Optional wiring**| `.WithEndpoint…`, `.WithHealthCheck…`, `.WithImage…`, `.WithEnvironment…`, `.WithArgs…`, `Eventing.Subscribe…` | Configure container details, wiring, and runtime hooks |

---
---

## Configuring Resources with `WithX(...)`

Expand All @@ -1025,7 +1024,7 @@
| `WithX(...)` | `IResourceBuilder<TResource>` | Attaches `XAnnotation` via `WithAnnotation` |
| Returns | `IResourceBuilder<TResource>` | Enables fluent chaining |

---
---

## Annotations

Expand All @@ -1051,7 +1050,7 @@
| Attach | `builder.WithAnnotation(new XAnnotation(...))` | Adds metadata to resource builder |
| Query | `resource.TryGetLastAnnotation<XAnnotation>(out var a)` | Consumers inspect annotations as needed |

---
---

## Custom Value Objects

Expand Down Expand Up @@ -1105,7 +1104,7 @@
| `IValueWithReferences` _(opt.)_ | `References` | Declare resource dependencies |
| `WithEnvironment(...)` | `new("NAME", valueProvider)` | Attach structured values unflattened |

---
---

## Manifest Publishing & Resource Serialization

Expand Down Expand Up @@ -1157,7 +1156,7 @@
| Implement `WriteToManifest`| Use `context.Writer` to emit JSON properties | Define resource manifest representation |
| Structured fields | `IManifestExpressionProvider.ValueExpression`| Ensure publish-time placeholders are preserved |

---
---

## Key Conventions

Expand All @@ -1169,7 +1168,7 @@
| `[ResourceName]` attribute | Enforces valid resource naming at compile time |
| Preserve parameter/value objects | Ensures deferred evaluation of secrets/outputs |

---
---

## Full Examples

Expand Down Expand Up @@ -1506,7 +1505,7 @@
}
```

---
---

## Glossary

Expand Down
Loading