构建一个拥有2600万地址的法国地址验证 API
Source: Dev.to
(请提供您希望翻译的正文内容,我将为您翻译成简体中文。)
问题:碎片化的法国地理数据
如果你在法国构建金融科技产品,需要对客户地址进行 KYC 合规验证。听起来很简单,对吧?
当前格局(2026)
| API / Service | 费用 | SLA | 速率限制 | 公司数据 |
|---|---|---|---|---|
| API Adresse (BAN) | 免费 | 无 | 50 req/s | 否 |
| La Poste RNVP | – | – | – | 无公开的 REST API |
| Google Address Validation | $0.005 /request | – | – | 无 SIRENE 集成 |
| INSEE API SIRENE | 免费 | – | – | 无地址验证,约 500 ms 延迟,单独认证 |
要完成合规的 KYC,通常需要 至少两个 这样的 API,每个都有各自的认证方式、响应格式和速率限制。
我们决定构建一个一次性完成所有功能的 API。
架构概览
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)
分层设计
REST 控制器(17 个控制器,39 个端点)
│
业务服务(12 个接口,16 个实现)
│
仓库(JPA + Elasticsearch)
│
PostgreSQL + Redis + Elasticsearch
从 BAN 导入 2600 万地址
BAN 将其数据以 CSV 文件形式发布,每月更新一次。完整数据集压缩后约为 3.5 GB。
导入策略
- 下载 最新的 BAN CSV 导出文件。
- 使用流式 CSV 读取器 解析(不在内存中加载完整文件)。
- 通过 JDBC 批量操作进行 批量插入(
batch size = 5000)。 - 将城市数据 索引 到 Elasticsearch,以实现自动补全。
法国行政层级
Region (18) → Department (101) → Commune (35 000+) → Address (26 M)
巴黎、里昂和马赛拥有作为子社区的区(arrondissements),它们拥有各自的 INSEE 代码。
我们在 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 评分
Endpoint: POST /addresses/validate
Input: 法国地址。
Output:
- 置信度评分 (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
城市自动完成必须覆盖 35 000 个社区。
- 模糊搜索:
GET /cities/search?q=Monplier(使用fuzziness: AUTO)正确返回 Montpellier。
多租户 API 密钥与速率限制
GEOREFER 是一款 SaaS 产品,提供 5 种订阅计划:
| 计划 | 每日限制 | 速率 /分钟 | 价格 |
|---|---|---|---|
| DEMO | 50 | 10 | 免费 |
| FREE | 100 | 10 | 免费 |
| STARTER | 5 000 | 30 | 49 EUR/月 |
| PRO | 50 000 | 60 | 199 EUR/月 |
| ENTERPRISE | 无限 | 200 | 定制 |
每个 API 密钥都有自己的 令牌桶(Bucket4j)用于速率限制。认证通过 Spring 过滤器链进行:
Request
→ API‑key 验证 (Redis 缓存)
→ 配额检查
→ 速率限制执行
→ 功能门控评估
→ Controller
功能门控(Feature Gate)决定了在特定计划下可用的端点和评分组件,确保高级客户能够使用完整的 GeoTrust 套件,而低级用户只能使用精简版功能。
各计划的端点
例如,公司搜索(/companies)需要 PRO 或更高级别的计划,而 城市搜索 在所有计划中均可使用。
接下来
我们目前已导入 1680 万条 SIRENE 企业,并索引了 35,000+ 个市镇。API 支持 39 个端点,涵盖地理数据、地址验证、公司搜索以及管理/计费。
如果你正在构建涉及法国地址或公司数据的任何项目,欢迎尝试:
- 免费套餐:每日 100 次请求,无需信用卡
- 文档:(链接待定)
- 注册:(链接待定)
- 示例:(链接待定)
在下一篇文章中,我们将深入探讨如何在 66 ms 内使用 PostgreSQL trigram 索引查询 1680 万条 SIRENE 企业。
AZMORIS Engineering — “Software that Endures”