Beste praksis for projeksjoner i API-svar
Utform projeksjoner som samsvarer med responsstrukturen i REST-API-et, slik at nyttelastens størrelse reduseres og sensitive felt beskyttes.
Beste praksis for projeksjoner i API-svar er en gratis leksjon i MongoDB Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i MongoDB Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i MongoDB Academy inneholder totalt 4 leksjoner.
Tilpass projeksjoner til API-svarenes struktur
Hvert REST- eller GraphQL-endepunkt som applikasjonen Deres eksponerer, har en definert svarstruktur. Den ideelle MongoDB-projeksjonen returnerer nøyaktig feltene som denne strukturen krever – verken flere eller færre. Når projeksjonen gjenspeiler API-kontrakten for svaret, unngår De to vanlige anti-mønstre: overhenting (at De returnerer felt endepunktet aldri sender) og underhenting (at De returnerer felt som tvinger frem en ny spørring).
Definer projeksjonskonstanter
Hvis De skriver projeksjonsobjekter direkte inn i hver spørring, fører det over tid til duplisering og avvik. Definer projeksjonskonstanter sammen med dataaksessfunksjonene eller repositoryene. Hvis API-svarstrukturen endres, oppdaterer De én konstant i stedet for å lete gjennom hele kodebasen etter hver spørring.
// 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 });Returner aldri sensitive felt til klienter
Felt som passwordHash, totpSecret, apiKey, ssn og paymentMethodToken skal aldri vises i API-svar. Definer en sikker grunnprojeksjon som utelukker dem som standard, og hent dem bare i interne tjenestekall som spesifikt trenger dem. Følg prinsippet om minste privilegium i datalaget.
// 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 totpSecretListeendepunkter: Projiser bare sammendragsfelt
Listeendepunkter (for eksempel GET /products) returnerer vanligvis et sammendrag av hvert element, ikke hele dokumentet. En produktliste kan vise name, price, thumbnailUrl og rating – ikke hele description, arrayen specifications eller reviews. En begrenset projeksjon for listesøk kan redusere størrelsen på nyttelasten med 90 % når hele dokumenter inneholder store tekstmengder eller arrayer.
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();Detaljendepunkter: Projiser hele objektet
Detaljendepunkter (for eksempel GET /products/:slug) returnerer en mer omfattende visning av ett dokument. Også her bør De vurdere å utelate felt som bare brukes internt. De kan projisere alle offentlige felt, samtidig som De skjuler intern kostpris, kontaktopplysninger til leverandører eller ID-er fra interne kildesystemer for lagerbeholdning som klientene ikke skal se.
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 }
);Bruk også projeksjoner i aggregeringspipelines
Beste praksis for projeksjoner gjelder også for aggregeringspipelines. Plasser et $project-steg etter $match og før kostbare steg som $lookup eller $unwind, slik at størrelsen på dokumentene som går gjennom pipelinen, reduseres. Mindre dokumenter i pipelinen betyr lavere minne- og CPU-bruk på serveren.
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'
}
}
]);Projeksjoner og API-versjonering
Når De legger til nye felt i MongoDB-dokumenter, forventer eldre API-klienter kanskje ikke disse feltene. Med strenge inkluderingsprojeksjoner (der De lister opp nøyaktig feltene som skal returneres) blir nye dokumentfelt usynlige for eksisterende API-forbrukere helt til De uttrykkelig legger dem til i projeksjonen. Dette gir en naturlig versjoneringsgrense: Oppdater projeksjonen når De oppdaterer API-versjonen.
// 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 };Test at projeksjonene samsvarer med svarskjemaene
Skriv enhetstester som bekrefter at MongoDB-projeksjonsobjektet samsvarer med API-svarskjemaet (for eksempel et Joi-skjema eller en TypeScript-type). Dette forhindrer den vanlige feilen der en utvikler legger til et felt i API-svartypen, men glemmer å ta det med i projeksjonen – feltet kommer tilbake som undefined i produksjon, selv om det består TypeScript-typesjekkene.
// 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');Unngå avvik mellom projeksjon og skjema i Mongoose
Mongoose-skjemaer med select: false på et felt hindrer feltet i å vises i resultater fra spørringer, med mindre det tas med igjen uttrykkelig. Kombiner dette med virtuals på skjemanivå for å beregne avledede verdier uten å lagre dem. Sammen gjør disse verktøyene det mulig å håndheve en sikker standardprojeksjon på modellnivå og redusere risikoen for utilsiktet datalekkasje på grunn av en manglende spørringsprojeksjon.
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();
});Overvåk projeksjonseffektiviteten
Bruk explain('executionStats')
nReturned og keysExamined samt docsExamined. Hvis docsExamined er lik antallet samsvarende dokumenter (og ikke null), er projeksjonen ikke dekket av en indeks, men den er fortsatt korrekt – De kan vurdere om det er verdt vedlikeholdskostnaden å legge til en dekkende indeks.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);Oppsummering: Sjekkliste for beste praksis for projeksjoner
Bruk denne sjekklisten for hver MongoDB-spørring i API-et:
- Definer navngitte projeksjonskonstanter – én per endepunkt eller svarstruktur
- Bruk inkluderingsmodus for API-svar – list opp nøyaktig det De trenger
- Utelukk alltid sensitive felt – passwordHash, tokens og interne ID-er
- Bruk begrensede projeksjoner for listeendepunkter – bare sammendrag, ingen store innholdsfelt
- Plasser $project tidlig i aggregeringspipelines – reduser datamengden som sendes videre
Kort kontroll
Test forståelsen Deres av konseptene innen MongoDB & NoSQL Databases fra denne leksjonen.
Oppsummering av leksjonen
I denne leksjonen lærte De at projeksjonskonstanter bør defineres per API-endepunkt for å hindre avvik, at sensitive felt alltid må utelukkes fra klientrettede spørringer, og at tidlig plassering av $project i aggregeringspipelines reduserer minnebelastningen. Deretter skal vi utforske sortering og paginering for å ordne og dele opp store resultatsett på en effektiv måte.
Lær deg JavaScript med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 30
- Leksjoner
- 120
Ofte stilte spørsmål
Er leksjonen «Beste praksis for projeksjoner i API-svar» gratis?
Ja – hele teksten i «Beste praksis for projeksjoner i API-svar» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av MongoDB Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i MongoDB Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Beste praksis for projeksjoner i API-svar»?
Utform projeksjoner som samsvarer med responsstrukturen i REST-API-et, slik at nyttelastens størrelse reduseres og sensitive felt beskyttes. Du øver på MongoDB Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med MongoDB Academy?
Ingen tidligere erfaring er nødvendig. MongoDB Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.
Hvor lang tid tar leksjonen «Beste praksis for projeksjoner i API-svar»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne MongoDB Academy-leksjonen?
Ja. Alle MongoDB Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Projeksjoner med inkludering kontra ekskludering
- Projisere nestede felt og arrayfelt
- Arrayprojeksjonene $ og $elemMatch
- Beste praksis for projeksjoner i API-svar