Надійний, швидкий та зручний клієнт на Rust для публічного API Єдиного державного реєстру декларацій (НАЗК)
Ця бібліотека є production-ready обгорткою для взаємодії з реєстром декларацій НАЗК, яка надає сувору типізацію, автоматичну пагінацію, Fluent Builder для зручного пошуку та вбудовану відмовостійкість (Exponential Backoff при 502/503 помилках).
- Сувора Типізація Кроків (Кроки 0..17): Усі кроки декларації, починаючи з особистих даних (
step_1) і закінчуючи доходами (step_11) та нерухомістю (step_3), типізовані, з підтримкою розширення невідомих полів черезHashMap. - Автоматична Пагінація (
Stream): Перегляд великих масивів документів більше не потребує ручного керуванняpage. API самостійно запитує нові сторінки завдякиasync-stream. - Відмовостійкість (Resiliency): Інтегрований
reqwest-middleware+reqwest-retryавтоматично обробляє проблеми зі з'єднанням абоRate Limitsз боку серверів НАЗК. - Fluent Builder: Зручне та захищене створення запитів без
Some(val)за допомогоюDocumentFilterBuilder. - Парсинг специфічних помилок НАЗК: Автоматичний переклад кодів помилок, таких як
1310101(Невідповідність довжини запиту), у зрозуміліRust Enum.
Додайте залежність до вашого Cargo.toml:
[dependencies]
nazk_api = "0.1.0"
tokio = { version = "1", features = ["full"] }
futures = "0.3"use nazk_api::{NazkClient, DocumentFilterBuilder, DOC_TYPE_DECLARATION};
#[tokio::main]
async fn main() -> Result<(), nazk_api::NazkError> {
let client = NazkClient::new();
// Створюємо фільтр пошуку
let filter = DocumentFilterBuilder::new()
.query("Шевченко") // Пошук за прізвищем
.declaration_year(2023)
.document_type(DOC_TYPE_DECLARATION)
.build();
let response = client.list_documents(&filter).await?;
println!("Знайдено документів: {}", response.count);
Ok(())
}Бібліотека автоматично розбиває структуру декларації на відповідні об'єкти (RealEstate, Income, Vehicle тощо).
use nazk_api::NazkClient;
#[tokio::main]
async fn main() -> Result<(), nazk_api::NazkError> {
let client = NazkClient::new();
// Отримання документа
let doc = client.get_document("db6e33f7-9204-4c4f-9eec-108ecf6f96ff").await?;
if let Some(payload) = doc.data {
// Шаг 11: Доходи
if let Some(incomes) = payload.step_11 {
for income in incomes.data {
println!("Розмір доходу: {:?}", income.size_income);
}
}
// Шаг 3: Нерухомість
if let Some(estates) = payload.step_3 {
for estate in estates.data {
println!("Місто: {:?}", estate.city);
}
}
}
Ok(())
}Якщо ви вивантажуєте декларації по певному міністерству або регіону і результатів багато, замість ручної пагінації використовуйте стріми:
use nazk_api::{NazkClient, DocumentFilterBuilder};
use futures::StreamExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = NazkClient::new();
let filter = DocumentFilterBuilder::new()
.work_place("Міністерство")
.build();
// stream_documents сам здійснює ітерацію по сторінках API
let mut stream = Box::pin(client.stream_documents(&filter));
let mut count = 0;
while let Some(result) = stream.next().await {
let doc = result?; // У випадку обриву з'єднання або помилки API ми дізнаємося про це тут
println!("Опрацьовано документ: {}", doc.id);
count += 1;
if count >= 200 { break; }
}
Ok(())
}Помилки НАЗК автоматично перетворюються в NazkError:
match client.get_document("invalid-id").await {
Ok(doc) => println!("Success"),
Err(nazk_api::NazkError::NotFound) => println!("Документ не знайдено (404)"),
Err(nazk_api::NazkError::ApiError(code, msg)) => println!("Помилка API НАЗК [{}]: {}", code, msg),
Err(e) => println!("Мережева або інша помилка: {}", e),
}Цей проєкт поширюється за ліцензією MIT. Ви можете вільно використовувати, змінювати та поширювати його у комерційних та некомерційних цілях.