# Integration und HTTP

Integrationsfunktionen verbinden deine App mit Diensten und Kommunikationstools außerhalb von Ninox. Du kannst APIs aufrufen, XML gegen Schemas validieren, XML transformieren, E-Mails senden und Termine oder Erinnerungen erstellen, wenn deine Umgebung das unterstützt.

In diesem Kapitel lernst du, wie du:

* externe Dienste mit HTTP aufrufst.
* XML transformierst.
* Termine erstellst.

<table><thead><tr><th width="249.3359375">Funktion (A-Z)</th><th>Aufgabe</th></tr></thead><tbody><tr><td><code>appointment()</code></td><td>Erstellt einen Terminwert</td></tr><tr><td><code>email()</code></td><td>Gibt einen E-Mail-Wert zurück oder verwendet ihn wieder</td></tr><tr><td><code>formatXML()</code></td><td>Konvertiert JSON-Daten in XML-Text</td></tr><tr><td><code>http()</code></td><td>Sendet eine HTTP-Anfrage</td></tr><tr><td><code>parseXML()</code></td><td>Konvertiert XML-Text in ein JSON-Objekt</td></tr></tbody></table>

## Externe Dienste aufrufen

Nutze diese Funktionen, um jede REST API aufzurufen, Daten aus einem anderen Dienst zu holen oder Daten zwischen Ninox Datenbanken zu übertragen.

### Mit `http()` eine API aufrufen

Nutze `http()`, um eine Anfrage an einen externen Dienst zu senden.

Nutze es, wenn du:

* Daten aus einem anderen System holen oder Updates dorthin senden willst.
* Ninox mit REST APIs und anderen Ninox Datenbanken verbinden willst.

{% hint style="warning" %}
**Setze `http()` nicht in `do as transaction...end` ein**

Transaktionen nutzen eine single-threaded Schreibwarteschlange. Ein HTTP-Aufruf innerhalb einer Transaktion blockiert alle anderen Schreibvorgänge, bis die Anfrage abgeschlossen ist. Die App hängt nicht dauerhaft, aber jeder wartende Schreibvorgang wartet über die komplette Laufzeit des Aufrufs. Das kann die App langsam wirken lassen.
{% endhint %}

`http(method, url)`\
`http(method, url, body)`\
`http(method, url, header, body)`\
`http(method, url, header, body, files)`

* `method`: Textwert der HTTP-Methode, zum Beispiel `"GET"` oder `"POST"`
* `url`: Textwert der Endpoint-URL
* `header`: optionale Header als JSON-Objekt, zum Beispiel `{ Authorization: token }`
* `body`: optionaler Request-Body als JSON-Objekt
* `files`: optionale Dateien zum Upload als `[file]`, wenn der aktuelle Ausführungskontext Datei-Uploads unterstützt (Server-Kontext)

{% hint style="warning" %}
**Beim Zugriff auf Ninox Daten ist ein Body erforderlich**

Wenn du `http()` nutzt, um auf Daten in Ninox zuzugreifen, musst du einen Body übergeben. Wenn keine Informationen im Body nötig sind, bleibt er einfach leer. Ein Beispiel dafür ist:

`http(“GET”, “https://api.ninox.com/v1/[...]”, {Authorization: “Bearer xxxx-xxxx-xxxx”, content-type: “application/json”}, {})`
{% endhint %}

#### Schauen wir uns einige Beispiele an:

```ninox
http("GET", "https://api.example.com/status")
```

Ruft den externen Dienst auf und gibt ein JSON-Antwortobjekt oder ein Fehlerobjekt zurück.

```ninox
let url := "https://api.ninoxdb.de/v1/teams/" + teamId() +
           "/databases/" + databaseId() + "/tables/";
let apiKey := "Bearer abcd1234-0000-xxxx-zzzz-1a1aa1aaa1a111";

let response := http("GET", url, {
    Authorization: apiKey
});
response
```

Listet Tabellen aus der aktuellen Datenbank über die Ninox API oder gibt ein Fehlerobjekt zurück.

```ninox
do as server
   let url := "https://api.ninoxdb.de/v1/teams/" + teamId() +
             "/databases/" + databaseId() + "/query";
   let apiKey := "Bearer abcd1234-0000-xxxx-zzzz-1a1aa1aaa1a111";
   
   let response := http("POST", url, {
             Authorization: apiKey, 
             "content-type": "application/json"
   }, {
    query: "select customers where status = 4"
   });
   response
end
```

Sendet eine POST-Anfrage und gibt passende Datensätze oder ein Fehlerobjekt zurück.

<pre class="language-ninox"><code class="lang-ninox"><strong>let response ::= do as server
</strong>    http("POST",
        "https://example.com/upload",
        { "content-type": "multipart/form-data" },
        null,
        [myFile])
end
</code></pre>

Lädt eine Datei zu einem externen Dienst hoch, wenn Datei-Uploads im aktuellen Ausführungskontext unterstützt werden.

Tipps:

* `http()` gibt ein JSON-Objekt zurück, keinen Klartext.
* Wenn du auf eine andere Ninox Datenbank zugreifst, brauchst du einen API-Key.
* Manche Endpoints erwarten selbst bei `GET`-Anfragen einen Body. Nutze `{}`, wenn der Ziel-Endpoint einen Body verlangt und du keine Felder senden musst.
* Datei-Uploads hängen vom Ausführungskontext ab.
* Teste Integrationsskripte mit echten Antworten des Dienstes, nicht nur mit Beispielausgaben.

