프랑스 주소 검증 API 구축, 2600만 개 주소
Source: Dev.to
Source: …
문제: 단편화된 프랑스 지리 데이터
프랑스에서 핀테크 제품을 구축한다면 KYC 준수를 위해 고객 주소를 검증해야 합니다. 간단해 보이죠?
현재 상황 (2026)
| API / 서비스 | 비용 | SLA | 요청 제한 | 회사 데이터 |
|---|---|---|---|---|
| API Adresse (BAN) | 무료 | 없음 | 50 req/s | 아니오 |
| La Poste RNVP | – | – | – | 아니오 (공개 REST API 없음) |
| Google Address Validation | $0.005 /요청 | – | – | 아니오 (SIRENE 통합 없음) |
| INSEE API SIRENE | 무료 | – | – | 주소 검증 기능 없음, ~500 ms 지연, 별도 인증 필요 |
적절한 KYC를 수행하려면 일반적으로 두 개 이상의 이러한 API가 필요하며, 각각 고유한 인증 방식, 응답 형식 및 요청 제한 제약이 있습니다.
우리는 모든 기능을 하나의 API로 구현하기로 결정했습니다.
Architecture Overview
GEOREFER는 간단한 Java 스택을 기반으로 구축되었습니다:
Java 11 + Spring Boot 2.7.5
PostgreSQL 16 (42 M+ rows across 12 tables)
Redis 7 (API‑key cache, TTL 5 min)
Elasticsearch 7.17 (city autocomplete, fuzzy search)
Layered design
REST Controllers (17 controllers, 39 endpoints)
│
Business Services (12 interfaces, 16 implementations)
│
Repositories (JPA + Elasticsearch)
│
PostgreSQL + Redis + Elasticsearch
BAN에서 2,600만 개 주소 가져오기
BAN은 데이터를 CSV 파일 형태로 매월 업데이트하여 제공합니다. 전체 데이터셋은 압축 시 약 3.5 GB입니다.
가져오기 전략
- 다운로드 최신 BAN CSV 내보내기 파일.
- 스트리밍 CSV 리더로 파싱 (전체 파일을 메모리에 올리지 않음).
- JDBC 배치 작업을 이용해 배치 삽입 (
batch size = 5000). - Elasticsearch에 도시 데이터를 색인하여 자동완성 기능 제공.
프랑스 행정 계층
Region (18) → Department (101) → Commune (35 000+) → Address (26 M)
파리, 리옹, 마르세유는 자체 INSEE 코드를 가진 하위 행정구역인 arrondissement(구역)를 가지고 있습니다.
우리는 french_town_desc 테이블에 전체 계층 구조를 저장합니다:
SELECT f.name,
f.insee_code,
f.postal_code,
d.name AS department,
r.name AS region
FROM georefer.french_town_desc f
JOIN georefer.department d ON f.department_code = d.code
JOIN georefer.region r ON d.region_code = r.code
WHERE f.name ILIKE 'paris%';
주소 검증 및 GeoTrust 점수
엔드포인트: POST /addresses/validate
입력: 프랑스 주소.
출력:
- 신뢰도 점수 (0‑100) – 주소가 존재한다는 확신 정도.
- GeoTrust 점수 (0‑100) – KYC를 위한 복합 신뢰도 점수.
- 검증된 주소 – 정규화, 교정, GPS 좌표 포함.
- AFNOR 형식 – 우편 표준 NF Z 10‑011 포맷.
점수 모델
| 구성 요소 | 가중치 | 측정 항목 |
|---|---|---|
| 신뢰도 | 35 % | 거리 수준 주소 매칭 |
| 지리 일관성 | 25 % | 우편 번호 ↔ 시/군 ↔ 부서 교차 검증 |
| 우편 일치 | 20 % | 우편 번호 정확도 (정확, 부분, 무효) |
| 국가 위험 | 20 % | FATF/GAFI 국가 위험 등급 |
예시 요청
curl -X POST 'https://georefer.io/geographical_repository/v1/addresses/validate' \
-H 'Content-Type: application/json' \
-H 'X-Georefer-API-Key: YOUR_API_KEY' \
-d '{
"street_line": "15 Rue de la Paix",
"postal_code": "75002",
"city": "Paris",
"country_code": "FR"
}'
예시 응답
{
"success": true,
"data": {
"validated_address": {
"street_line": "15 Rue de la Paix",
"postal_code": "75002",
"city": "PARIS",
"country": "France"
},
"confidence_score": 95,
"geotrust_score": {
"overall": 92,
"level": "LOW",
"components": {
"confidence": 95,
"geo_consistency": 100,
"postal_match": 100,
"country_risk": 0
}
}
}
}
Elasticsearch for City Autocomplete
City autocomplete must cover 35 000 communes.
- Fuzzy search:
GET /cities/search?q=Monplier(usingfuzziness: AUTO) correctly returns Montpellier.
다중 테넌트 API 키 및 속도 제한
GEOREFER는 5개의 구독 플랜을 제공하는 SaaS입니다:
| 플랜 | 일일 한도 | 분당 속도 | 가격 |
|---|---|---|---|
| DEMO | 50 | 10 | Free |
| FREE | 100 | 10 | Free |
| STARTER | 5 000 | 30 | 49 EUR/mo |
| PRO | 50 000 | 60 | 199 EUR/mo |
| ENTERPRISE | Unlimited | 200 | Custom |
각 API 키는 속도 제한을 위해 자체 토큰 버킷(Bucket4j)을 갖습니다. 인증은 Spring 필터 체인을 통해 흐릅니다:
Request
→ API‑key validation (Redis cache)
→ Quota check
→ Rate‑limit enforcement
→ Feature‑gate evaluation
→ Controller
Feature Gate는 주어진 플랜에 대해 어떤 엔드포인트와 점수 산정 구성 요소를 사용할 수 있는지 결정합니다. 이를 통해 상위 티어 고객은 전체 GeoTrust 제품군을 받고, 하위 티어 사용자는 축소된 기능을 제공받습니다.
플랜별 엔드포인트
예를 들어, 회사 검색( /companies)은 PRO 이상 플랜이 필요하고, 도시 검색은 모든 플랜에서 사용할 수 있습니다.
다음 단계
우리는 현재 1,680만 SIRENE 사업장을 가져왔고 35,000개 이상의 커뮌을 색인했습니다. API는 지리 데이터, 주소 검증, 기업 검색, 관리/청구 등 39 엔드포인트를 처리합니다.
프랑스 주소나 기업 데이터를 다루는 무언가를 구축하고 있다면, 한 번 시도해 보세요:
- 무료 티어: 하루 100 요청, 신용카드 필요 없음
- 문서: (link pending)
- 가입: (link pending)
- 예시: (link pending)
다음 기사에서는 PostgreSQL 트라이그램 인덱스를 사용해 1,680만 SIRENE 사업장을 66 ms에 조회하는 방법을 자세히 살펴볼 것입니다.
AZMORIS Engineering — “지속되는 소프트웨어”