Msw: Support multiple GraphQL endpoints

Created on 31 Jul 2020  Β·  10Comments  Β·  Source: mswjs/msw

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
our app has to hit multiple graphql endpoints. So this is either a question, or if it's not possible a feature request.

The problem is that our app is using graphql endpoints from more than 1 url.

Describe the solution you'd like

The ability to specify the base url for a graphql.query.

Currently you define a route like this: graphql.query("MyQuery", () => {})

Not sure exactly what the best api is for this, but here are a couple of options.

1) something simple like

graphql.query("MyQuery", () => {}, {baseUrl:"http://example")
graphql.query("MyFooQuery", () => {}, {baseUrl:"http://foo")

2) something at a higher level that let's us map multiple queries:

graphql.urls({
  "http://example": [
     graphql.query("MyQuery", () => {}), graphql.query("MyOtherQuery", () => {})
  ],
  "http://foo": [
     graphql.query("MyFooQuery", () => {}), graphql.query("MyOtherFooQuery", () => {})
  ]

3) open to other options? just need a way to handle multiple GQL endpoints. again, maybe there's already a way and we can close this issue.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

graphql feature

Most helpful comment

πŸŽ‰ that was fast! Thank you @kettanaito !

All 10 comments

Hey, @benmonro.

What do you think if we adopt an approach similar to Apollo's "Link" component and allow to define a separate graphql request handler instances based on the server URL?

import { setupWorker, graphql } from 'msw'

const gitHub = graphql.link('https://api.github.com/graphql')
const stripe = graphql.link('https://api.stripe/v3/gql')

setupWorker(
  gitHub.query('GetUser', resolver),
  stripe.mutation('WithdrawFunds', resolver),
)

I'd appreciate your expertise in GraphQL to suggest us what the API for graphql.link (or graphql.client) may look like. Is there anything else to cover than the endpoint URL?

Such API should definitely exist, and we need to define its spec first.

  1. How should it align with the existing GraphQL clients? Should it resemble something like schema federation?
  2. Should the endpoint URL support parameters, wildcards, RegExp? Is there a practical use in such support?
  3. Should graphql.link allow some per-endpoint logic? For example, a custom "middleware".

This would be perfect! Nice clean API, I love it.

My expertise on gql is limited I'm afraid but everything you said all seems good to me. I think the way you describe it also lends itself to iteration.

to avoid breaking changes we should support both forms? πŸ€”

Hey, @marcosvega91. There's no breaking changes, as graphql.link just encapsulates both .query and .mutation, adding an extra URL (mask) predicate check.

I've started working on this, will ship pull request soon!

The graphql.link API has been added to the 0.20.2 release πŸŽ‰

Refer to the Documentation for explanations and use examples.

πŸŽ‰ that was fast! Thank you @kettanaito !

@kettanaito just curious, do you think it would make sense to apply this same pattern to rest?

i.e. rest.link?

While it may sound compelling, graphql.link and rest.link would have significant design difference:

  • graphql.link adds an extra layer of endpoint matching as a part of its predicate.
  • rest already matches a request URL against a given endpoint, so the functionality of linking routes to a specific endpoint becomes a matter of a plain abstraction:
const github = (path: string) => {
  return `https://api.github.com/v3${path}`
}

rest.get(github(β€˜/repo/:owner/:name’), resolver)

I wish this was a way we solve a per-endpoint mocking for GraphQL as well, and it may become similar to this in the future.

Yeah for sure. Makes sense just thought it would be more consistent to have a unified approach...

We actively encourage functional composition, so introducing a function that prepends a fixed portion of a URL is the way to go. Think of it as of custom React hooks: if you need a hook you don't request it to be added to the React API, you reuse existing hooks to create your own. Request handlers in this matter are very similar: you are given an API and you are in charge of adapting it so it suits your specific needs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Afsoon picture Afsoon  Β·  3Comments

otaciliolacerda picture otaciliolacerda  Β·  3Comments

hauptrolle picture hauptrolle  Β·  4Comments

lukesmurray picture lukesmurray  Β·  3Comments

abrudin picture abrudin  Β·  3Comments