Создание GraphQL API для поиска видео

Когда наша база данных видео разрослась до сотен тысяч записей, наше API стало узким местом.

Для одного экрана требовалось пять различных REST-вызовов, чтобы отобразить трендовые видео, сведения о канале, теги, количество просмотров и рекомендации. Пользователям мобильных устройств с медленным соединением приходилось отправлять 30 запросов только для загрузки одной страницы.

GraphQL решает эту проблему. Клиент запрашивает именно то, что ему нужно, одним запросом.

Я разработал готовый к эксплуатации API для поиска видео, используя Strawberry и FastAPI. Вот как я это сделал.

Почему Strawberry?

Я протестировал Graphene и Ariadne, но Strawberry победил по следующим причинам:

Аннотации типов служат схемой. Вы пишете код на Python, а Strawberry строит типы GraphQL. Ручная синхронизация не требуется. • Он нативно поддерживает асинхронность. Это позволяет API обрабатывать множество запросов, не блокируя цикл событий (event loop). • Интеграция с FastAPI бесшовная. GraphQL-эндпоинт располагается рядом с существующими REST-маршрутами. • Встроенный DataLoader. Этот инструмент решает проблему N+1 «из коробки».

Стек данных

Данные хранятся в базе данных SQLite, которой управляет PHP-сайт. Я использую SQLite FTS5 для быстрого полнотекстового поиска.

Python-сервис читает эту базу данных как слой только для чтения. Это гарантирует наличие единого источника истины (single source of truth).

Чтобы поиск был качественным, я смешиваю оценки релевантности FTS5 с сигналом популярности. Это предотвращает ситуацию, когда одно вирусное видео заглушает все остальные результаты поиска.

Решение проблемы N+1

Распространенная ловушка в GraphQL — это проблема N+1. Если вы запрашиваете 20 видео, а затем запрашиваете канал для каждого из них, наивное API выполнит 21 запрос к базе данных.

DataLoader исправляет это с помощью пакетной обработки (batching). Он собирает все ID каналов за один такт и выполняет один запрос, чтобы получить их все. Это сократило время выполнения наших запросов с 40 мс до менее чем 5 мс.

Ключевые проектные решения

Непрозрачные (Opaque) ID: Я использую строки для ID. Это позволяет вносить изменения в будущем, не ломая клиентские приложения. • Намеренная допускаемость null (Intentional Nullability): Я определяю, какие поля могут быть пустыми. Это помогает клиентам обрабатывать отсутствующие данные без сбоев. • Схема только для чтения: GraphQL API не обрабатывает операции записи. Это избавляет от многих проблем с безопасностью. • Кэширование на границе (Edge Caching): GraphQL по умолчанию использует POST, что затрудняет кэширование. Я использую автоматизированные постоянные запросы (Automatic Persisted Queries, APQ), чтобы обеспечить возможность кэширования через Cloudflare.

Если вы боретесь с избытком кастомных эндпоинтов или сложными параметрами запроса, этот стек станет отличным вариантом.

Источник: https://dev.to/ahmet_gedik778845/building-a-graphql-video-discovery-api-with-strawberry-and-fastapi-1dp2