Navnerumsopdelt konfiguration med registerAs
Gruppér relaterede indstillinger i typede konfigurationsnavnerum, og injicér dem med ConfigService.get
Navnerumsopdelt konfiguration med registerAs er en gratis NestJS-backend-API'er til virksomheder-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i NestJS-backend-API'er til virksomheder, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. NestJS-backend-API'er til virksomheder-kurset indeholder 4 lektioner i alt.
Problemet med flad konfiguration
Efterhånden som en API vokser, bliver det uoverskueligt at hælde alle indstillinger ind i ét stort ConfigService-navnerum. Du ender med kald som config.get('DB_HOST'), config.get('REDIS_PORT') og config.get('JWT_SECRET') spredt overalt uden gruppering eller typesikkerhed.
- Ingen struktur — nøgler til database, cache og godkendelse ligger alle på samme flade niveau.
- Ingen typer —
get()returnererunknowneller en løst typet værdi. - Svært at omstrukturere — hvis du omdøber en nøgle, skal du lede efter rå strenge i hele kodebasen.
NestJS løser dette med navnerumsopdelt konfiguration via hjælperen registerAs fra @nestjs/config.
Introduktion til registerAs
registerAs(token, factory) opretter en konfigurationsfabrik, der er knyttet til et navnerumstoken. Fabrikken læser fra process.env og returnerer et typebestemt objekt, der samler relaterede indstillinger.
Hvert navnerum bliver sin egen logiske enhed — database, jwt, redis — som du kan registrere, injicere og teste uafhængigt.
import { registerAs } from '@nestjs/config';
export default registerAs('database', () => ({
host: process.env.DB_HOST ?? 'localhost',
port: parseInt(process.env.DB_PORT ?? '5432', 10),
username: process.env.DB_USER ?? 'postgres',
password: process.env.DB_PASSWORD ?? '',
name: process.env.DB_NAME ?? 'app',
}));Registrering af navnerummet
Du indlæser fabrikker med navnerum via arrayet load i ConfigModule.forRoot. Hver post er en fabrik, der er oprettet med registerAs.
Markér modulet med isGlobal: true, så ConfigService er tilgængelig overalt uden at blive importeret igen.
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import databaseConfig from './config/database.config';
import jwtConfig from './config/jwt.config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [databaseConfig, jwtConfig],
}),
],
})
export class AppModule {}Læsning af et navnerum med get()
Når navnerummet er registreret, er hele navnerummet tilgængeligt under sit token. Kaldet configService.get('database') returnerer hele det grupperede objekt.
Du kan også hente en enkelt indlejret værdi med adgang via en sti med punktummer: configService.get('database.host').
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class DbConnector {
constructor(private readonly config: ConfigService) {}
connect() {
const host = this.config.get<string>('database.host');
const port = this.config.get<number>('database.port');
return `connecting to ${host}:${port}`;
}
}Typning af navnerummet
For at få reel typesikkerhed skal du udlede en type fra fabrikken ved hjælp af ConfigType. Det udleder den nøjagtige form, som din registerAs-fabrik returnerer — uden en manuel grænseflade, der skal holdes synkroniseret.
ConfigType<typeof databaseConfig>giver dig{ host: string; port: number; ... }.- Autofuldførelse og kontrol ved kompilering fungerer nu for hvert felt.
import { ConfigType } from '@nestjs/config';
import databaseConfig from './config/database.config';
// Inferred: { host: string; port: number; username: string; ... }
type DatabaseConfig = ConfigType<typeof databaseConfig>;
function describe(db: DatabaseConfig): string {
return `${db.username}@${db.host}:${db.port}/${db.name}`;
}Direkte injicering af navnerummet
Det mest bekvemme mønster er at injicere navnerumstokenet direkte i stedet for at gå gennem ConfigService.get overalt. Brug decoratoren @Inject(databaseConfig.KEY) — registerAs tilføjer en egenskab med navnet KEY til fabrikken netop til dette.
Feltet er nu fuldt typebestemt, og afhængigheden er tydelig i konstruktøren.
import { Inject, Injectable } from '@nestjs/common';
import { ConfigType } from '@nestjs/config';
import databaseConfig from './config/database.config';
@Injectable()
export class UserRepository {
constructor(
@Inject(databaseConfig.KEY)
private readonly db: ConfigType<typeof databaseConfig>,
) {}
dsn(): string {
return `postgres://${this.db.host}:${this.db.port}/${this.db.name}`;
}
}Hvorfor injicere tokenet i stedet for ConfigService
Begge tilgange fungerer, men det har klare fordele at injicere namespace-tokenet, når løsningen vokser:
- Typesikkert — det injicerede objekt er fuldt typet; ingen
get<T>-casts, der stille og roligt kan komme ud af synkronisering. - Eksplicitte afhængigheder — konstruktøren angiver præcis, hvilken konfiguration den har brug for.
- Mindre overflade — en klasse, der kun bruger databasekonfiguration, ser aldrig JWT- eller Redis-nøgler.
- Lettere test — angiv et almindeligt objekt for
databaseConfig.KEYi stedet for at simulereConfigService.
Flere namespaces side om side
Rigtige enterprise-apps har flere namespaces. Hvert namespace ligger i sin egen fil og factory og registreres samlet i load-arrayet. Når de holdes adskilt, risikerer en ændring i JWT aldrig at ødelægge databasekonfigurationen.
import { registerAs } from '@nestjs/config';
export const jwtConfig = registerAs('jwt', () => ({
secret: process.env.JWT_SECRET ?? 'dev-secret',
accessTtl: process.env.JWT_ACCESS_TTL ?? '15m',
refreshTtl: process.env.JWT_REFRESH_TTL ?? '7d',
}));
export const redisConfig = registerAs('redis', () => ({
host: process.env.REDIS_HOST ?? 'localhost',
port: parseInt(process.env.REDIS_PORT ?? '6379', 10),
ttl: parseInt(process.env.REDIS_TTL ?? '60', 10),
}));Typetvang sker i factoryen
Miljøvariabler er altid strenge. Namespace-factoryen er det rigtige sted at konvertere typer og angive standardværdier én gang, så forbrugerne altid modtager værdier med de korrekte typer.
Denne rene hjælpefunktion viser den logik til typekonvertering, som du ville placere i en registerAs-factory — den kan køre selvstændigt.
function buildDbConfig(env: Record<string, string | undefined>) {
return {
host: env.DB_HOST ?? 'localhost',
port: parseInt(env.DB_PORT ?? '5432', 10),
ssl: env.DB_SSL === 'true',
poolSize: parseInt(env.DB_POOL_SIZE ?? '10', 10),
};
}
const cfg = buildDbConfig({ DB_PORT: '6543', DB_SSL: 'true' });
console.log(cfg.port, typeof cfg.port); // 6543 'number'
console.log(cfg.ssl, typeof cfg.ssl); // true 'boolean'
console.log(cfg.host); // localhostBrug af et namespace i forRootAsync
Andre moduler kan bruge et namespace asynkront. Injicer namespace-tokenet via inject, og læs det typede objekt i useFactory — for eksempel når du konfigurerer TypeORM ud fra dit database-namespace.
import { ConfigType } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import databaseConfig from './config/database.config';
TypeOrmModule.forRootAsync({
inject: [databaseConfig.KEY],
useFactory: (db: ConfigType<typeof databaseConfig>) => ({
type: 'postgres',
host: db.host,
port: db.port,
username: db.username,
password: db.password,
database: db.name,
}),
});Almindelige faldgruber
Vær opmærksom på disse fejl, når du arbejder med namespaced konfiguration:
- At glemme at indlæse factoryen i
load: [...]— namespace-værdien bliverundefined. - At blande tokens og stier —
get('database')returnerer objektet;get('database.host')returnerer bladet. Forveksl dem ikke. - At konvertere typer igen hos forbrugerne — konverter typen én gang i factoryen; forbrugerne skal stole på typerne.
- At bruge
process.envdirekte i services i stedet for at injicere namespace'et, så du mister typeinformation og testbarhed.
Hurtigt tjek
Test din forståelse af namespaced konfigurationsinjektion.
Opsummering
Du har lært at gruppere indstillinger i typede konfigurationsnamespaces med registerAs:
- registerAs(token, factory) grupperer relaterede miljøvariabler i ét navngivet, typet objekt.
- Registrer factoryer via
ConfigModule.forRoot({ load: [...] }). - Læs et namespace med
config.get('database')eller et blad medconfig.get('database.host'). - Foretræk @Inject(config.KEY) sammen med
ConfigType<typeof config>for fuld typesikkerhed og eksplicitte afhængigheder. - Udfør al typekonvertering og angivelse af standardværdier i factoryen, så forbrugerne kan stole på typerne.
Dette mønster holder konfigurationen struktureret, typet og testbar, efterhånden som din enterprise-API vokser.
Lær TypeScript med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 20
- Lektioner
- 76
Ofte stillede spørgsmål
Er lektionen “Navnerumsopdelt konfiguration med registerAs” gratis?
Ja — hele teksten til “Navnerumsopdelt konfiguration med registerAs” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af NestJS-backend-API'er til virksomheder-kurset, skal du opgradere til CoddyKit PRO. NestJS-backend-API'er til virksomheder-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Navnerumsopdelt konfiguration med registerAs”?
Gruppér relaterede indstillinger i typede konfigurationsnavnerum, og injicér dem med ConfigService.get Du øver dig i NestJS-backend-API'er til virksomheder med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på NestJS-backend-API'er til virksomheder?
Der kræves ingen tidligere erfaring. NestJS-backend-API'er til virksomheder på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.
Hvor lang tid tager lektionen “Navnerumsopdelt konfiguration med registerAs”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne NestJS-backend-API'er til virksomheder-lektion?
Ja. Alle NestJS-backend-API'er til virksomheder-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Skemavaliderede miljøvariabler med Joi og forRoot
- Navnerumsopdelt konfiguration med registerAs
- Indlæsning af hemmeligheder fra HashiCorp Vault og AWS SSM
- Konfiguration pr. miljø og sikre standarder