API — Countries¶
This page documents CountryController, mounted under /api/countries. It is the smallest controller in PerfShop — a single public reference endpoint.
Controller covered
CountryController → GET /api/countries
GET /api/countries¶
Returns the list of countries supported by PerfShop, sorted with France first then alphabetically by localized label. This endpoint typically feeds the dropdowns of address forms (user profile, checkout).
Auth: none
Controller: CountryController.getCountries()
Service: ValidationService.getCountries() (i18n via I18nService)
Response — 200 OK¶
[
{ "code": "FR", "label": "France" },
{ "code": "DE", "label": "Germany" },
{ "code": "AR", "label": "Argentina" },
{ "code": "AU", "label": "Australia" },
{ "code": "AT", "label": "Austria" },
{ "code": "BD", "label": "Bangladesh" },
{ "code": "BE", "label": "Belgium" },
{ "code": "BR", "label": "Brazil" }
]
The response is a raw JSON array (no envelope). Each entry contains:
| Field | Description |
|---|---|
code |
ISO 3166-1 alpha-2 code (2 uppercase letters) |
label |
Country label in the backend's active language (PERFSHOP_LANG) |
Sorting rules¶
Sorting is performed server-side:
- France first — the
FRkey is sorted with the virtual value"0"while all other countries use"1"as their sort prefix. - Alphabetical on the localized label for all other countries.
This stable sort guarantees that the list order depends only on the active language, and that the default country (FR) is always immediately accessible at the top of the list.
Closed list
The list of supported countries is hardcoded in ValidationService — there is no API to extend it. This limitation is deliberate: it guarantees that every listed country has a postalCode and phone validation rule in ValidationService. Adding a country requires:
- Adding the entry to
ValidationService.getCountries() - Adding the
country.XX=Labelkey tomessages_fr.propertiesandmessages_en.properties - Adding the postal code validation rule to
ValidationService.validatePostalCode() - Adding the phone validation rule to
ValidationService.validatePhone()
Currently supported countries¶
The following ISO codes are present in messages_en.properties (country.* keys):
Europe¶
FR (France), BE (Belgium), CH (Switzerland), LU (Luxembourg), DE (Germany), GB (United Kingdom), NL (Netherlands), ES (Spain), IT (Italy), PT (Portugal), IE (Ireland), AT (Austria), SE (Sweden), NO (Norway), DK (Denmark), FI (Finland), PL (Poland), CZ (Czech Republic), RO (Romania), HU (Hungary), UA (Ukraine), RU (Russia)
Americas¶
US (United States), CA (Canada), MX (Mexico), BR (Brazil), AR (Argentina), CL (Chile), CO (Colombia)
Asia¶
IN (India), PK (Pakistan), BD (Bangladesh), JP (Japan), CN (China), KR (South Korea), TW (Taiwan), HK (Hong Kong), SG (Singapore), MY (Malaysia), PH (Philippines), TH (Thailand), ID (Indonesia), VN (Vietnam)
Oceania¶
AU (Australia), NZ (New Zealand)
Middle East¶
AE (United Arab Emirates), SA (Saudi Arabia), IL (Israel), QA (Qatar), TR (Turkey)
Africa¶
ZA (South Africa), MA (Morocco), TN (Tunisia), EG (Egypt), NG (Nigeria), KE (Kenya)
Total: 56 countries.
Chaos and security¶
No chaos applies to this endpoint. It is:
- Always public
- Always read-only
- Always returned instantly (no database call — the list is built in memory from the i18n keys loaded at startup)
- Excluded from performance chaos interceptors
It is an "infrastructure" endpoint stable by construction — its sole role is to serve as a source of truth for the frontend.
curl example¶
Related links¶
- auth.md —
PUT /api/auth/me— usage of thecountryfield - orders.md —
POST /api/checkout/address— country validation at delivery - Internationalization —
I18nServicemechanism andcountry.*keys