## XML transformieren

Nutze diese Funktionen, wenn ein anderes System XML sendet oder erwartet, besonders wenn das XML zu einem definierten Schema passen muss.

### Mit `parseXML()` XML-Text in Daten umwandeln

Nutze `parseXML()`, um XML-Text in ein JSON-Objekt umzuwandeln, das du in Ninox prüfen kannst. Das ist besonders nützlich, wenn du Ninox per API mit externen Diensten verbindest und XML-Antworten verarbeiten musst. XML ist neben JSON ein gängiges Austauschformat.

Nutze es, wenn du:

* Werte aus einer XML-Antwort lesen willst.
* Felder aus importiertem XML extrahieren willst.
* XML für spätere Logik in strukturierte Daten umwandeln willst.

`parseXML(string)`

* `string`: der XML-Text, den du in ein JSON-Objekt umwandeln willst

#### Schauen wir uns einige Beispiele an:

```ninox
let xml := "<?xml version=""1.0"" encoding=""UTF-8""?>
<note>
    <to>Jane Doe</to>
    <from>Ninox</from>
    <heading>Save the world!</heading>
    <body>Please save the world!</body>
</note>";
parseXML(xml)
```

Gibt ein JSON-Objekt zurück, das aus dem XML-Text erzeugt wurde, zum Beispiel:

```json
{
  "note": {
    "to": {
      "@": "Jane Doe"
    },
    "from": {
      "@": "Ninox"
    },
    "heading": {
      "@": "Save the world!"
    },
    "body": {
      "@": "Please save the world!"
    }
  }
}
```

Tipp:

* Wenn du ein XSD-Schema hast, validiere externes XML vor dem Parsen.

### Mit `formatXML()` XML-Text erstellen

Nutze `formatXML()`, um JSON-Daten in XML-Text umzuwandeln.

Nutze es, wenn du:

* XML für einen anderen Dienst vorbereiten willst.
* geparste Daten in lesbares XML umformatieren willst.

`formatXML(JSON)`\
`formatXML(JSON, boolean)`

* `JSON`: die strukturierten Daten, die du in XML umwandeln willst
* `boolean`: ob die Ausgabe zur besseren Lesbarkeit optisch strukturiert sein soll

#### Schauen wir uns einige Beispiele an:

```ninox
let x := parseXML("<root><item>1</item></root>");
formatXML(x, true)
```

Formatiert das geparste Objekt zurück in gut lesbaren XML-Text.

```ninox
formatXML({
    contact: {
        @type: "Person",
        firstName: {
            @: "Max"
        },
        lastName: {
            @: "Mustermann"
        },
        phone: [{
            @type: "Mobile",
            @: "(+1) (202) 123 45 67"
        }, {
            @type: "Phone",
            @: "+1.151.11 ++66 14 66"
        }]
    }
}, true)
```

Konvertiert das JSON-Objekt in strukturierten XML-Text. Schlüssel wie `@type` werden zu XML-Attributen. `@` wird zum Textwert des Knotens.

Tipps:

* Nutze die Pretty-Option, wenn Menschen das Ergebnis lesen sollen.
* Nutze kompakte Ausgabe, wenn das Zielsystem nur die Nutzlast braucht.
* Diese Funktion ist besonders nützlich für API-Integrationen, die XML statt JSON erwarten.

## Termine erstellen

Nutze diese Funktionen, wenn du für deinen Workflow ein zeitbasiertes Element erstellen willst.

### Mit `appointment()` einen Terminwert erstellen

Nutze `appointment()`, um zeitbezogene Werte in einen Terminwert umzuwandeln.

Nutze es, wenn du:

* einen Termin oder Zeitslot aus Start- und Endwerten aufsetzen willst.
* einen Zeitraum aus einem Startwert und einer Dauer erstellen willst.
* einen geplanten Zeitraum an spätere Logik übergeben willst.

`appointment(any, any)`

* erstes `any`: der Start-Zeitstempel
* zweites `any`: der End-Zeitstempel des Termins oder eine Dauer

#### Schauen wir uns einige Beispiele an:

```ninox
appointment(datetime(2021, 3, 16, 19), datetime(2021, 3, 6, 17))
```

Erstellt einen Termin aus zwei Zeitstempeln. Ninox nutzt automatisch den früheren Zeitstempel als Start.

```ninox
appointment(datetime(2021, 5, 22, 10), time(1, 45))
```

Erstellt einen Termin aus einem Start-Datum mit Uhrzeit und einer Dauer von 1 Stunde und 45 Minuten.

Tipps:

* Die Reihenfolge der Argumente ist egal, wenn du zwei Zeitstempel übergibst. Ninox nutzt den früheren Wert als Start.
* Wenn Start und Ende am selben Tag liegen, zeigt die Anzeige meist nur ein Datum. Wenn der Zeitraum mehrere Tage umfasst, werden beide Daten gezeigt.

{% hint style="info" %}
Das Verhalten von Integrationen kann von deiner Umgebung, dem Client und verbundenen Diensten abhängen. Prüfe HTTP- und E-Mail-Workflows in derselben Umgebung, die deine Nutzer in Produktion verwenden.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ninox.com/ninox-scripting/de/automate-your-workflows/work-with-functions/integration-and-http.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
