graphql-request icon indicating copy to clipboard operation
graphql-request copied to clipboard

Support operation name

Open Henner25 opened this issue 6 years ago • 10 comments

It is not possible to run queries like this because the name of the operation I want the server to execute cannot be specified (see http://graphql.org/learn/serving-over-http/#post-request):

query HeroName {
  hero {
    name
  }
}

query HeroNameAndFriends {
  hero {
    name
    friends {
      name
    }
  }
}

Do you intend to add this functionality?

Henner25 avatar Feb 28 '18 14:02 Henner25

Great point @Henner25. Do you have a suggestion on how to extend the API without introducing a breaking change? 💡

schickling avatar Feb 28 '18 16:02 schickling

You probably do not want request(query, variables, operation) because then the user would have to pass an empty variables object just to select an operation?

Having both request(query, operation, variables) and request(query, variables) and discerning the call by checking the type of the second argument does not feel nice either...

So no, unfortunately I don't know of a very nice way.

Henner25 avatar Feb 28 '18 16:02 Henner25

How about introducing a new signature for input using JS de-structuring. request({ query, variables, operation } )

Detecting object vs string for backward compatibility. Adding the new operation field only to the de-structuring way of input.

And dropping support for old signature request(query, variables) in 2.x or maybe keeping it around forever?

divyenduz avatar Aug 01 '18 09:08 divyenduz

We should explore the implications of having both at the same time in terms of DX (editor auto-completion support, type inference etc).

I'd really like to preserve the simplicity of request('{ hello }') and not complicate it with something like request({ query: '{ hello }' })

schickling avatar Aug 01 '18 11:08 schickling

We can support both, editor autocomplete works when types for various call signatures is specified like in graphql-yoga. I will set it up and send a couple of GIFs to show how that looks like.

divyenduz avatar Aug 01 '18 11:08 divyenduz

Any intent on when operation name will become supported or what would need to be done in a pr to get support for this feature?

nathanBrenner avatar Nov 22 '18 21:11 nathanBrenner

Given the following query:

query HeroName {
  hero {
    name
  }
}

query HeroNameAndFriends {
  hero {
    name
    friends {
      name
    }
  }
}

mutation CreateNewHero($name: String) {
  hero {
      createNewHero(name: $name) {
         id
         name
      }
  }
}

With pull request #165 , HeroName can be called viz:

request(serverUrl, query, { __operation: 'HeroName' });

or, as:

// Configure a custom key for `operationName`
var client = new GraphqlClient(serverUrl, { operationNameKey: '$operationName' });

// Make a request with the custom key
client.request(query, { $operationName: 'HeroName' });

The mutation CreateNewHero can be called viz:

request(serverUrl, query, { __operation: 'CreateNewHero', name: "New Hero Name" });

Notice how the name variable played along with the __operation variable.

This approach would extend the API without introducing a breaking change.

adebisi-fa avatar May 27 '20 16:05 adebisi-fa

I like @divyenduz suggestion -- allow the first arg to be an object. But given it's been years now, I guess it's not acceptable. An alternative would be to add:

requestOperation(query, variables, operationName, requestHeaders)

Yeah, it's gross but it gives people who want to log operations on the server a way to adopt/keep this nifty library.

timscott avatar May 14 '21 15:05 timscott

Any idea when this will be supported? Having a hard time intercepting requests made by graphql-request using Cypress

jasonlimantoro avatar Jun 05 '21 08:06 jasonlimantoro

@jasonlimantoro

As a workaround, here my HttpRequestInterceptor to catch GraphQL call and response the correct fixture.

import { HttpRequestInterceptor } from 'cypress/types/net-stubbing'

const stubbedOperations = {
  getSocieties: {
    fixture: 'graphql/getSocieties.json',
  },
}

/**
 * Get operation name from request `query operationName {`
 */
const OPERATION_NAME_REGEX = /(?<=^query\s*)\w+(?=\s*\{)/

/**
 * Stubs the calls to graphql
 * @param req
 */
export const stubGraphql: HttpRequestInterceptor = async (req) => {
  const matching = req.body.query.match(OPERATION_NAME_REGEX)
  const operationName = matching[0]
  const stubbedOperation = stubbedOperations[operationName]
  if (stubbedOperation) {
    console.log('Stubbing operation', stubbedOperation)
    req.alias = `gql${operationName}`
    req.reply({
      statusCode: 200,
      fixture: stubbedOperation.fixture,
    })
  } else {
    console.warn('Un mocked graphQL call')
    req.reply({
      statusCode: 404,
      body: 'Missing GraphQL mock',
    })
  }
}

ghost avatar Jul 13 '21 12:07 ghost

hey, any update on this feature request?

elijaholmos avatar Dec 23 '22 19:12 elijaholmos

It is sent now.

jasonkuhrt avatar Feb 03 '24 05:02 jasonkuhrt