GraphQL: unknown keywords when trying to query - ruby

I currently using the github/graphql-client ruby gem to try and query my GraphQL API. Here is what I have.
module MyAPI
HTTP = GraphQL::Client::HTTP.new("http://myapi.com/graphql")
Schema = GraphQL::Client.load_schema(HTTP)
Client = GraphQL::Client.new(schema: Schema, execute: HTTP)
end
# Create the query.
CreateMeeting = MyAPI::Client.parse <<-'GRAPHQL'
mutation CreateMeeting($name: String!, $meeting_id: String!){
createMeeting(name: $name, meeting_id: $meeting_id){
name
}
}
GRAPHQL
meeting = {name: 'test', meeting_id: 'm_id'}
MyAPI::Client.query(CreateMeeting, meeting)
This give me back the following error:
unknown keywords: name, meeting_id
I'm not sure what's causing this, because within createMeeting on the API name and meeting_id are defined as String arguments.
Any help is appreciated!

Related

Mock GraphQLUpload dataype in POSTMAN

I am using Postman to send GraphQL queries to my graphQL server. This is what a particular mutation schema looks like:
extend type Mutation {
createMutation(
my_id: ID!
my_data: input_data
): some_output
input input_data {
some_key: int
file : Upload!
}
I am able to perform other mutations and query through graphQL by defining appropriate GraphQL variables in here
I am not sure how to create a json value in GraphQL Variables for "file" of type Upload

Overload GraphQL Schema to Support getting a user by username or password

I am trying to create a GraphQL Schema such that a user will be able to find a user by their email or username. Imagine for these purposes one user could have an email that is the username of another user.
My typeDefs look as follows:
const typeDefs = gql`
type Query {
user: User(username: String!)
user: User(email: String!)
}
`;
Is this a valid Schema? If not how would I change my solution to be valid and solve my problem?
Edit: So I tried to execute the above and I get an error: 'Error: Field "Query.user" can only be defined once.' As I thought I might.
Is there any way to ensure that exactly one of username and email is null in the following: user: User(username: String, email: String)?
There is no "overloading" of fields in GraphQL, and no syntax that would support one of two fields being required. An argument is either nullable or non-null, that's it. You can do this:
type Query {
user(username: String, email: String): User
}
or this
type Query {
user(filter: UserFilter!): User
}
input UserFilter {
username: String
email: String
}
and then handle validation (at least one argument is defined but not both) inside your resolver. The only other way to do it would be something like:
type Query {
user(key: UserFilterKey!, value: String!): User
}
enum UserFilterKey {
username
email
}
But this kind of approach is not very intuitive for anyone consuming the schema. It also only works if the arguments in question have the same type.

Apollo graphQL - can you query local state using variables without having to use a resolver?

I am using apollo-cache-inmemory, apollo-client, react-apollo.
My local state contains a users array like so: -
users: [{
__typename: "User",
userId: "hashid1",
...
},
{
__typename: "User",
userId: "hashid2",
...
}]
Now I can obviously run a simple query to retrieve all the users from the local state: -
import gql from "graphql-tag"
export default gql`{users #client {userId}}`
However, what I would like to do is to be able to query the users array directly, passing variables like so: -
const userDetails = await client.query({ query: USER_DETAILS, variables: {id: "hashId1"}})
Is it possible to run this query without using a resolver? I have attempted the following but { data } returns as null: -
export default gql`query user($id: String!) {users(userId: $id) #client {userId}}`
I already use resolvers and can easily write one to take care of this issue but I am wondering if there it is possible to perform this task without one?
It looks like you're looking for some magic ;)
You must write customization code (overwrite default resolver - return all records) to have a customized behavior (return data filtered by your criteria). That should be obviuos.
There is no default/ready/built in searching/filtering syntax in graphql - therefore, there is no default behaviours for them in apollo-client (no matter local/remote server/data). It is up to you to implement what you need.

GraphQL - Unknown directive "unique"

I just updated GraphQL from version 0.13.2 to 14.0.2. When starting the server, I get the error message: Error: Unknown directive "unique". This is my schema:
const { gql } = require('apollo-server')
// type Query is the root query
exports.typeDefs = gql`
type User {
username: String! #unique
password: String!
}
type Query {
getAllUsers: User
}
Note even though I'm using gql from apollo-server it's using GraphQL under the hood.
As you can see what is causing is the issue is that I've made it so the username has to be unique. The updated version of GraphQL must not have this directive anymore. Sure enough, removing #unique solves the issue. I still want username to be unique. I've read that you can create custom directives. How do I go about doing this?
I've encountered a similar scenario to yours when working in fully custom directives with the upgrade of graphql-tools to v14 the definition of the directive is needed within the schema. You can specify by field, object, mutation where your directive will work.
directive #requireAuth on FIELD_DEFINITION
To work in something like this, at field level
extend type Query {
me: String! #requireAuth
user(userId: ID!):User!
users: [User]!
}
And my class that extends SchemaDirectiveVisitor it's something like this
import { SchemaDirectiveVisitor } from "apollo-server";
export class YourCustomDirective extends SchemaDirectiveVisitor {
// Your code for the directive
}
In the link provided, there is the available methdos to use in order to have your custom logic at field, object, scalar, etc level. Hope this helps.
Schema Directive Visitor

graphql schema import Error: Type "Contact" not found in document

I use graphql-import to load graphql schema written in separate file. I have more than 40+ individual schema files however with surprise it doesn't recognize Contact type I have. Following are more details.
// contact.graphql
type Contact {
firstName: String
lastName: String
email: String!
phoneNumber: String
}
// seller.graphql
# import Contact from './contact.graphql'
type Seller {
sellerId: String!
name: String
image: String
contact: Contact # Somehow not able to find Contact type
}
Note: contact.graphql and seller.graphql are in same directory
Following is code to import schema.
const { importSchema } = require('graphql-import');
// Load GraphQL schema from files
const typeDefs = importSchema('./typedef/index.graphql');
While running server, I get following error. I have no clue why? Any help will be appreciated.
/Users/****/workspace/my-project//node_modules/graphql/utilities/buildASTSchema.js:134
throw new Error('Type "' + typeRef.name.value + '" not found in document.');
^
Error: Type "Contact" not found in document.
at ASTDefinitionBuilder._resolveType (/Users/****/workspace/my-project/node_modules/graphql/utilities/buildASTSchema.js:134:11)
at ASTDefinitionBuilder.buildType (/Users/****/workspace/my-project/node_modules/graphql/utilities/buildASTSchema.js:218:79)
at ASTDefinitionBuilder._buildWrappedType (/Users/****/workspace/my-project/node_modules/graphql/utilities/buildASTSchema.js:227:24)
at ASTDefinitionBuilder.buildField (/Users/****/workspace/my-project/node_modules/graphql/utilities/buildASTSchema.js:248:18)
at /Users/****/workspace/my-project/node_modules/graphql/utilities/buildASTSchema.js:302:21
at /Users/****/workspace/my-project/node_modules/graphql/jsutils/keyValMap.js:28:31
at Array.reduce (<anonymous>)
at keyValMap (/Users/****/workspace/my-project/node_modules/graphql/jsutils/keyValMap.js:27:15)
at ASTDefinitionBuilder._makeFieldDefMap (/Users/****/workspace/my-project/node_modules/graphql/utilities/buildASTSchema.js:299:49)
at fields (/Users/****/workspace/my-project/node_modules/graphql/utilities/buildASTSchema.js:284:23)
Try using # import Contact from 'contact.graphql'
After going through my big schema list, I realized that two graphql file has same schema name as Seller (in different location) that was causing conflict.
Learning is, even we can organize graphql files into different logical directory structure, but we have to keep unique type :-)

Resources