slogan3

Help me bij het implementeren van type-veilige API-aanvraag- en antwoordverwerking in TypeScript voor {{api_type}}.

description

Door type-veilige API-aanvraag- en antwoordverwerking te implementeren, kan ik runtime-fouten verminderen, de onderhoudbaarheid van de code verbeteren en zorgen dat mijn gegevensstructuren consistent blijven in de hele applicatie.

prompt

try_prompt

Ik heb begeleiding nodig over hoe ik API-aanvragen en antwoorden effectief kan beheren op een type-veilige manier met behulp van TypeScript voor {{api_type}}. Geef voorbeelden v ... more
generate_helper
disclaimerOnPageApi image_legal_disclaimer...

ai_answers

provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een overzicht en voorbeelden om API-aanvragen en -antwoorden type-veilig te beheren met TypeScript voor REST APIs. ### 1. Definieer request- en response-typen Begin met het definiëren van duidelijke TypeScript-interfaces voor je API-aanvragen en -antwoorden: ```typescript // Voorbeeld: Gebruiker aanmaken interface CreateUserRequest { naam: string; email: string; leeftijd?: number; // optioneel } interface UserResponse { id: string; naam: string; email: string; createdAt: string; } ``` ### 2. Functie om API-aanvragen te doen met type-veiligheid Gebruik generieke functies die de request- en response-typen kennen: ```typescript async function apiRequest<T, R>( url: string, options: RequestInit, ): Promise<R> { const response = await fetch(url, options); if (!response.ok) { // Foutafhandeling const errorText = await response.text(); throw new Error(`Fout bij API-aanroep: ${response.status} - ${errorText}`); } const data: R = await response.json(); return data; } ``` ### 3. Aanroepen met type-veiligheid Voor een POST-aanvraag om een gebruiker aan te maken: ```typescript const nieuwUser: CreateUserRequest = { naam: 'Jan Jansen', email: 'jan@example.com', }; apiRequest<CreateUserRequest, UserResponse>('https://api.example.com/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(nieuwUser), }) .then((user) => { console.log('Gebruiker aangemaakt:', user); }) .catch((error) => { console.error('Fout:', error); }); ``` ### 4. Foutafhandeling en type-veiligheid - Controleer of de response succesvol is (`response.ok`). - Gooi expliciet fouten met relevante informatie. - Gebruik `try-catch` blokken bij async/await. Voorbeeld met `try-catch`: ```typescript async function createUser(user: CreateUserRequest): Promise<UserResponse> { try { const result = await apiRequest<CreateUserRequest, UserResponse>('https://api.example.com/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(user), }); return result; } catch (err) { // Afhandeling of her-throw console.error('Error bij aanmaken gebruiker:', err); throw err; } } ``` ### 5. Samenvatting - Definieer duidelijk je request- en response-typen. - Gebruik generieke functies voor API-aanroepen. - Behandel fouten expliciet en overzichtelijk. - Zorg dat je TypeScript-typen je hele proces begeleiden, van request tot response. Wil je nog een uitgebreider voorbeeld of specifieke hulp bij andere API-methoden?
provider: deepseek
model: deepseek-chat
Hier is een uitgebreide handleiding voor type-veilige API-interacties met TypeScript voor REST: ## 1. Basis Type Definities ```typescript // Basis API response types interface ApiResponse<T> { data: T; status: number; message?: string; } interface ApiError { code: string; message: string; details?: unknown; } // Voorbeeld domein types interface User { id: string; name: string; email: string; createdAt: Date; } interface CreateUserRequest { name: string; email: string; password: string; } ``` ## 2. Generic API Client Implementatie ```typescript class ApiClient { private baseURL: string; constructor(baseURL: string) { this.baseURL = baseURL; } async request<T>( endpoint: string, options: RequestInit = {} ): Promise<ApiResponse<T>> { try { const response = await fetch(`${this.baseURL}${endpoint}`, { headers: { 'Content-Type': 'application/json', ...options.headers, }, ...options, }); if (!response.ok) { const errorData: ApiError = await response.json().catch(() => ({ code: 'PARSE_ERROR', message: 'Failed to parse error response', })); throw new ApiError(errorData.message, response.status, errorData.code); } const data: T = await response.json(); return { data, status: response.status, }; } catch (error) { if (error instanceof ApiError) { throw error; } throw new ApiError( 'Network error occurred', 0, 'NETWORK_ERROR' ); } } // Type-veilige methoden async get<T>(endpoint: string): Promise<ApiResponse<T>> { return this.request<T>(endpoint, { method: 'GET' }); } async post<T, U>(endpoint: string, body: U): Promise<ApiResponse<T>> { return this.request<T>(endpoint, { method: 'POST', body: JSON.stringify(body), }); } async put<T, U>(endpoint: string, body: U): Promise<ApiResponse<T>> { return this.request<T>(endpoint, { method: 'PUT', body: JSON.stringify(body), }); } async delete<T>(endpoint: string): Promise<ApiResponse<T>> { return this.request<T>(endpoint, { method: 'DELETE' }); } } ``` ## 3. Custom Error Klasse ```typescript class ApiError extends Error { constructor( message: string, public statusCode: number, public code: string ) { super(message); this.name = 'ApiError'; } } ``` ## 4. Type-veilige Service Laag ```typescript class UserService { private apiClient: ApiClient; constructor() { this.apiClient = new ApiClient('https://api.jouw-domein.nl'); } // Type-veilige methoden met gedefinieerde request/response types async getUser(id: string): Promise<User> { const response = await this.apiClient.get<User>(`/users/${id}`); return response.data; } async createUser(userData: CreateUserRequest): Promise<User> { const response = await this.apiClient.post<User, CreateUserRequest>( '/users', userData ); return response.data; } async updateUser(id: string, userData: Partial<User>): Promise<User> { const response = await this.apiClient.put<User, Partial<User>>( `/users/${id}`, userData ); return response.data; } async deleteUser(id: string): Promise<void> { await this.apiClient.delete(`/users/${id}`); } } ``` ## 5. Runtime Validatie met Zod ```typescript import { z } from 'zod'; // Schema validatie const UserSchema = z.object({ id: z.string().uuid(), name: z.string().min(1), email: z.string().email(), createdAt: z.string().datetime(), }); const CreateUserSchema = z.object({ name: z.string().min(1), email: z.string().email(), password: z.string().min(8), }); // Type inference van Zod schema's type ValidatedUser = z.infer<typeof UserSchema>; type ValidatedCreateUser = z.infer<typeof CreateUserSchema>; // Validatie wrapper class ValidatedApiClient extends ApiClient { async validatedRequest<T>( endpoint: string, schema: z.ZodSchema<T>, options: RequestInit = {} ): Promise<ApiResponse<T>> { const response = await this.request<unknown>(endpoint, options); try { const validatedData = schema.parse(response.data); return { ...response, data: validatedData, }; } catch (error) { if (error instanceof z.ZodError) { throw new ApiError( 'Response validation failed', 422, 'VALIDATION_ERROR' ); } throw error; } } } ``` ## 6. Gebruik in Componenten ```typescript // React component voorbeeld const UserComponent: React.FC = () => { const [user, setUser] = useState<User | null>(null); const [loading, setLoading] = useState(false); const [error, setError] = useState<string | null>(null); const userService = new UserService(); const fetchUser = async (userId: string) => { setLoading(true); setError(null); try { const userData = await userService.getUser(userId); setUser(userData); } catch (err) { if (err instanceof ApiError) { setError(`Fout: ${err.message} (Code: ${err.code})`); } else { setError('Onverwachte fout opgetreden'); } } finally { setLoading(false); } }; const createNewUser = async (userData: CreateUserRequest) => { try { const newUser = await userService.createUser(userData); console.log('Gebruiker aangemaakt:', newUser); } catch (err) { // Type-veilige error handling if (err instanceof ApiError) { switch (err.code) { case 'VALIDATION_ERROR': console.error('Validatiefout:', err.message); break; case 'NETWORK_ERROR': console.error('Netwerkfout:', err.message); break; default: console.error('API fout:', err.message); } } } }; if (loading) return <div>Laden...</div>; if (error) return <div>{error}</div>; return ( <div> {user && ( <div> <h1>{user.name}</h1> <p>{user.email}</p> </div> )} </div> ); }; ``` ## 7. Geavanceerde Features ```typescript // Request/response interceptors class ExtendedApiClient extends ApiClient { private requestInterceptors: Array<(config: RequestInit) => RequestInit> = []; private responseInterceptors: Array<(response: Response) => Response> = []; addRequestInterceptor(interceptor: (config: RequestInit) => RequestInit) { this.requestInterceptors.push(interceptor); } addResponseInterceptor(interceptor: (response: Response) => Response) { this.responseInterceptors.push(interceptor); } async request<T>(endpoint: string, options: RequestInit = {}): Promise<ApiResponse<T>> { // Request interceptors toepassen let processedOptions = options; for (const interceptor of this.requestInterceptors) { processedOptions = interceptor(processedOptions); } const response = await super.request<T>(endpoint, processedOptions); return response; } } // Automatische retry logica class RetryApiClient extends ApiClient { async requestWithRetry<T>( endpoint: string, options: RequestInit = {}, maxRetries: number = 3 ): Promise<ApiResponse<T>> { let lastError: Error; for (let attempt = 0; attempt < maxRetries; attempt++) { try { return await this.request<T>(endpoint, options); } catch (error) { lastError = error as Error; if (error instanceof ApiError && error.statusCode >= 500) { // Alleen retry bij server errors await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000) ); continue; } break; } } throw lastError!; } } ``` ## Belangrijkste Voordelen: 1. **Compile-time type safety**: TypeScript vangt type fouten tijdens ontwikkeling 2. **Runtime validatie**: Zod zorgt voor data-integriteit 3. **Uitbreidbare architectuur**: Makkelijk aan te passen voor nieuwe endpoints 4. **Consistente error handling**: Gestandaardiseerde foutafhandeling 5. **Herbruikbare componenten**: Generic types voor maximale herbruikbaarheid Deze aanpak zorgt voor robuuste, onderhoudbare en type-veilige API-interacties in je TypeScript applicatie.