# Externe Dienste mit API() und den Treibern von NEWAPI() aufrufen

> Registriere mit NEWAPI() einen Treiber für einen Dienst und rufe ihn aus Aktionen mit API(name, schema, data) auf, im gleichen Stil von Callback, Fehler und Promise wie der Query Builder.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: de
Content-SHA256: 093f6cc524658d63972b0ad8e601aa366eae5cd6d0dc9033adba9121a9ea7b37
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

`API(name, schema, data, [$])` ruft eine Operation eines externen Dienstes auf, und `NEWAPI()` registriert den **Treiber**, der den Aufruf ausführt, sodass der Code deiner Aktionen nicht davon abhängt, wie der Dienst erreicht wird (HTTP, eine Bibliothek, eine Warteschlange...).

- `NEWAPI('name', driver)` registriert den Treiber des Dienstes `name` (`'a,b'` registriert einen Treiber für zwei Namen und `NEWAPI(driver)` den `default`). `NEWAPI('name', config, driver)` speichert zusätzlich ein `config`-Objekt, das jeder Aufruf als `options.config` erhält.
- Der Treiber ist `function(options, next)`. `options.name` ist der Dienst, `options.schema` die Operation, `options.data` die Daten und `options.config` die Konfiguration. Antworte mit `next(error, response)`.
- `API('name', 'operation', data)` gibt einen Builder zurück: Schließe ihn mit `.callback($)` (die Antwort geht an die Aktion `$`), `.callback(function(err, response) {})` oder `await ....promise($)` ab. `.configure({ key: value })` ergänzt `options.config` für diesen Aufruf, und `.error('text')` lässt eine leere Antwort mit dieser Meldung fehlschlagen.
- Ist für den Namen kein Treiber registriert, schlägt der Aufruf mit `API is not initialized` fehl.

```js definitions/api.js
// The driver of a fake weather service: in a real one this would be an HTTP request
NEWAPI('weather', { unit: 'C' }, function(options, next) {
	if (options.schema === 'forecast')
		next(null, { city: options.data.city, temperature: 21, unit: options.config.unit, service: options.name });
	else
		next('Unknown operation ' + options.schema);
});
```

```js controllers/weather.js
exports.install = function() {
	ROUTE('GET /forecast/', forecast);
	ROUTE('GET /forecast-fahrenheit/', fahrenheit);
	ROUTE('GET /unknown/', unknown);
	ROUTE('GET /missing/', missing);
	ROUTE('GET /promise/', promise);
};

function forecast($) {
	API('weather', 'forecast', { city: $.query.city }).callback($);
}

function fahrenheit($) {
	API('weather', 'forecast', { city: $.query.city }).configure({ unit: 'F' }).callback($);
}

function unknown($) {
	API('weather', 'rain', {}).callback($);
}

function missing($) {
	API('nobody', 'forecast', {}).callback($);
}

async function promise($) {
	const data = await API('weather', 'forecast', { city: 'Oslo' }).promise($);
	$.json({ city: data.city, same: true });
}

```
