# Roep externe diensten aan met API() en de drivers van NEWAPI()

> Registreer een driver voor een dienst met NEWAPI() en roep hem aan vanuit acties met API(name, schema, data), in dezelfde stijl van callback, fout en promise als de query builder.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: nl
Content-SHA256: 63caec8c933b59ce361e15aa010753bf0117318c22b29d2781661913cb15aa53
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

`API(name, schema, data, [$])` roept een bewerking van een externe dienst aan en `NEWAPI()` registreert de **driver** die de aanroep uitvoert, zodat de code van je acties niet afhangt van hoe de dienst wordt bereikt (HTTP, een bibliotheek, een wachtrij...).

- `NEWAPI('name', driver)` registreert de driver van de dienst `name` (`'a,b'` registreert één driver voor twee namen en `NEWAPI(driver)` registreert de `default`). `NEWAPI('name', config, driver)` bewaart ook een `config`-object dat elke aanroep ontvangt als `options.config`.
- De driver is `function(options, next)`. `options.name` is de dienst, `options.schema` de bewerking, `options.data` de gegevens en `options.config` de configuratie. Antwoord met `next(error, response)`.
- `API('name', 'operation', data)` geeft een builder terug: sluit hem af met `.callback($)` (het antwoord gaat naar de actie `$`), `.callback(function(err, response) {})` of `await ....promise($)`. `.configure({ key: value })` voegt toe aan `options.config` voor die aanroep en `.error('text')` laat een leeg antwoord mislukken met die melding.
- Als er voor de naam geen driver is geregistreerd, mislukt de aanroep met `API is not initialized`.

```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 });
}

```
