04.08.2026 404 материалов

Разработчик создал API характеристик смартфонов на .NET и Caddy: нормализованные данные вместо сырых строк

Независимый разработчик опубликовал открытый API характеристик мобильных устройств, который возвращает нормализованные JSON вместо сырых строк. Разбираем архитектуру, возможности фильтрации и реальные ограничения проекта.

Разработчик создал API характеристик смартфонов на .NET и Caddy: нормализованные данные вместо сырых строк

Если существующие API характеристик смартфонов выдают вам строку «Octa-core (1×3.4 GHz Cortex-A725 & 3×3.2 GHz Cortex-A725 & 4×2.2 GHz Cortex-A725)» вместо структурированных данных — проблема не в вашем парсере, а в поставщике данных.

Проблема: данные о железе по-прежнему неудобны для программной обработки

Кто хоть раз работал с публичными API характеристик мобильных устройств — GSMArena-парсерами, DeviceSpecifications-клонами, эндпоинтами сервисов вроде AnTuTu Benchmark — знает эту боль. Характеристики смартфона приходят как сплошные текстовые строки, которые нужно разбирать вручную или через регулярные выражения.

Девелопер под ником Kupa опубликовал на платформе DEV.to описание своего проекта Device Specs API, который решает именно эту задачу: возвращает структурированные, типизированные данные о характеристиках смартфонов. Серверная часть написана на ASP.NET Core (.NET), а в качестве обратного прокси используется Caddy.

Конкретных примеров из оригинала красноречивы. Хочешь получить частоту обновления экрана? Существующий API вернёт что-то вроде "6.7 inches, 120Hz LTPO OLED" — строку, из которой нужно ещё извлечь число. Нужна тактовая частота процессора? Придётся парсить конструкцию вида Octa-core (1×3.4 GHz Cortex-A725 & 3×3.2 GHz Cortex-A725 & 4×2.2 GHz Cortex-A725). Одна задача превращается в лекцию по регулярным выражениям.

Что именно изменилось: типизация и нормализация

Автор проекта перенёс всю нагрузку по парсингу на серверную сторону. Клиент получает не сырые строки, а типизированный JSON, где числа остаются числами, булевы значения — булевыми, а списки RAM и хранилища — массивами объектов.

Примеры нормализованных полей:

  • battery_capacity — целое число (5000), а не строка "5000"
  • has_nfc — булево значение (true), а не "yes"
  • Варианты RAM и хранилища — структурированные массивы вместо склеенной строки вроде "256GB 8GB RAM, 512GB 12GB RAM"

Для обратной совместимости автор сохранил возможность получить и «сырой» формат — через отдельное поле. Это разумное инженерное решение: новые клиенты работают с нормализованными данными, а легаси-интеграции не ломаются.

Deep Filtering: фильтрация через URL-параметры

Отдельная примечательная фича — так называемая глубокая фильтрация (Deep Filtering). Она позволяет формировать сложные запросы к каталогу устройств прямо через параметры URL.

Пример запроса: найти все устройства с батареей более 5000 мА·ч, не менее 8 ГБ RAM, от Samsung или Xiaomi, в названии модели содержащие «pro»:

?battery_gt=5000&ram_gte=8&manufacturer_in=samsung,xiaomi&model_contains=pro

