# Google APIs gebruiken in Node.js [[TOC]] Node.js is een populaire keuze voor Workspace-integraties, vooral voor webapps en serverless functies. De officiele googleapis-bibliotheek van Google dekt vrijwel elke API met een consistent patroon. Heb je eenmaal een dienst onder de knie, dan voelen de andere meteen vertrouwd aan. In dit artikel installeer je de bibliotheek, regel je authenticatie en doe je je eerste calls. ## Installatie De bibliotheek staat op npm onder de naam googleapis. Installeer hem met een vaste versie en commit je lockfile, zodat je builds reproduceerbaar blijven. ```bash npm install googleapis ``` :::info title="Auto-gegenereerd en compleet" De googleapis-bibliotheek wordt onderhouden door Google en is automatisch gegenereerd uit de API-discovery-documenten. Daardoor zijn nieuwe endpoints meestal snel beschikbaar en zijn de methodenamen voorspelbaar. Het pakket bundelt alle Workspace-API's in een keer. ::: ## Authenticeren met een service account Voor server-side processen zonder gebruiker aan de knoppen gebruik je doorgaans `GoogleAuth`. Die pikt automatisch credentials op uit de omgeving of uit een sleutelbestand. ```javascript const { google } = require('googleapis'); const auth = new google.auth.GoogleAuth({ keyFile: '/secrets/sa-key.json', scopes: ['https://www.googleapis.com/auth/drive.readonly'] }); const drive = google.drive({ version: 'v3', auth }); ``` Draait je code binnen Google Cloud (bijvoorbeeld Cloud Run of een Cloud Function), dan kun je het `keyFile` weglaten. De bibliotheek gebruikt dan de ingebouwde identiteit van de omgeving, zodat je geen sleutelbestand hoeft te beheren. :::tip title="Liever geen sleutelbestand op schijf" Een service-account-sleutel op schijf is een gevoelig geheim. Gebruik waar mogelijk Workload Identity in Google Cloud, of laad de sleutel uit een secret-manager in plaats van uit een bestand in je repository. Zet een sleutelbestand nooit in versiebeheer. ::: ## Authenticeren met OAuth2 Voor toegang tot data van een specifieke gebruiker gebruik je een OAuth2-client met de tokens van die gebruiker. ```javascript const oauth2Client = new google.auth.OAuth2(clientId, clientSecret, redirectUri); oauth2Client.setCredentials({ refresh_token: opgeslagenRefreshToken }); const gmail = google.gmail({ version: 'v1', auth: oauth2Client }); ``` De client ververst access tokens automatisch zolang de refresh token geldig blijft. Bewaar refresh tokens versleuteld en behandel ze als wachtwoorden. ## Je eerste calls Elke methode retourneert een promise. De data zit in de `data`-eigenschap van het antwoord. :::howto title="Een API-call uitvoeren" 1. Maak de juiste service-client aan met `version` en `auth`. 2. Roep de gewenste methode aan met een parameter-object. 3. `await` het resultaat en lees `response.data` uit. 4. Vang fouten op met `try/catch` en inspecteer de statuscode. ::: ```javascript async function lijstBestanden() { const res = await drive.files.list({ pageSize: 10, fields: 'files(id, name)' }); return res.data.files; } ``` ## Paginering afhandelen Veel lijst-endpoints geven een `nextPageToken` terug. Loop door totdat die ontbreekt. ```javascript async function alleBestanden() { let bestanden = []; let pageToken = null; do { const res = await drive.files.list({ pageSize: 100, pageToken, fields: 'nextPageToken, files(id, name)' }); bestanden = bestanden.concat(res.data.files); pageToken = res.data.nextPageToken; } while (pageToken); return bestanden; } ``` :::tip title="Vraag alleen de velden op die je nodig hebt" Gebruik de `fields`-parameter om je response te beperken tot wat je echt gebruikt. Dat versnelt je calls aanzienlijk en verlaagt je quota-verbruik, omdat je minder data ophaalt en verwerkt. ::: ## Fouten en quota :::warn title="Bouw exponential backoff in" Bij hoge volumes loop je tegen rate limits aan, herkenbaar aan statuscode 429 of 403 met reden `rateLimitExceeded`. Bouw exponential backoff in met willekeurige jitter, zodat je niet alle requests tegelijk opnieuw probeert en de limiet juist langer raakt. ::: Een mislukte call gooit een error met onder meer `code`, `message` en vaak een `errors`-array met details. Log die velden bij debuggen, zodat je precies ziet welke request faalde en waarom. ## Veelgestelde vragen :::faq ### Werkt googleapis ook met TypeScript? Ja, de bibliotheek bevat volledige typedefinities. Je krijgt autocompletion op alle methoden en parameters, zonder dat je losse types hoeft te installeren. ### Hoe stel ik impersonation in voor een service account? Voor domain-wide delegation handel je namens een gebruiker. Geef bij `GoogleAuth` via `clientOptions` een `subject` mee met het e-mailadres van de gebruiker, of gebruik de JWT-client met het `subject`-veld. Het service account moet hiervoor in de Admin-console de juiste scopes gedelegeerd hebben gekregen. ### Moet ik elke API apart installeren? Nee, het googleapis-pakket bevat alle API's in een bundel. Wil je een kleinere bundel, dan kun je losse pakketten per API gebruiken, zoals `@googleapis/drive` of `@googleapis/gmail`. ### Hoe debug ik een mislukte call? Inspecteer de error: die bevat `code`, `message` en vaak een `errors`-array met details. Zet logging aan om de exacte request en de gebruikte scopes te zien, zodat je een 403 wegens ontbrekende rechten snel onderscheidt van een echte fout. ### Hoe kies ik tussen OAuth2 en een service account? Gebruik een service account voor server-side werk zonder eindgebruiker, bijvoorbeeld een achtergrondtaak die jouw eigen data verwerkt. Gebruik OAuth2 wanneer je namens een specifieke gebruiker diens Gmail, Drive of Agenda benadert en die gebruiker toestemming moet geven. ::: Met deze basis kun je in Node.js vrijwel elke Workspace-API aanspreken volgens hetzelfde betrouwbare patroon.