> For AI agents: the complete documentation index is available at https://nhanbe.id.vn/llms.txt, the full documentation bundle is available at https://nhanbe.id.vn/llms-full.txt.

# AEM - Code Execute flow

## Problem statement

> Just because code runs on Author doesn't mean it will run correctly on Publish. Do you know the boundaries between these environments?
>
> **Note:** Sling/Java code still executes on Publish. A CDN like Cloudflare does not execute Sling code; it only caches and serves the responses generated by the Publisher.

## Code Execution Flow

- **Publish Environment**

```mermaid
graph LR
    Browser --> CF[CloudFlare / CDN] --> Dispatcher --> Publisher["AEM Publisher"] 
    --> Sling --> Servlet["Servlet, Sling Model, OSGi Service, JCR"] --> Response["HTML / JSON"]
```

- **Author Environment**

```mermaid
graph LR
    Browser --> AEM_Author[AEM Author] --> Sling --> Servlet_Model_Service_JCR["Servlet / Sling Model / OSGi Service / JCR"] --> Response["HTML / JSON"]
```

If a request hits the Publisher, Java code will execute. If a request is served directly from the Dispatcher or CDN cache, Java code will **not** execute.

***

## Separation of Concerns Across 4 Layers

### 1. Java / Sling Correctness

Code must run independently on Publish.
**Check:** Sling Models, Servlets, OSGi Services, Schedulers, Event Handlers, ResourceResolvers, and Service Users.

> Do not rely on conditions or paths that only exist on Author.

**Example:**

```java
resolver.getResource("/content/cq:tags/...");
```

or

```java
resolver.getResource("/conf/...");
```

These paths or nodes might not exist on Publish.

Just because Author has resources at:

```
/content/foo
/conf/foo
/content/cq:tags/foo
```

does not mean Publish has them.

***

### 2. Author vs. Publish Content

Author and Publish instances have separate JCR repositories.

**Example:**

Author initial state:

```
/content/mysite/en
    title = "Hello"
```

You update it to:

```
title = "Hello World"
```

Author reflects the change immediately, but Publish will still show `title = "Hello"` until the page is published/replicated.

***

### 3. Dispatcher Security & Filters

**Example:**

```java
@SlingServletPaths("/bin/product")
```

- **Author directly:** `http://localhost:4502/bin/product` works.
- **Publish directly:** `http://localhost:4503/bin/product` works.
- **Through Dispatcher:** `https://site.com/bin/product` returns `403` or `404`.

**Reason:** The Dispatcher filter blocks requests by default:

```ini
/filter {
    /0001 { /type "deny" /url "*" }
}
```

and `/bin/product` has not been explicitly allowed yet.

***

### 4. CDN & Caching

The caching chain is: **Cloudflare (CDN) -> Dispatcher -> Publisher**.
If content is cached at the CDN or Dispatcher level, requests won't hit the Publisher, so cache invalidation/flushing is required when updating dynamic logic or content.

***

## Tips & Best Practices

- **Add request-correlated logging during development:**

```java
log.debug(
    "ProductModel executing. path={}, selector={}, user={}",
    request.getResource().getPath(),
    request.getRequestPathInfo().getSelectorString(),
    request.getResourceResolver().getUserID()
);
```
