React Query API Design – Lessons Learned

Rate this content
Bookmark

React Query is a popular library for maintaining asynchronous state - most often state returned from data fetching. It has grown so much in popularity over the last couple of years that it is now used in almost 20% of all React applications. To some extent, this is attributed to it's ease of use and great developer experience.


In this talk, React Query maintainer Dominik will walk us through some of the API design choices that were made in React Query to get to that DX. You'll hear stories about things that went well, but also about tradeoffs and mistakes that were made, and what lessons we can all learn from those.

This talk has been presented at React Advanced 2024, check out the latest edition of this React Conference.

FAQ

React Query is a popular open-source library designed to manage server state in React applications. It provides features like caching, request deduplication, and background updates.

Dominik removed multiple signatures from useQuery to simplify the API and improve TypeScript support, reducing the complexity and potential for confusing error messages.

Dominik believes TypeScript helps in designing APIs that are easy to understand and type, reducing complexity and maintenance burden while providing better developer experience.

Dominik works part-time as a contractor, which allows him enough time to contribute to open source projects like React Query, even though it doesn't pay the bills.

Dominik advises considering types from the beginning, taking time before adding features to avoid bloating the API, and ensuring that APIs are intuitive and flexible to meet diverse user needs.

Dominik values user feedback, especially during beta releases, to prevent issues from making it into stable versions. He encourages users to try out beta versions and provide feedback to maintainers.

The challenges include managing user demands while preventing the API from becoming bloated, ensuring new features are aligned with the library's core functionalities, and considering the implementation complexity.

In open source libraries, a major version is about breaking changes rather than new features. These changes require careful planning and often involve marketing efforts to communicate the updates to users.

Dominik is a software engineer from Vienna, working as a front-end tech leader at Verity. He is also known for maintaining the open-source library React Query, now called PanStack React Query.

Dominik Dorfmeister
Dominik Dorfmeister
26 min
25 Oct, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
I'm super excited to be here today, giving my first live talk at an in-person conference. Dominik, the maintainer of React Query, walks through the API design decisions, including success stories, trade-offs, and mistakes. Tener Linsley designed React Query's medium-sized query API to be minimal, intuitive, powerful, and flexible. Major versions in open source require marketing efforts, but not primarily for adding new features. TypeScript is crucial for building projects and managing user demands in open source can be challenging. The addition of the max pages option improved performance and avoided unnecessary refetches. Inversion of control gives users flexibility, but mistakes can happen in API design. Open source requires time management and feedback from users. API design is influenced by typing ease and good TypeScript support. Getting involved in open source involves trial and error and joining community platforms like TanStack Discord. Dominik's journey started during the pandemic and he can be found on Twitter, TanStack Discord, and his blog.

1. Introduction to React Query API Design

Short description:

I'm super excited to be here today, giving my first live talk at an in-person conference. My name's Dominik, a software engineer from Vienna, and I've maintained the popular open-source library React Query for the last three and a half years. I want to walk you through the API design decisions we've made, including stories of success, trade-offs, and mistakes. API design is hard, and React Query's sweet API has contributed to its success.

♪ I'm super excited to be here today, because this is actually the first time that I'm giving a live talk at an in-person conference. Um, yeah, thank you. Um... So I thought I want to take a quick photo just to remember this forever. That's all right. Yeah, all right. Cool, thank you.

Anyway, my name's Dominik. I'm a software engineer from Vienna, where I work as a front-end tech leader at Verity. You can find me online as tkdodo almost everywhere. And for the last three and a half years, I've maintained the quite popular open-source library React Query. Sorry, PanStack React Query, as we call it these days.

Quick question. Please raise your hands if you've heard about that library before. Yeah, wow. Okay, that's a lot of hands. That's great, because it means you might actually know some of the APIs I'm going to talk about today. Because, you know, today, I want to walk you through some of the API design decisions that we've made in React Query over the last couple of years. Um, tell some stories about things that went well, but also highlight some of the trade-offs that we had to make and, you know, there were some mistakes that we made. And, yeah, maybe there are some lessons that we can all learn from those. And I want to talk about that mainly for two reasons.

