Rules Hub

Coding Rules Library

← Back to all rules
backend ruleStack: node
architecturedesign-patternsclean-codedata-fetchingrefactoring

Encapsulate data fetching in dedicated Providers

Centralize data access and transformation logic within dedicated Provider classes instead of loose functions or inline logic.

PR: Feat/FCK-1669 - Adding Job Landing Page #3656Created: Dec 8, 2025

Bad example

Old codets
1// src/server/utils/jobUtils.ts
2export async function fetchJob(id: string) {
3 const res = await fetch(`https://api.internal/jobs/${id}`);
4 if (!res.ok) return null;
5 return res.json();
6}
7
8// src/server/routes/jobRoute.ts
9import { fetchJob } from '../utils/jobUtils';
10
11app.get('/jobs/:id', async (req, res) => {
12 // Logic depends on a loose function that might be hard to mock or extend
13 const job = await fetchJob(req.params.id);
14 res.json(job);
15});

Explanation (EN)

Using loose functions for data fetching scatters logic across the codebase, making it harder to maintain state, handle configuration, or mock dependencies for testing.

Objašnjenje (HR)

Korištenje zasebnih funkcija za dohvaćanje podataka raspršuje logiku po kodu, što otežava održavanje stanja, upravljanje konfiguracijom ili mockanje ovisnosti za testiranje.

Good example

New codets
1// src/server/providers/JobProvider.ts
2export class JobProvider {
3 constructor(private readonly baseUrl: string) {}
4
5 async getById(id: string): Promise<Job | null> {
6 const res = await fetch(`${this.baseUrl}/jobs/${id}`);
7 if (!res.ok) return null;
8 return res.json();
9 }
10}
11
12// src/server/routes/jobRoute.ts
13import { JobProvider } from '../providers/JobProvider';
14
15app.get('/jobs/:id', async (req, res) => {
16 // Logic is encapsulated in a cohesive class structure
17 const job = await JobProvider.instance().getById(req.params.id);
18 res.json(job);
19});

Explanation (EN)

Encapsulating logic in a Provider class creates a clear boundary for data access. It allows for dependency injection, singleton management, and centralized error handling.

Objašnjenje (HR)

Enkapsulacija logike u Provider klasu stvara jasnu granicu za pristup podacima. To omogućuje ubacivanje ovisnosti (dependency injection), upravljanje singletonima i centralizirano rukovanje greškama.