MongoDB Academy · Les

Best practices voor projecties in API-responses

U ontwerpt projecties die aansluiten op de responsevormen van REST API's, de payload verkleinen en gevoelige velden beschermen.

Les 4 van 413 stappen

Best practices voor projecties in API-responses is een gratis MongoDB Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject MongoDB Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus MongoDB Academy bevat in totaal 4 lessen.

Projecties afstemmen op API-antwoordstructuren

Elk REST- of GraphQL-eindpunt dat je applicatie aanbiedt, heeft een vastgelegde antwoordstructuur. De ideale MongoDB-projectie retourneert precies de velden die deze structuur vereist—niet meer en niet minder. Wanneer je projectie overeenkomt met het contract van je API-antwoord, voorkom je twee veelvoorkomende antipatterns: te veel gegevens ophalen (velden retourneren die het eindpunt nooit verstuurt) en te weinig gegevens ophalen (velden retourneren waarvoor een tweede query nodig is).

Projectieconstanten definiëren

Als je projectieobjecten inline in elke query hardcodeert, leidt dat na verloop van tijd tot duplicatie en afwijkingen. Definieer projectieconstanten naast je functies of repositories voor gegevenstoegang. Als de structuur van het API-antwoord verandert, hoef je één constante aan te passen in plaats van elke query in de codebase op te zoeken.

// projections.js — centralised projection definitions
export const USER_PUBLIC = { _id: 0, username: 1, avatarUrl: 1, createdAt: 1 };
export const USER_PROFILE = { _id: 0, username: 1, email: 1, bio: 1, avatarUrl: 1 };
export const USER_ADMIN = { _id: 0, username: 1, email: 1, role: 1, lastLoginAt: 1, isActive: 1 };

// Usage
const user = await db.collection('users').findOne({ username: 'alice' }, { projection: USER_PROFILE });

Gevoelige velden nooit naar clients retourneren

Velden zoals passwordHash, totpSecret, apiKey, ssn en paymentMethodToken mogen nooit in API-antwoorden voorkomen. Definieer een veilige basisprojectie die deze velden standaard uitsluit en haal ze alleen op in interne serviceaanroepen die ze specifiek nodig hebben. Pas het principe van minimale toegangsrechten toe op de gegevenslaag.

// Always exclude sensitive fields from user queries
const SECURE_USER_BASE = {
  passwordHash: 0,
  totpSecret: 0,
  resetToken: 0
};

// All user API responses go through this projection
const user = await db.collection('users').findOne(
  { _id: userId },
  { projection: SECURE_USER_BASE }
);

// Result never contains passwordHash or totpSecret

Lijst-eindpunten: alleen samenvattingsvelden projecteren

Lijst-eindpunten (bijvoorbeeld GET /products) retourneren meestal een samenvatting van elk item, niet het volledige document. Een productlijst kan name, price, thumbnailUrl en rating tonen—maar niet de volledige description, de array specifications of reviews. Een beperkte projectie voor lijstquery's kan de omvang van de payload met 90% verminderen wanneer volledige documenten grote teksten of arrays bevatten.

const PRODUCT_SUMMARY = {
  _id: 0,
  slug: 1,
  name: 1,
  price: 1,
  thumbnailUrl: 1,
  rating: 1,
  reviewCount: 1
};

// GET /products — lightweight list query
const products = await db.collection('products')
  .find({ category: 'electronics', isActive: true })
  .projection(PRODUCT_SUMMARY)
  .sort({ rating: -1 })
  .limit(20)
  .toArray();

Detail-eindpunten: het volledige object projecteren

Detail-eindpunten (bijvoorbeeld GET /products/:slug) retourneren een uitgebreidere weergave van één document. Overweeg ook hier om alleen interne velden uit te sluiten. Je kunt alle openbare velden projecteren en tegelijk de interne kostprijs, contactgegevens van leveranciers of ID's van interne voorraadsystemen onderdrukken die clients niet mogen zien.

const PRODUCT_DETAIL = {
  supplierCost: 0,       // internal — never expose to clients
  warehouseLocation: 0,  // internal
  syncedFromErpAt: 0     // internal audit field
};

// GET /products/:slug — rich detail query
const product = await db.collection('products').findOne(
  { slug: req.params.slug, isActive: true },
  { projection: PRODUCT_DETAIL }
);

Projecties ook in aggregatiepijplijnen gebruiken

Best practices voor projecties gelden ook voor de aggregatiepijplijn. Plaats een $project-fase na $match en vóór dure fasen zoals $lookup of $unwind om de documentgrootte die door de pijplijn stroomt te beperken. Kleinere documenten in de pijplijn betekenen minder geheugen- en CPU-gebruik op de server.

db.orders.aggregate([
  { $match: { status: 'shipped', customerId: ObjectId('c1') } },
  // Project early to reduce document size before $lookup
  { $project: { total: 1, createdAt: 1, customerId: 1, _id: 0 } },
  {
    $lookup: {
      from: 'customers',
      localField: 'customerId',
      foreignField: '_id',
      as: 'customer'
    }
  }
]);

Projecties en API-versiebeheer