One, I think API design is hard. If you don't believe me, that's not my quote. Julius said that. He's a really smart guy. He maintains TRPC. He also contributes to React Query from time to time. So if he says it, it's probably right. And the second reason is I think React Query has a really, really sweet API. And it's one of the reasons why it has become so successful over the last couple of years.

2. Evolution of React Query API

Short description:

Tener Linsley designed the library with a medium-sized query API. It needs to be both minimal and intuitive, as well as powerful and flexible. API complexity should grow with application complexity. The useQuery API provides many features out of the box, and additional functions like useMutation can be added for more complex tasks. As an open-source maintainer, I've learned not to be excited about major versions.

Now, of course, I can't take credit for that. Tener Linsley made the library, and he designed most of the APIs. And he actually has a very good tweet summarizing the goals of the library, where he says that the query API is actually medium sized when you unpack it all, but the most important part is that you can understand and learn how to use it by starting with a single function that provides 80% of the entire value proposition first try. From there, the rest of its API can be gradually learned if needed. And I think that's what it takes for a library to become popular. It needs to be both minimal and intuitive, as well as powerful and flexible.

But for any given API, you know, those two things are usually on the opposite sides of the same scale. If we take a look at array methods, for example, on the left-hand side, we would have something like array.join, right? A very simple method. It does one thing and does it very well, and there's no surprises there. And on the other end of the spectrum, we would have something like array.reduce, which is very powerful. We can implement all other array methods just with reduce. But you know, if this is the only thing we have available, it would probably also not be great, because it's also quite complicated to read from time to time.

Now, for libraries, I think the second scale is missing, and that should usually be application complexity, because as your app complexity grows, you actually want your APIs to become more powerful and flexible. And on that scale, I would put useQuery right about here, bottom left, if we call it with the minimal required arguments, which is basically just the query key and the query function. Now, that API, I think, is still quite simple and easy to use, but it gives us a lot of things already out of the box. We get things like caching, requested duplication, background updates, you know, automatic garbage collection, like the list goes on and on. There's a lot of things that we get from just this one function call. And then later on, we might add a useMutation call, right, to make an update and then link it back with invalidate queries. So, this is already a little bit more involved, but, you know, we can get really far with just those two functions.

So, I put that right about here. But as time goes on and your application becomes more complex, you might want to do more things. So, you're going to make an optimistic update, maybe from time to time, or you need an infinite query. And those APIs are certainly a bit more complex. And all the way up, we have, like, for example, our plugins or the cache subscriptions, which are really, really low-level. For example, our dev tools are built with the cache subscriptions. But, you know, once you get to a point where you need this complexity, you're probably happy that those exist as well, just like you are about using reduce from time to time. And that gets me right to the first learning that I had as an open-source maintainer, which is I'm no longer excited about major versions. And I think you probably shouldn't be either. API design is hard.

