project setup with core files including configuration, package management, and basic structure. Added .gitignore, README, and various TypeScript types for CMS components. Implemented initial components and layouts for the application.
This commit is contained in:
89
middlelayer/utils/dataloaders.ts
Normal file
89
middlelayer/utils/dataloaders.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import DataLoader from "dataloader";
|
||||
import type { Product, Page } from "../types/index.js";
|
||||
import type { User } from "../types/user.js";
|
||||
import { dataService } from "../dataService.js";
|
||||
import { userService } from "../auth/userService.js";
|
||||
|
||||
/**
|
||||
* Dataloader für Batch-Loading von Produkten
|
||||
* Verhindert N+1 Queries, wenn mehrere Produkte in einer Query abgefragt werden
|
||||
*/
|
||||
export const createProductLoader = () => {
|
||||
return new DataLoader<string, Product | null>(
|
||||
async (ids: readonly string[]) => {
|
||||
// Batch-Loading: Lade alle Produkte in einem Batch
|
||||
const products = await Promise.all(
|
||||
ids.map((id) => dataService.getProduct(id))
|
||||
);
|
||||
|
||||
// Stelle sicher, dass die Reihenfolge mit den IDs übereinstimmt
|
||||
return products;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dataloader für Batch-Loading von Seiten
|
||||
* Unterstützt Locale im Key-Format: "slug:locale" oder "slug"
|
||||
*/
|
||||
export const createPageLoader = () => {
|
||||
return new DataLoader<string, Page | null>(
|
||||
async (keys: readonly string[]) => {
|
||||
const pages = await Promise.all(
|
||||
keys.map((key) => {
|
||||
// Parse Key: Format kann "slug:locale" oder "slug" sein
|
||||
const parts = key.split(":");
|
||||
const slug = parts[0];
|
||||
const locale = parts.length > 1 ? parts[1] : undefined;
|
||||
return dataService.getPage(slug, locale);
|
||||
})
|
||||
);
|
||||
return pages;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dataloader für Batch-Loading von Usern
|
||||
*/
|
||||
export const createUserLoader = () => {
|
||||
return new DataLoader<string, User | null>(
|
||||
async (userIds: readonly string[]) => {
|
||||
const users = await Promise.all(
|
||||
userIds.map((id) => userService.getUserById(id))
|
||||
);
|
||||
return users;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Context für GraphQL Resolver
|
||||
* Enthält Dataloader-Instanzen und User-Informationen
|
||||
*
|
||||
* Der Context wird für jeden GraphQL Request erstellt und enthält:
|
||||
* - `user`: Aktueller authentifizierter User (oder null)
|
||||
* - `loaders`: Dataloader-Instanzen für Batch-Loading (verhindert N+1 Queries)
|
||||
*/
|
||||
export interface GraphQLContext {
|
||||
user: User | null;
|
||||
loaders: {
|
||||
product: DataLoader<string, Product | null>;
|
||||
page: DataLoader<string, Page | null>;
|
||||
user: DataLoader<string, User | null>;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen neuen Context mit Dataloadern und User
|
||||
*/
|
||||
export const createContext = (user: User | null = null): GraphQLContext => {
|
||||
return {
|
||||
user,
|
||||
loaders: {
|
||||
product: createProductLoader(),
|
||||
page: createPageLoader(),
|
||||
user: createUserLoader(),
|
||||
},
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user