Files
admin/docs/apps-architecture/react-frontend/layers/refdata.md
T
2026-06-25 15:53:49 +03:00

2.5 KiB

Reference Data Layer

Table of Contents

Purpose

The refdata/ layer contains app-wide reference datasets that are reused across modules.

Reference data is data that usually comes from the backend, but is not owned by one feature module.

Examples:

  • countries
  • languages
  • currencies
  • time zones
  • common option dictionaries
  • shared lookup datasets

Responsibilities

The refdata/ layer is responsible for:

  • fetching common reference datasets
  • exposing reusable query hooks for those datasets
  • defining cache keys for reference data
  • keeping app-wide lookup data out of feature modules

For small datasets, a single file per dataset is enough:

refdata/
├── countries.ts
├── languages.ts
└── currencies.ts

For larger datasets, use a folder:

refdata/
└── countries/
    ├── api.ts
    ├── dto.ts
    ├── mapper.ts
    ├── queries.ts
    └── keys.ts

Rules

  1. Use refdata/ only for app-wide datasets.

    If a dataset belongs to one feature module, keep it in that module's data/ layer.

  2. refdata/ may use infrastructure.

    Reference data hooks can use #infrastructure/axios and #infrastructure/reactQuery.

  3. refdata/ should not import from view/, pages/, or feature modules.

    It should remain reusable across the app.

  4. Expose hooks or small service functions.

    Consumers should not need to know backend endpoints or cache key details.

  5. Add mappers when backend DTOs differ from app-facing reference data.

    If a reference dataset performs DTO transformation, test the mapper the same way module data mappers are tested.

Examples

import { keepPreviousData, useQuery } from "@tanstack/react-query";
import { axiosClient } from "#infrastructure/axios";
import { createKeyBuilder } from "#infrastructure/reactQuery";

export const countriesCacheKey = createKeyBuilder(
  "REF_DATA",
  "COUNTRIES",
  "LIST",
);

interface CountryData {
  code: string;
  name: string;
}

export const useCountries = () => {
  return useQuery({
    queryKey: countriesCacheKey.store(),
    placeholderData: keepPreviousData,
    queryFn: async () => {
      return axiosClient
        .get<Array<CountryData>>("/datasets/countries")
        .then((data) => data.data);
    },
  });
};