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

JSON object as String in query variables #262

Closed
sudheerj opened this issue Dec 27, 2016 · 12 comments
Closed

JSON object as String in query variables #262

sudheerj opened this issue Dec 27, 2016 · 12 comments
Labels

Comments

@sudheerj
Copy link

sudheerj commented Dec 27, 2016

Can you please guide on how to pass below JSON object as String

{
"filter": {
"region": "APAC",
"code": {"in": [ "HK1", "SG1" ]},
"account_number": {"nin": [ "1" ]}
}
}

@asiandrummer
Copy link
Contributor

Hey @sudheerj! I'm not really sure what you mean by passing JSON object as String - are you trying to execute a query with above JSON as variables?

@sudheerj
Copy link
Author

Exactly.I want to pass above JSON object as String query variable.It contains many operators and fields.The above expression is a direct Mongoose schema that works on DB.I don't want to pass it as InputObject.

@asiandrummer
Copy link
Contributor

Let me try answering in a couple phases:

  1. I guess the easiest way is, given that the JSON is simple enough (which is probably not what you want), if you declare the type of $filter argument as GraphQLString, you could pass it in as a JSON.stringifyed string from Variable Editor I presume:
{
  "filter": "{ "region: "APAC", ... }"
}

If what you wanted is to pass an object and convert it into a string later, it'll be difficult to achieve that as GraphiQL does not (and probably should not) attempt to process the query/variables strings; instead it merely passes the provided strings to GraphQL executor (in this case graphql-js). You might be able to tweak the fetcher function to detect certain GraphQL variable keys and process into the string format there, but it feels too much of a hack.

  1. I'd advise to create a GraphQLInputObject type for this:
new GraphQLInputObjectType({
  name: 'filter',
  fields: {
    "region": { type: GraphQLString },
    "code": { type: new GraphQLInputObjectType({ ... }) },
    "account_number": { type: new GraphQLInputObjectType({ ... }) },
  }
});

FYI, you may already know this, but I did a quick google search and came up with a couple of example adapter libraries with GraphQL and Mongoose DB (e.g. graffiti-graphql), as well as some posts on what other people did to connect the two.

For the last mark, this question is probably more suited for graphql-js repository (I'm making an educated guess from looking at your other questions and the fact that you may be using graphql-js reference implementation for your application)

@sudheerj
Copy link
Author

sudheerj commented Dec 28, 2016

I should pass JSON object only because it contains mongoose operators which executed directly.You can observe $gt,$gte,$in,$nin etc so I'am expecting them as String instead on Input object.

Do I need to pass filter args for Root query here? Other inputs will be passed to Model object

let RootQuery = new GraphQLObjectType({
  name: 'Query',      //Return this type of object
  fields: () => ({
    accounts: AccountQueries.accounts
    
  })
});

@leebyron
Copy link
Contributor

leebyron commented Jan 9, 2017

@asiandrummer's suggestion is a good one. You simply provide a string for your variable which happens to appear as JSON:

{
  "filter": "{ \"region\": \"APAC\", ... }"
}

Within your application, you can first call JSON.parse() on the string variable to get your unstructured JSON object within your server.

@leebyron leebyron closed this as completed Jan 9, 2017
@nikordaris
Copy link

nikordaris commented May 3, 2017

@leebyron the suggestion to escape quotes in a string is very cumbersome for large data and not a reasonable solution for this in my opinion. Given there is a JSONString input type, GraphiQL should support transforming the Object variable to JSONString. Defining custom Input Types is also not possible for my situation since this is for a mutation that needs to support multiple types and interfaces are not supported for input types. My work around for now is to do the hacky modification of my fetcher. This still has the problem of GraphiQL highlighting my variables saying, "Expected value of type JSONString". But I guess I can just ignore this since this is only used by our sys admins.

For anyone else facing this same situation this is my fetcher:

fetcher = (params) => {
    let {variables = {}} = params;
    variables = variables && Object.keys(variables).reduce((result, key) => {
      if (hasIn(variables[key], '__stringify')) {
        return {...result, [key]: JSON.stringify(variables[key].__stringify)};
      }
      return {...result, [key]: variables[key]};
    }, {});
    return fetch('/graph', {
      method: 'POST',
      headers: new Headers({
          'Content-Type': 'application/json'
      }),
      body: JSON.stringify({...params, variables})
    }).then((response) => {
      return response.json();
    });
  }

I used a __stringify wrapper to avoid stringifying unintended objects.

@leebyron
Copy link
Contributor

leebyron commented May 3, 2017

@nikordaris, JSONString is not part of the standard set of scalars and GraphiQL only supports the standard set, that's a custom scalar type added by your server. If you're sending complex unstructured JSON data as a string - I suggest calling JSON.stringify on the client before sending the query

@acronoah
Copy link

I have the same issue. I can submit the JSON just fine, but graphIQL complains that the type is supposed to be Json.

acao added a commit to acao/graphiql that referenced this issue Jun 1, 2019
acao pushed a commit to acao/graphiql that referenced this issue Jun 5, 2019
@robross0606
Copy link

I'm still seeing this problem as of today:
image

@acao
Copy link
Member

acao commented May 4, 2022

hello @robross0606 - that is insomnia, i think you need to open a ticket with them!

@acao
Copy link
Member

acao commented May 4, 2022

Another route to implementing this here and in insomnia would be via this initiative, and thus adopting the graphql spec for custom scalar URLs therein

#2386

so, custom, non-spec scalars like JSON or DateTime, etc can all be implemented and automatically validated, etc

@nikolov9996
Copy link

Screenshot 2023-09-15 at 10 53 00

This worked!

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

No branches or pull requests

8 participants