Синтаксис фильтров поддерживает операторы сравнения (_gt, _gte, проверку на вхождение (_in), поиск подстроки (_contains). Подход стандартный для REST API — аналогичная логика используется в Django REST Framework, Hasura, Supabase и других фреймворках.

Однако скептицизм тут уместен. Глубокая фильтрация через URL-параметры работает корректно при небольшом количестве полей и простых условиях. Как только речь заходит о составных логических выражениях («(A или B) и не C»), OR-группировках, полнотекстовом поиске по нескольким полям — URL-параметры быстро упираются в читаемость и длину строки. Неясно, как API автора обрабатывает такие сценарии. Без документации с полным перечнем поддерживаемых операторов и примерами граничных случаев судить сложно.

Архитектура и стек технологий

Стек проекта выглядит следующим образом:

  • Backend: ASP.NET Core Web API на платформе .NET
  • Frontend: гибрид Blazor WebAssembly и Blazor Server
  • Хостинг: Ubuntu 24.04 в Docker-контейнерах
  • Обратный прокси и SSL: Caddy
  • Формат данных: нормализованный JSON

Выбор ASP.NET Core для подобного рода API — вполне рационален. Фреймворк обеспечивает хорошую производительность при обработке JSON, имеет зрелую систему модельного связывания (model binding) для сложных query-параметров и встроенную поддержку OpenAPI/Swagger для документации. Бенчмарки TechEmpower стабильно ставят ASP.NET Core в верхнюю часть таблиц по throughput для JSON-serialization сценариев.

Blazor как фронтенд для документации API — нестандартный, но логичный выбор для .NET-разработчика, который не хочет переключаться на JavaScript-стек. Blazor WebAssembly позволяет отдать SPA без серверного рендеринга, а Blazor Server — обработать интерактивные элементы (например, интерактивный тестер запросов) на сервере. Гибридный режим компилирует оба варианта в один проект.

Почему Caddy, а не Nginx

Автор прямо объясняет мотивацию перехода с Nginx на Caddy: автоматическое управление TLS-сертификатами без certbot и cron-задач. Caddy автоматически выпускает и обновляет Let's Encrypt-сертификаты «из коробки» — достаточно указать домен в конфигурации.

Синтаксис Caddyfile действительно лаконичнее, чем конфиги Nginx. Минимальный конфиг для проксирования на .NET-приложение может выглядеть так:

ds.gtgroup.dev {
    reverse_proxy localhost:5000
}

Всё. Автоматический HTTPS, HTTP/2, HTTP/3, Brotli-сжатие — всё включено по умолчанию. Для сравнения, аналогичная конфигурация в Nginx потребует явного указания путей к сертификатам, настройки ssl-директив, а для автоматического обновления — интеграции с certbot или acme.sh.

Стоит, впрочем, отметить: Caddy менее распространён в production-средах крупных компаний, его экосистема плагинов скромнее, а документация по тонкой настройке производительности — скуднее, чем у Nginx. Для небольшого пет-проекта или indie-сервиса Caddy — отличный выбор. Для highload-инфраструктуры с десятками бэкендов и кастомными логами выбор не так очевиден.

Открытые вопросы

Публикация на DEV.to — это showcase, а не полноценное техническое описание. Несколько существенных деталей остались за кадром:

  1. Источник данных. Откуда берутся характеристики устройств? Парсинг GSMArena? Ручной ввод? Crowdsourcing? Качество API целиком зависит от актуальности и полноты источника. Если база обновляется вручную, через полгода данные начнут устаревать.

  2. Покрытие устройств. Сколько моделей в базе? Есть ли региональные варианты (например, Samsung Galaxy S24 с Exynos в Европе и Snapdragon в США)? Обрабатываются ли разные модификации одной модели с разным объёмом памяти?

  3. Производительность при сложных фильтрах. Какой объём данных в базе, и как Deep Filtering работает на больших выборках? Есть ли индексация по фильтруемым полям? Используется ли реляционная БД или NoSQL-хранилище?

  4. Rate limiting и авторизация. Публичный API без ограничений на количество запросов — рискованная история. Если проект обретёт популярность, расходы на хостинг могут вырасти непредсказуемо.

  5. Лицензия и условия использования. Можно ли коммерчески использовать данные из API? Есть ли ограничения на кеширование?

Зачем это нужно рынку

Несмотря на скромный масштаб пет-проекта, проблема, на которую указывает Kupa, реальна. Разработчики приложений для сравнения смартфонов, маркетплейсы б/у-техники, сервисы trade-in, обзорные сайты — все они нуждаются в структурированных данных о характеристиках. И все они до сих пор вынуждены парсить сырые строки или покупать доступ к коммерческим API (DeviceSpecifications, MobileDeviceSpecs и подобные), которые тоже не всегда предлагают чистые данные.

Нормализованный API с типизированными полями и удобной фильтрацией — это инфраструктурный слой, который мог бы сэкономить сотни часов разработки. Вопрос только в масштабе, качестве данных и долгосрочной поддержке.

Проект доступен по адресу ds.gtgroup.dev — интерфейс включает живую документацию и интерактивный тестер запросов. Для оценки полноты базы и стабильности API этого достаточно.


Автор проекта — разработчик Kupa, работающий на .NET. Проект позиционируется как open showcase и публично доступен для тестирования.