GraphQL - optional after value - graphql

I have the following GraphQL query:
query workflowState($id: String!, $after: String!){
workflowState(id: $id) {
issues(after: $after) {
pageInfo {
hasNextPage,
endCursor
}
nodes {
id
title
labels{
nodes {
id,
name
}
}
}
}
}
}
The first time I run the query I do not want to pass after to the issues I would like to get all issues from the beginning.
When I parse the response, if hasNextPage is true I would like to call the query again and this time pass endCursor to after so I get the next set of paginated results.
I can successfully parse the response and make the second call but
how do I go about making the first call that does not have and after value?
I have tried passing an empty or non-existent UUID, and I get the error: Invalid input: after must be an UUID

This definition
query workflowState($id: String!, $after: String!){
... makes after variable required.
Solution:
Just remove '!' - exclamation mark:
query workflowState($id: String!, $after: String){
... and [when not required] don't pass 'after' variable - issues(after: $after) will get (will be evaluated to) undefined value. This way 'after' will work as an optional parameter.

Related

Building Mutation Graphql Query

I am quite new to GraphQL so I am struggling a little bit to understand how to write a proper Query on the front-end.
So, this is the Mutation I've on the server-side
type Mutation {
addTerminal(terminal: TerminalInput): Terminal
// other stuff not related
}
type Terminal {
terminalId: String!
merchantId: String
terminalDesignator: String
}
input TerminalInput {
terminalId: String!
merchantId: String
terminalDesignator: String
}
I believe it is using the right structure, but when I try to connect with the client-side im a bit confused.
This is the query I've on the front-end.
export const ADD_TERMINAL_MUTATION = () => (
mutation addTerminalMutation($terminalId: TerminalInput) {
addTerminal(terminal: { terminalId: $terminalId }) {
terminalId,
merchantId,
terminalDesignator,
}
}
);
and when I fire it to the server, I receive the following feedback:
Variable "$terminalId" of type "TerminalInput" used in position expecting type "String!".
So I changed to this:
addTerminal(terminal: { terminalId: "123" }) {
and got the error
Variable "$terminalId" is never used in operation "addTerminalMutation".
If I change to
mutation addTerminalMutation($terminalId: String!) {
It says that the TerminalId wasnt provided, but if I log it, it can be seen
So, what is the right way to write this ?
Thanks.
You need to change addTerminalMutation($terminalId: TerminalInput) to addTerminalMutation($terminalId: String!) to indicate the correct type.
First, the
Variable "$terminalId" is never used in operation "addTerminalMutation".
is caused by passing the variable in line
mutation addTerminalMutation($terminalId: TerminalInput)
and never referencing it later.
The problem in the second part seems that the terminalId parameter is not decomposed.
The parameter in the line
addTerminal(terminal: { terminalId: $terminalId })
is expected to be a String!.
You could do something like this:
addTerminal(input: $terminalId)
to pass in the whole terminal id object.
See this for further info:
https://blog.apollographql.com/designing-graphql-mutations-e09de826ed97

GraphQL error FieldsConflict: fields have different list shapes

I'm using AWS AppSync's GraphQL server with the following (simplified) schema:
type Query {
getIssue(id: String!): Issue
}
type Issue {
id: String!
data: IssueData!
}
type Event {
id: String!
time: AWSDateTime!
status: [String]
}
type Payment {
id: String!
amount: Int!
status: String
}
union IssueData = Event | Payment
When I make a query that includes inline fragments to select the status as a child of either an Event or Payment type in the Issue/data field, I get a FieldsConflict error:
query getIssue($id: String!) {
getIssue(id: $id) {
id
data {
... on Event {
time
status
}
... on Payment {
amount
status
}
}
}
}
Validation error of type FieldsConflict: status: fields have different list shapes # 'getIssue/data'
This is presumably caused by the Event/status field returning an array of strings, while the Payment/status field returns a single string.
Why does GraphQL consider this to be a conflict? How should I construct my query to allow access to the status field on both data types?
Note that I'm using a union rather than an extended interface because the Issue and Payment types have no common data structure.
From the spec:
If multiple field selections with the same response names are encountered during execution, the field and arguments to execute and the resulting value should be unambiguous. Therefore any two field selections which might both be encountered for the same object are only valid if they are equivalent.
You can resolve the issue by providing a field alias for one or both fields:
query getIssue($id: String!) {
getIssue(id: $id) {
id
data {
... on Event {
time
eventStatus: status
}
... on Payment {
amount
status
}
}
}
}
Renaming one or both fields in your schema would obviously also resolve the issue.

I get a GraphQL error when running this query using the apollo server. Anyone one knows what is the problem with it?

I am trying to fetch some data from the GitHub GraphQL but I get a GaphQLError. I have tried the same query on the developer section of github and it works. Anyone know what is the problem with it?
issueQuery = gql`
query search(first: 10, type: ISSUE, query: "repo:angular/angular is:issue state:open") {
issueCount
edges {
node {
... on Issue {
createdAt
title
body
url
comments(first: 10) {
nodes {
body
}
}
}
}
}
}
`;
Error Stack Trace:
"GraphQLError: Syntax Error: Expected $, found Name "first"
at syntaxError (http://localhost:4200/vendor.js:70270:10)
at expect (http://localhost:4200/vendor.js:75154:67)
at parseVariable (http://localhost:4200/vendor.js:73984:3)
at parseVariableDefinition (http://localhost:4200/vendor.js:73970:15)
at many (http://localhost:4200/vendor.js:75222:16)
at parseVariableDefinitions (http://localhost:4200/vendor.js:73959:82)
at parseOperationDefinition (http://localhost:4200/vendor.js:73926:26)
at parseExecutableDefinition (http://localhost:4200/vendor.js:73881:16)
at parseDefinition (http://localhost:4200/vendor.js:73845:16)
at many (http://localhost:4200/vendor.js:75222:16)"
New Error Stack Trace when adding $ before the parameters:
"GraphQLError: Syntax Error: Expected Name, found Int "10"
at syntaxError (http://localhost:4200/vendor.js:70270:10)
at expect (http://localhost:4200/vendor.js:75154:67)
at parseName (http://localhost:4200/vendor.js:73809:15)
at parseNamedType (http://localhost:4200/vendor.js:74385:11)
at parseTypeReference (http://localhost:4200/vendor.js:74364:12)
at parseVariableDefinition (http://localhost:4200/vendor.js:73971:83)
at many (http://localhost:4200/vendor.js:75222:16)
at parseVariableDefinitions (http://localhost:4200/vendor.js:73959:82)
at parseOperationDefinition (http://localhost:4200/vendor.js:73926:26)
at parseExecutableDefinition (http://localhost:4200/vendor.js:73881:16)"
Don't confuse the operation with the actual field being queried. The syntax should look like this:
operationType [operationName] [variableDefinitions] {
selectionSet
}
where operationType is one of query, mutation or subscription, operationName is an arbitrary name for your operation used in debugging, variableDefinitions are type definitions for any variables you reference inside the operation, and selectionSet is one or more fields you're actually querying.
In this case, search is a field we're querying, so it should not be proceeded by the query keyword. This works fine, provided you're authenticated:
query OptionalName {
search(first: 10, type: ISSUE, query: "repo:angular/angular is:issue state:open") {
issueCount
edges {
# more fields
}
}
}
If the operation type is query, you can omit the query keyword altogether. This is called "query shorthand":
{
search(first: 10, type: ISSUE, query: "repo:angular/angular is:issue state:open") {
issueCount
edges {
# more fields
}
}
}
If you use variables, define them inside parentheses beside your operation. Variable names are arbitrary, but by convention we use the input field names they will be used in:
query OptionalName ($first: Int, type: SearchType!, $query: String! ) {
search(first: $first, type: $type, query: $query) {
issueCount
edges {
# more fields
}
}
}

Resolving query type with promise in bucklescript

I've got this query im trying to test with with the reason graphql_ppx library. code gist
This is a screenshot of the editor type annotations:
Using the #mhallin/graphql_ppx library, i've got the following query set up:
module FilmQuery = [%graphql
{|
{
allFilms {
films {
id
title
releaseDate
}
}
}
|}
];
exception Graphql_error(string);
/* Construct a "packaged" query; FilmQuery takes no arguments: */
let filmQuery = FilmQuery.make();
/* Send this query string to the server */
let query = filmQuery##query // type string
I get an the following error when i send the query to the server it returns the following error.
{ errors: [ { message: 'Must provide query string.' } ] }
But if you Js.log(query) you see its being constructed which works on https://swapi.apis.guru
query films($first: Int) {
allFilms(first: $first) {
films {
id
title
releaseDate
}
}
}
If you Js.log(filmQuery) you get:
{ query: 'query {\nallFilms {\nfilms {\nid \ntitle \nreleaseDate \n}\n}\n}',
variables: null,
parse: [Function: parse] }
If your run the same query in Altair and you check the query that was sent in the devtools network tab you see:
{"query":" query films($first: Int) {\n allFilms(first: $first) {\n films {\n id\n title\n releaseDate\n }\n }\n }\n","variables":{}}
The editor is provided this type error:
"- error
[bucklescript]
This has type:
string
But somewhere wanted:
Js.t({.. query : string, variables : Js.Json.t })
string"
How do I get this promise/unit type resolved? Thank you.
So the new question is: Why isn't the sendQuery() function recognizing the filmQuery##parse key?
Your sendQuery method is expecting a type in the shape of what is returned from FilmQuery.make(), but you are passing it just the query property, which is a string.
You can fix this by passing filmQuery as into sendQuery instead of just the query property from filmQuery that is referenced by the query variable.

GraphQL mutation variables

I'm trying to do a simple mutation using GraphQL with the GraphiQL interface. My mutation looks like this:
mutation M($name: String) {
addGroup(name:$name) {
id,
name
}
}
with variables:
{
"name": "ben"
}
But it gives me the error: Variable $name of type "String" used in position expecting type "String!"
If I change my mutation to mutation M($name: String = "default") it works as expected. This looks like it's related to the type system, but I can't seem to figure out what the problem is.
You probably defined the input name as a non-null string (something like type: new GraphQLNonNull(GraphQLString) if using js server, or String! in plain GraphQL).
So your input in the mutation must match, which means it must also be a non-null string. If you change to the following, it should work:
mutation M($name: String!) {
addGroup(name:$name) {
id,
name
}
}
Also if you define a default value as you did, it will be a non-null string.
Finally, you could drop the requirement of being a non-null in the server.
I think in you addGroup() mutation the args for name is of type String! that is new GraphQLNonNull(GraphQLString) but in your mutation you specify as String which conflicts with the type system.
When you have an error like this check your database model, in my case I checked my schema and as mongo pluralizes the words was causing me error but I could fix it, also check the documentation.
mutation {
createProject(
name:"project two",
description:"project two"
) {
name
}
}
=> works

Resources