Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Network Layer -- Modifying the RelayQueryRequest #654

Closed
eyston opened this issue Dec 6, 2015 · 2 comments
Closed

Custom Network Layer -- Modifying the RelayQueryRequest #654

eyston opened this issue Dec 6, 2015 · 2 comments

Comments

@eyston
Copy link

eyston commented Dec 6, 2015

Hello,

This is more of an information request / check of sanity.

I'm toying around with making a custom network layer to modify / split queries. The problem I'm running into is that the RelayNetworkLayer interface doesn't support modifying the RelayQueryRequest. The return value for RelayNetworkLayer#sendQueries doesn't seem to be used for anything internally:

RelayNetworkLayer.sendQueries(currentQueue);

I can still make the custom network layer, the downside being that if I break a query into pieces I can only resolve the entire original RelayQueryRequest at once and would need to merge the responses.

The other option would be to call RelayStoreData#handleQueryPayload directly and incrementally and then resolve the original RelayQueryRequest when all sub queries have been completed. Does this sound sane or insane?

It doesn't seem really feasible to refactor RelayNetworkLayer to return new RelayQueryRequest's since it puts them into the query tracker before calling the network layer (plus they network layer is called via setImmediate).

That said, RelayQueryNode#createNode and RelayQueryNode#clone are so far making it easy screw around with the query data structure.

@josephsavona
Copy link
Contributor

the RelayNetworkLayer interface doesn't support modifying the RelayQueryRequest

This is intentional in order to keep the API surface area small, and allow faster iteration on Relay internals. In particular, allowing users or network layers to modify the query would require us to document and be careful to support the RelayQuery API. We're constantly iterating on this API and are not yet at a point where can support it as public API.

That said, it's easy to imagine how this could work in the future: RelayQueryRequest would be an observable subject, which allows multiple values to be yielded, instead of a deferred which only allows a single value. The network layer could then resolve pairs of query & reponses before closing the request to indicate all data was fetched.

Before we consider that, though, what is your use case? It may very well be something we could support in the core.

@eyston
Copy link
Author

eyston commented Dec 7, 2015

I was seeing if local data could be implemented via a Network Layer (inspired by the reactjs meetup talk by @steveluscher -- the network layer was a common answer on how to extend Relay). This will eventually be done as part of #114, so I'll close this with your answer :).

The idea was having a composite network layer where a query is split and routed to different network layers -- one of which could be local (e.g. https://github.com/relay-tools/relay-local-schema). This is easy for top level fields, but is proving ridiculous if you allow arbitrary mixing ... I'm ending up post-walking the query and building up a queue of queries with each entry of the queue an array of queries capable of being done in parallel.

query {
  viewer {
    id
    messages(first: 10) { ... }
    drafts(first: 10) { ... }
  }
}

default network layer:

query {
  viewer {
    id
    messages(first: 10) { ... }
  }
}

local network layer:

query {
  node(id: <viewer-id>) {
    fragment on User {
      drafts(first: 10) { ... }
    }
  }
}

And then if each draft had author it would go back to the default network layer per draft (but could be done in parallel):

query {
  node(id: <draft-user-id>) {
    fragment on User {
       id name
    }
  }
}

So basically -- a terrible idea it is turning out (ps. this doesn't work at all). Even if this did work an unfortunate thing is that you need the entire local schema on the device at once (vs having the schema downloaded incrementally attached to components).

thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants