Building a GraphQL Video Discovery API

When our video database grew to hundreds of thousands of records, our API became the bottleneck.

A single screen needed five different REST calls to show trending videos, channel details, tags, view counts, and recommendations. Mobile users on slow connections had to send 30 requests just to load one page.

GraphQL solves this. The client asks for exactly what it needs in one request.

I built a production video discovery API using Strawberry and FastAPI. Here is how I did it.

Why Strawberry?

I tested Graphene and Ariadne, but Strawberry won for these reasons:

• Type hints are the schema. You write Python code, and Strawberry builds the GraphQL types. No manual syncing is needed. • It is async-native. This allows the API to handle many requests without blocking the event loop. • FastAPI integration is seamless. The GraphQL endpoint lives right next to existing REST routes. • Built-in DataLoader. This tool solves the N+1 problem out of the box.

The Data Stack

The data lives in a SQLite database managed by a PHP site. I use SQLite FTS5 for fast full-text search.

The Python service reads this database as a read-only layer. This ensures there is only one source of truth.

To make search feel good, I blend FTS5 relevance scores with a popularity signal. This prevents a single viral video from drowning out all other search results.

Solving the N+1 Problem

A common trap in GraphQL is the N+1 problem. If you fetch 20 videos and then fetch the channel for each one, a naive API will run 21 database queries.

DataLoader fixes this by batching. It collects all channel IDs in one tick and runs a single query to fetch them all. This dropped our query time from 40ms to under 5ms.

Key Design Choices

• Opaque IDs: I use strings for IDs. This allows for future changes without breaking client apps. • Intentional Nullability: I define which fields can be empty. This helps clients handle missing data without crashing. • Read-only Schema: The GraphQL API does not handle writes. This removes many security headaches. • Edge Caching: GraphQL uses POST by default, which is hard to cache. I use Automatic Persisted Queries (APQ) to allow caching via Cloudflare.

If you struggle with too many custom endpoints or complex query parameters, this stack is a strong option.

Source: https://dev.to/ahmet_gedik778845/building-a-graphql-video-discovery-api-with-strawberry-and-fastapi-1dp2