Wanneer je nieuwe velden aan MongoDB-documenten toevoegt, verwachten oude API-clients deze mogelijk niet. Met strikte projecties voor opname (waarbij je precies de te retourneren velden opsomt) blijven nieuwe documentvelden onzichtbaar voor bestaande API-gebruikers totdat je ze expliciet aan de projectie toevoegt. Zo ontstaat een natuurlijke grens voor versiebeheer: werk de projectie bij wanneer je de API-versie bijwerkt.

// v1 projection — stable contract for existing clients
export const USER_V1 = { _id: 0, username: 1, email: 1 };

// v2 projection — includes new avatarUrl and bio fields
export const USER_V2 = { _id: 0, username: 1, email: 1, avatarUrl: 1, bio: 1 };

Testen of projecties overeenkomen met antwoordschema's

Schrijf unittests die controleren of het MongoDB-projectieobject overeenkomt met je API-antwoordschema (bijvoorbeeld een Joi-schema of een TypeScript-type). Zo voorkom je de veelvoorkomende fout waarbij een ontwikkelaar een veld aan het API-antwoordtype toevoegt, maar vergeet dit in de projectie op te nemen—het veld komt in productie terug als undefined, terwijl de TypeScript-typecontroles slagen.

// Example test asserting projection covers all required response fields
const USER_RESPONSE_FIELDS = ['username', 'email', 'avatarUrl'];
const projection = { username: 1, email: 1, avatarUrl: 1, _id: 0 };

for (const field of USER_RESPONSE_FIELDS) {
  if (projection[field] !== 1) {
    throw new Error('Projection missing field: ' + field);
  }
}
console.log('Projection covers all required response fields');

Niet-overeenkomende projecties in Mongoose voorkomen

Mongoose-schema's met select: false voor een veld voorkomen dat dit veld in queryresultaten verschijnt, tenzij het expliciet opnieuw wordt opgenomen. Combineer dit met virtuele velden op schemaniveau om afgeleide waarden te berekenen zonder ze op te slaan. Met deze hulpmiddelen kun je op modelniveau een veilige standaardprojectie afdwingen, waardoor de kans kleiner wordt dat gegevens per ongeluk uitlekken door een ontbrekende queryprojectie.

const userSchema = new mongoose.Schema({
  username: String,
  email:    String,
  // Excluded from all queries by default — must explicitly use +passwordHash
  passwordHash: { type: String, select: false },

  // Virtual — computed, not stored, never in DB
  get displayName() { return this.username.toUpperCase(); }
});
userSchema.virtual('displayName').get(function() {
  return this.username.toUpperCase();
});

Efficiëntie van projecties controleren

Gebruik explain('executionStats')

om te controleren of je projecties werken zoals bedoeld. Bekijk de verhouding tussen nReturned en keysExamined en docsExamined. Als docsExamined gelijk is aan het aantal overeenkomende documenten (en niet nul), wordt je projectie niet volledig door een index gedekt, maar werkt deze nog steeds correct—je kunt afwegen of een index die de query volledig dekt de onderhoudskosten waard is.

const result = await db.collection('users').find(
  { role: 'admin' },
  { projection: { username: 1, email: 1, _id: 0 } }
).explain('executionStats');

console.log('Docs examined:', result.executionStats.totalDocsExamined);
console.log('Keys examined:', result.executionStats.totalKeysExamined);
console.log('Docs returned:', result.executionStats.nReturned);

Samenvatting: checklist voor best practices bij projecties

Pas deze checklist toe op elke MongoDB-query in je API:

  • Definieer benoemde projectieconstanten — één per eindpunt of antwoordstructuur
  • Gebruik de modus voor opname voor API-antwoorden — vermeld precies wat je nodig hebt
  • Sluit gevoelige velden altijd uit — passwordHash, tokens, interne ID's
  • Gebruik beperkte projecties voor lijst-eindpunten — alleen een samenvatting, geen grote inhoud
  • Plaats $project vroeg in aggregatiepijplijnen — beperk de gegevensstroom naar volgende fasen

Korte controle

Test je begrip van de concepten uit deze les over MongoDB & NoSQL Databases.

Samenvatting van de les

In deze les heb je geleerd dat projectieconstanten per API-eindpunt moeten worden gedefinieerd om afwijkingen te voorkomen, dat gevoelige velden altijd moeten worden uitgesloten van clientgerichte query's en dat het vroeg plaatsen van $project in aggregatiepijplijnen de geheugendruk vermindert. Hierna bekijken we sorteren en pagineren om grote resultaatverzamelingen efficiënt te ordenen en in pagina's op te delen.

Gratis beginnen

Leer JavaScript met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
30
Lessen
120

Veelgestelde vragen

Is de les “Best practices voor projecties in API-responses” gratis?

Ja — de volledige tekst van “Best practices voor projecties in API-responses” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus MongoDB Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus MongoDB Academy bevat in totaal 4 lessen.

Wat leer ik in “Best practices voor projecties in API-responses”?

U ontwerpt projecties die aansluiten op de responsevormen van REST API's, de payload verkleinen en gevoelige velden beschermen. Je oefent met MongoDB Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met MongoDB Academy te beginnen?

Ervaring vooraf is niet nodig. MongoDB Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Best practices voor projecties in API-responses”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over MongoDB Academy?

Ja. Elke les over MongoDB Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Inclusie- versus exclusieprojecties
  2. Geneste velden en arrayvelden projecteren
  3. De arrayprojecties $ en $elemMatch
  4. Best practices voor projecties in API-responses
← Terug naar MongoDB Academy