👋 Welcome back to Stef’s Dev Notes - this is Article #2 in my series on API Design.
In the first article, we explored the problem with data-dump APIs and the vision for APIs that enable experiences, not just expose tables.
Now we go deeper. How do you turn a database schema into an API that actually serves the UI? How do you balance performance, clarity, and developer experience? This article lays out practical patterns and decisions for building experience-driven APIs.
Why Schema-First Isn’t Enough
Many API designs start with the database schema:
We have a
users
table → we create/users
We have an
orders
table → we create/orders
We have a
transactions
table → we create/transactions
It feels natural, but here’s the problem: users don’t care about tables.
A product manager doesn’t ask: “Give me the orders
table.”
They ask: “I need daily revenue for the last 30 days, with average order value and top products.”
Schema-first APIs leave the frontend to stitch together business views, filter data, and perform calculations that should happen on the server. The result? slow dashboards, messy code, and duplicated business logic.
Schema is important - it defines the foundation - but it must be mapped to user-facing experiences.
GraphQL vs. Purpose-Built REST
This is where teams often diverge. Two approaches dominate:
1. GraphQL
GraphQL lets clients request exactly what they need:
Pros: flexibility, avoids over-fetching, dynamic queries.
Cons: harder to monitor, complex caching, risk of frontend leaking business logic.
2. Purpose-Built REST
Purpose-built REST endpoints are designed for specific experiences:
Response:
Frontend consumption becomes simple:
No manual aggregation, no complex transformations - just ready-to-use data.
When GraphQL Makes Sense
While purpose-built REST endpoints excel in clarity and performance, GraphQL shines in specific scenarios:
Highly dynamic clients
Multiple frontend apps (web, mobile, admin dashboards) with different data needs.
Rapidly evolving features
Clients can request new fields without changing the server endpoint.
Complex relationships and nested data
Fetch deeply related entities (e.g., orders → customers → addresses → product details) in a single query.
Multiple consumers with differing needs
SaaS platforms with dashboards or embedded analytics that would otherwise require dozens of REST endpoints.
Trade-offs to keep in mind:
Monitoring and caching are more complex.
Business logic may shift to the frontend if queries are uncontrolled.
Over-flexibility can create inconsistent data views.
Rule of thumb:
Use GraphQL when flexibility and multiple consumers outweigh simplicity.
Use purpose-built REST when clarity, performance, and frontend simplicity are top priorities.
Designing Purpose-Built Endpoints in Practice
Here’s a practical workflow:
User story:
As a store manager, I want to see daily revenue metrics for the last 30 days so I can track sales performance.
Schema reality:
Only an
orders
table exists.
Schema-first approach:
GET /orders
→ returns 50,000 orders → frontend calculates metrics.
Experience-first approach:
GET /api/dashboard/revenue-metrics?range=30d
→ returns exactly what the UI needs.
This small shift reduces frontend complexity, improves performance, and centralizes business logic.
When Frontend Processing Still Makes Sense
Even with experience-driven APIs, there are cases where the frontend still performs some data manipulation:
Virtualized tables or infinite scrolling: Large datasets are loaded lazily instead of fetching everything at once.
Pagination and sorting: Dynamic rearrangements based on user interactions.
UI-specific transformations: Formatting timestamps, localizing currencies, or generating derived display fields.
The key is knowing what belongs where:
Heavy aggregations, business rules, and calculations across thousands of records → backend
UI-focused transformations, filtering, and rendering → frontend
Purpose-built APIs don’t remove all client-side processing, but they reduce unnecessary complexity, making frontend work predictable and maintainable.
A Decision Framework for API Design
When designing endpoints, I use four checks:
User-first → What task is the user doing?
Data-shape alignment → What shape of data makes the frontend simplest?
Performance placement → Should this calculation happen server-side or client-side?
Change resilience → Will this endpoint break if the schema evolves?
Running each API idea through this framework keeps your endpoints durable, consistent, and maintainable.
The Payoff: Developer Experience
Even though some frontend processing is still necessary, for virtualized tables, lazy loading, or UI-specific transformations, the benefits of experience-driven API design are clear:
Less boilerplate: Frontend engineers spend more time on UI, accessibility, and user flows, instead of manual data transformations.
Faster iteration: New dashboard features and tweaks are easier to implement because the data is already structured for the UI.
More consistent logic: Business calculations live in one place, reducing subtle bugs caused by scattered rules.
In real-world terms, what might have been dozens of lines of client-side aggregation and filtering can often be reduced to a few lines of code that simply render the data, freeing up time for actual product improvements.
Experience-driven API design isn’t a magic bullet, it’s a steady improvement in developer productivity, maintainability, and product quality.
Closing & Looking Ahead
Designing APIs isn’t just about exposing data, it’s about enabling the experiences your users need.
In this article, we explored practical ways to move from schema-first thinking to experience-driven endpoints:
Understanding when GraphQL makes sense vs when purpose-built REST is the better choice
Designing endpoints around user tasks, not tables
Simplifying frontend code by centralizing business logic and shaping responses for consumption
Recognizing that some frontend processing is still necessary for large or interactive datasets
Experience-driven APIs unlock faster iteration, clearer team alignment, and better outcomes for your users.
In the next article, Article #3: The Collaboration Playbook, we’ll dive into how frontend and backend teams can work together effectively, using contract-first design, workshops, and early mocks to catch misalignments before they become costly.
💡 Over to you:
Have you struggled to balance frontend needs with backend endpoints? What strategies helped your team?
I’d love to hear your experiences and lessons learned.
Until next time,
Stefania
Articles from the ♻️ Knowledge seeks community 🫶 collection: https://stefsdevnotes.substack.com/t/knowledgeseekscommunity
Articles from the ✨ Frontend Shorts collection:
https://stefsdevnotes.substack.com/t/frontendshorts
👋 Get in touch
Feel free to reach out to me, here, on Substack or on LinkedIn.