QnA

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Query: It’s Time to Break up with your "Global State”!
React Summit Remote Edition 2020React Summit Remote Edition 2020
30 min
React Query: It’s Time to Break up with your "Global State”!
Top Content
Global state management and the challenges of placing server state in global state are discussed. React Query is introduced as a solution for handling asynchronous server state. The Talk demonstrates the process of extracting logic into custom hooks and fixing issues with state and fetching logic. Optimistic updates with mutation are showcased, along with the benefits of using React Query for data fetching and mutations. The future of global state management is discussed, along with user feedback on React Query. The Talk concludes with an invitation to explore React Query for server state management.
Managing React State: 10 Years of Lessons Learned
React Day Berlin 2023React Day Berlin 2023
16 min
Managing React State: 10 Years of Lessons Learned
Top Content
Watch video: Managing React State: 10 Years of Lessons Learned
This Talk focuses on effective React state management and lessons learned over the past 10 years. Key points include separating related state, utilizing UseReducer for protecting state and updating multiple pieces of state simultaneously, avoiding unnecessary state syncing with useEffect, using abstractions like React Query or SWR for fetching data, simplifying state management with custom hooks, and leveraging refs and third-party libraries for managing state. Additional resources and services are also provided for further learning and support.
SolidJS: Why All the Suspense?
JSNation 2023JSNation 2023
28 min
SolidJS: Why All the Suspense?
Top Content
Suspense is a mechanism for orchestrating asynchronous state changes in JavaScript frameworks. It ensures async consistency in UIs and helps avoid trust erosion and inconsistencies. Suspense boundaries are used to hoist data fetching and create consistency zones based on the user interface. They can handle loading states of multiple resources and control state loading in applications. Suspense can be used for transitions, providing a smoother user experience and allowing prioritization of important content.
A Practical Guide for Migrating to Server Components
React Advanced 2023React Advanced 2023
28 min
A Practical Guide for Migrating to Server Components
Top Content
Watch video: A Practical Guide for Migrating to Server Components
React query version five is live and we'll be discussing the migration process to server components using Next.js and React Query. The process involves planning, preparing, and setting up server components, migrating pages, adding layouts, and moving components to the server. We'll also explore the benefits of server components such as reducing JavaScript shipping, enabling powerful caching, and leveraging the features of the app router. Additionally, we'll cover topics like handling authentication, rendering in server components, and the impact on server load and costs.
React Query and Auth: Who is Responsible for What?
React Advanced 2021React Advanced 2021
19 min
React Query and Auth: Who is Responsible for What?
Top Content
This talk introduces React Query and Auth, discussing how React Query maintains server state on the client and handles mutations and data updates. The day spa app example demonstrates the use of React Query to fetch data and handle user authentication. React Query is also useful for managing user data and ensuring accurate data from the server. The talk highlights the importance of addressing the three main players in user data: React Query, Auth Functions, and persistence across sessions.
Thinking in React Query
React Summit 2023React Summit 2023
22 min
Thinking in React Query
Top Content
Watch video: Thinking in React Query
React Query is not a data fetching library, but an Asian state manager. It helps keep data up to date and manage agent life cycles efficiently. React Query provides fine-grained subscriptions and allows for adjusting stale time to control data fetching behavior. Defining stale time and managing dependencies are important aspects of working with React Query. Using the URL as a state manager and Zustand for managing filters in React Query can be powerful.

Workshops on related topic

Rethinking Server State with React Query
React Summit 2020React Summit 2020
96 min
Rethinking Server State with React Query
Top Content
Featured Workshop
Tanner Linsley
Tanner Linsley
The distinction between server state and client state in our applications might be a new concept for some, but it is very important to understand when delivering a top-notch user experience. Server state comes with unique problems that often sneak into our applications surprise like:
- Sharing Data across apps- Caching & Persistence- Deduping Requests- Background Updates- Managing “Stale” Data- Pagination & Incremental fetching- Memory & Garbage Collection- Optimistic Updates
Traditional “Global State” managers pretend these challenges don’t exist and this ultimately results in developers building their own on-the-fly attempts to mitigate them.
In this workshop, we will build an application that exposes these issues, allows us to understand them better, and finally turn them from challenges into features using a library designed for managing server-state called React Query.
By the end of the workshop, you will have a better understanding of server state, client state, syncing asynchronous data (mouthful, I know), and React Query.
Fetch, useEffect, React Query, SWR, what else?
React Advanced 2023React Advanced 2023
102 min
Fetch, useEffect, React Query, SWR, what else?
Top Content
WorkshopFree
Ondrej Polesny
Ondrej Polesny
In this workshop, first, we’ll go over the different ways you can consume APIs in React. Then, we’ll test each one by fetching content from a headless CMS (with both REST and GraphQL) and checking in detail how they work.
While there is no advanced React knowledge required, this is going to be a hands-on session, so you’ll need to clone a preconfigured GitHub repository and utilize your preferred React programming editor, like VS Code.
You will learn:- What diverse data fetching options there are in React- What are advantages and disadvantages of each- What are the typical use cases and when each strategy is more beneficial than others