Skip to content

Multiple queries on one page #53

@k0ka

Description

@k0ka

What problem does this feature proposal attempt to solve?

My pages are generated using several GraphQL queries. Some of them can be cached and reused. But relay-nextjs allows only one query to be preloaded.

Which possible solutions should be considered?

I have implemented a proof of concept in https://github.com/k0ka/relay-nextjs/tree/multi-query
But it is not backward compatible. The main idea is that instead of

WiredProps<P extends {},Q extends OperationType> 

it is using

WiredProps<P extends {},Q extends {[key: string]: OperationType}>

So the user may pass some hash of queries to preload them. The example page would look like this:

function UserProfile({ preloadedQuery }: RelayProps<{}, {preloadedQuery: profile_ProfileQuery}>) {

And one can preload several queries like this:

function UserProfile({ query1, query2 }: RelayProps<{}, {query1: profile_ProfileQuery, query2: profile_AnotherQuery}>) {

Why backward compatibility breaks?

While it looks easy to add the backward compatibility on the first glance, but after looking in-depth, there are a lot of nuances. And it might end up being a big kludge.

For example, you assume the page always has the preloadedQuery prop to extract the server environment from it:

  const relayProps = getRelayProps(pageProps, initialPreloadedQuery);
  const env = relayProps.preloadedQuery?.environment ?? clientEnv!;

We can enforce that this prop is always set up for some query (it looks like a kludge) or change it as I do in my PoC (breaking BC)

    const [relayProps, serverEnv] = getRelayProps(pageProps, initialPreloadedQueries);
    const env = serverEnv ?? clientEnv!;

Also it is not easy to distinguish OperationType and [key: string]: OperationType in javascript as they both might be objects. We have to check some of the OperationType key type that's always defined and is not an object.

What's next?

I implemented the PoC in a more elegant but BC Breaking way. The next question is whether you really need this feature in the package. It might be too complex and specific for my case. In this case I'll just maintain it in my repo.

If you do need it, we have to decide on the way how to implement it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions