Apollo-client: Feature: Allow switching between batched and non-batched transport based on request

Created on 24 May 2017  路  7Comments  路  Source: apollographql/apollo-client

Based on this conversation: https://apollographql.slack.com/archives/C11QBB84R/p1495471281173263

It would be great to have a new NetworkInterface type that uses a batch transport by default but allows you to force a single request if you don't want it to batch. This is useful since it's possible for automatic batching to hold up an entire page because fast important queries are batched with slow unimportant ones, which end up blocking all requests on the slowest query

A possible implementation / design would be a new HTTPHybridNetworkInterface (or a better name if people have one) that would wrap a HTTPFetchNetworkInterface and a HTTPBatchNetworkInterface and route requests to one or the other based on a property of the request

Most helpful comment

All 7 comments

I'm not sure if something like this should live inside Apollo Client core. Although we currently do implement a few network interfaces within the core, this seems like something that might do better as an independent package.

That makes sense. I'll close my PR

I started digging into writing a custom networkInterface and an issue I ran into is that I can't forward any custom options from my query into my networkInterface. I'm using react-apollo and ideally would like to do something like:

graphql(
  gql`
  query TestQuery($organizationId: Int) {
    organization(id: $organizationId) {
      id
      name
    }
  }`,
  {
    options: ({ organizationId }) => ({
      variables: { organizationId },
      disableBatch: true, // or priority: 0 or any sort of custom info
    }),
    props: ({ data }) => ({
      organization: data.organization,
    }),
  }
);

Any thoughts on forwarding custom options as part of the request? Or some way to tag a request at query time in a way that a customNetworkInterface can do something interesting with?

Hey @gauravmk, I see your problem, but I don't think there's a decent way of solving this problem at the moment. We're working on a new network interface and core client API that will actually let you do this exact thing: pass through metadata with every query. For now, I think you should be able to use a special variable (that doesn't exist on the query) and read that out in the middleware. So for example you could use variables: { organizationId, __disableBatch: true }. I haven't tested it, but I think it should work. If you can try it, please report back here so other people can see if it worked or not.

Yep, that's exactly what I ended up doing and it works for us.

For other folks who want to do something similar, we're basically doing this:

/* @flow */
import {
  createBatchingNetworkInterface,
  createNetworkInterface,
  HTTPBatchedNetworkInterface,
  HTTPFetchNetworkInterface,
  Request,
} from 'apollo-client';

export class HTTPHybridNetworkInterface {
  batchedInterface: HTTPBatchedNetworkInterface;
  networkInterface: HTTPFetchNetworkInterface;

  constructor(opts: Object) {
    this.batchedInterface = createBatchingNetworkInterface(opts);
    this.networkInterface = createNetworkInterface(opts);
  }

  query(request: Request) {
    if (request.variables && request.variables.__disableBatch) {
      return this.networkInterface.query(request);
    } else {
      return this.batchedInterface.query(request);
    }
  }

  use(middlewares: Array<*>) {
    this.networkInterface.use(middlewares);
    this.batchedInterface.use(middlewares);
    return this;
  }

  useAfter(afterwares: Array<*>) {
    this.networkInterface.useAfter(afterwares);
    this.batchedInterface.useAfter(afterwares);
    return this;
  }
}

export function createHybridNetworkInterface(opts: Object) {
  return new HTTPHybridNetworkInterface(opts);
}

@gauravmk I'm wondering if this is something you could add to the documentation? http://dev.apollodata.com/core/network.html#custom-network-interface

People are frequently asking about custom network interfaces and need a basic example of a custom network interface to satisfy a common use case they can either use or modify to fit their needs. There is an 'Edit on Github' link on the page.

Was this page helpful?
0 / 5 - 0 ratings