> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mastermindcms.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Beispiele

> Typische Muster (SSR + API + Web-Komponenten)

Diese Seite enthält Praxisbeispiele für Browser-Client, `msm-components`, WebSocket, REST, SSR und Web-Komponenten.

Nach dem Laden von `msm-framework-js` wird eine gemeinsame Client-Instanz erstellt:

```js theme={null}
const app = new MSM2.App("wss://example.com");
```

## Backend-Service aufrufen

```js theme={null}
import { callService } from "msm-components/dist/services.js";

const response = await callService(
  "searchManagerServiceImpl", "PROTOTYPE", "search",
  [{ query: { isPublishedForSale: true }, offset: 0, limit: 10 }]
);
const items = response.result?.data?.content ?? [];
```

Wenn die Backend-Methode einen JSON-String erwartet, übergib `JSON.stringify(request)`.

## Repository und Bean

```js theme={null}
import { callRepository, updateBean } from "msm-components/dist/services.js";

const response = await callRepository("blogCategoryRepository", {
  query: { _id: categoryId }, skip: 0, limit: 1,
});

// Aktualisiert Werte einer mit @Component oder @Service registrierten Bean.
await updateBean(
  "dummyBean", "PROTOTYPE",
  { description: "Updated description" }
);
```

## React mit WebSocket-Daten

```jsx theme={null}
import { useEffect, useState } from "react";

const app = new MSM2.App("wss://example.com");

export function ProductList() {
  const [items, setItems] = useState([]);
  useEffect(() => {
    const subscription = app.invokeAndGetJson$(
      "searchManagerServiceImpl", "PROTOTYPE", "search",
      [{ type: "SellerSKU", query: {}, offset: 0, limit: 10 }], null, "USER"
    ).subscribe((response) => setItems(response.result?.data?.content ?? []));
    return () => subscription.unsubscribe();
  }, []);
  return <ul>{items.map((item) => <li key={item.id}>{item.name}</li>)}</ul>;
}
```

## SSR und eigene Events

```js theme={null}
app.renderPage();
app.renderElement(
  [{ elementId: "cart-container", path: "/components/cart", payload: {} }],
  { userId }
);

const subscription = app.registerJsonWebSocket("jobs", (event) => {
  console.log("Job-Ereignis", event);
});
```

## Übersetzungen und Routing

```js theme={null}
import { setLocalesPath, translate, loadManyTranslations } from "msm-components/dist/services.js";
import { routeManager } from "msm-components/dist/services.js";

setLocalesPath("/assets/locales/{{lng}}.json");
document.title = await translate("DashboardTitle");
const texts = await loadManyTranslations("SaveButton", "CancelButton");

routeManager.init("My application");
routeManager.addRoute("/", "home", "HomeTitle");
routeManager.addRoute("/products/:id.html", "product", "ProductTitle");
routeManager.loadRouteByCurrentUrl();
routeManager.navigate("product", "42.html");
```

## Web-Komponenten

```html theme={null}
<msc-header></msc-header>
<msm-button type="OUTLINE" variant="emphasis" href="/catalog">
  Katalog öffnen
</msm-button>
<msm-login-form></msm-login-form>
```

## Authentifizierung

```js theme={null}
MSM2.App.AuthHelper.authenticate$(
  "/api/v1/authenticate", "username=user@example.com&password=secret"
).subscribe({
  next: (response) => console.log(response),
  error: (error) => console.error("Login fehlgeschlagen", error),
});

MSM2.App.AuthHelper.logout$("/api/v1/logout", "role=user")
  .subscribe(() => { window.location.href = "/user/login.html"; });
```

## REST und Datei-Upload

```js theme={null}
const response = await fetch("/api/v1/bean/request", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Site-Context": "my-site",
    "Lang-Context": "de",
  },
  body: JSON.stringify({
    beanId: "frameworkOperationServiceImpl",
    scope: "PROTOTYPE", functionName: "getLangCode", args: [],
  }),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);

const formData = new FormData();
formData.append("file", file);
formData.append("payload", JSON.stringify({ destination: `${sellerId}/images` }));
formData.append("command", "UPLOAD_IMAGE");
await fetch("/api/v1/uploadImage", { method: "POST", body: formData });
```

## Formular-Payload

```js theme={null}
import { getPayloadOfForm } from "msm-components/dist/services.js";

const payload = getPayloadOfForm(document.querySelector("form[data-profile]"));
console.log(payload);
```

## Cookies und sprachabhängige URLs

```js theme={null}
import { setCookie, getCookie, languageAwareUrl } from "msm-components/dist/services.js";

setCookie("promo", "spring", null, null, "/");
console.log(getCookie("i18next"));
console.log(await languageAwareUrl("/catalog"));
```

## Eigene Topic-Subscription

```js theme={null}
const subscription = app.registerJsonWebSocket("orders", (event) => {
  console.log("Bestellereignis", event);
});
subscription.unsubscribe();
```

## Teilweises HTML-Rendering

```js theme={null}
app.renderElement(
  [{ elementId: "profile", path: "/components/profile", payload: {} }],
  { userId }
);
```

## Wiederholung fehlgeschlagener Aufrufe

```js theme={null}
async function callWithRetry(task, attempts = 3) {
  let lastError;
  for (let attempt = 1; attempt <= attempts; attempt += 1) {
    try { return await task(); }
    catch (error) {
      lastError = error;
      await new Promise((resolve) => setTimeout(resolve, attempt * 500));
    }
  }
  throw lastError;
}

const response = await callWithRetry(() => callService(
  "frameworkOperationServiceImpl", "PROTOTYPE", "getLangCode", []
));
```

## JSON-Antwort prüfen

```js theme={null}
const response = await callService(
  "frameworkOperationServiceImpl", "PROTOTYPE", "getLangCode", []
);
if (response.result == null) throw new Error("Leeres Ergebnis");
```

## Minimale HTML-Seite

```html theme={null}
<script src="https://cdn.jsdelivr.net/npm/msm-framework-js@0.0.7/index.js"></script>
<main id="app"></main>
<script>
  const app = new MSM2.App("wss://example.com");
  app.renderPage();
</script>
```

## Gemeinsame Client-Instanz

```js theme={null}
// Nur eine Instanz pro Anwendung erzeugen.
export const MSM2App = window.app || (window.app = new MSM2.App());

MSM2App.renderPage();
```
