Graphql scalar type for a value that can be string or object? - graphql

i have an api for sign up which returns error of string or null,
error: 'Email already use' or error: null
how do i construct it in schema? what i have now is this:
const typeDefs = gql`
type Mutation {
signUp(email: String, password: String): String
}
`;
since typeof null is object, how can i make it like this in graphql?
signUp(email: String, password: String): String || Object
Help?

GraphQL has a standard syntax for returning error values and your schema does not directly need to account for this.
In your schema I would “unconditionally” return whatever type you’d normally expect to return:
type UserAccount { ... }
type Query {
me: UserAccount # or null if not signed in
}
type Mutation {
signUp(email: String!, password: String!): UserAccount!
}
If it’s unsuccessful, you will get back a null field value (even though the schema in theory claims it shouldn’t) and an error.
{
"errors": [
{
"message": "It didn’t work",
"locations": [ { "line": 2, "column": 3 } ],
"path": [ "signUp" ]
}
]
}

In GraphQL you can define what field can be null and what can't.
Take a look at the docs:
https://graphql.org/learn/schema/#object-types-and-fields
String is one of the built-in scalar types - these are types that
resolve to a single scalar object, and can't have sub-selections in
the query. We'll go over scalar types more later.
String! means that the field is non-nullable, meaning that the GraphQL service promises
to always give you a value when you query this field. In the type
language, we'll represent those with an exclamation mark.
So in case of your schema String is absolutely fine. It can be null
type Mutation {
signUp(email: String, password: String): String
}

Related

Why can I execute mutation function with null parameter with type being `String!`?

Simple table with one two rows. ID (incrementing int) and test_value (TEXT, nullable).
1. Query
query getData($test_value:String!) {
testtable(where: {test_value: {_eq: $test_value}}) {
test_value
}
}
Variables
{"test_value":null}
Result
{
"errors": [
{
"extensions": {
"path": "$.selectionSet.testtable.args.where.test_value._eq",
"code": "validation-failed"
},
"message": "unexpected null value for type \"String\""
}
]
}
This is a correct that I expect.
2. Mutation
mutation InsertData($test_value: String!) {
insert_testtable(objects: {test_value: $test_value}) {
affected_rows
}
}
Variables
{"test_value":null}
Result
{
data: {
insert_testtable: {
affected_rows: 1
}
}
}
I expect and error (because of test_value:String! declaration), but I don't get it.
Why?
P.S.
testable schema looks like this:
id: Int!
test_value: String
My understanding of your issue: Your schema has a mutation insert_testtable that takes a nullable String argument. When you submit a named mutation operation with a non-nullable String! variable, the GraphQL server does not respond with an error.
The GraphQL spec says that is the expected behaviour for mutations and queries. The spec says that if the type in the schema is nullable and of the same type as the variable, the operation is to be considered valid. This is what's happening for your mutation.
If you are not seeing the same behaviour for the query, it is possible that your GraphQL server implementation differs from the spec. You could check your server docs or their GitHub Issues.
For what it's worth, I checked that AppSync, AWS's GraphQL implementation, produces the expected behaviour for both queries and mutations.

Error Cannot return null for non-nullable type: 'String' within parent MyModelType' (/createMyModelType/id)

I am trying to trigger a mutation in the aws console. I have linked my resolver function to a None type data source.
However, when I define my mutation with an input type as a parameter, the error " Error Cannot return null for non-nullable type: 'String' within parent MyModelType' (/createMyModelType/id)." occurs. Everything is fine though if I replace the input type with key word arguments.
I am certain it has to do with my resolver mapping template.
Just if you're wondering why I am using a None type, I want to be able to trigger a subscription without making real database changes or mutations.
I am not sure how to make it work with input types. Here is my code for the template:
{
"version": "2017-02-28",
"payload": $util.toJson($context.args)
}
My Schema:
input CreateMyModelType5Input {
title: String
}
type Mutation {
createMyModelType5(input: CreateMyModelType5Input!): MyModelType5
}
type MyModelType5 {
id: ID!
title: String
}
type Subscription {
onCreateMyModelType5(id: ID, title: String): MyModelType5
#aws_subscribe(mutations: ["createMyModelType5"])
}
Query I am trying to run:
mutation createMyModelType($createmymodeltypeinput: CreateMyModelTypeInput!) {
createMyModelType(input: $createmymodeltypeinput) {
id
title
}
}
Query Variables for the mutation query
{
"createmymodeltype5input": {
"title": "Hello, world!"
}
}
So I have been working on passing my arguments in the graphql mutation and using the input type seemed the only straight forward way around.
However, I have been able to do it with this way:
mutation = """mutation CreateMyModelType($id: String!, $title: String!){
createMyModelType(id: $id, title: $title){
id
title
}
}
"""
input_params = {
"id": "34",
"title": "2009-04-12"
}
response = app_sync.createMyModelType(mutation, input_params)
this can be a good guide

GraphQL, Apollo Server Federated schema

I get this error while querying:
"Cannot return null for non-nullable field Transaction.createdAt."
This is the query:
query getMyTransactions {
getMyTransactions {
id
createdAt
}
}
The schema for this query is:
extend type Transaction #key(fields: "id") {
id: ID! #external
}
type Query {
getMyTransactions: [Transaction!]!
}
And the other schema has Transaction type:
type Transaction #key(fields: "id") {
id: ID!
createdAt: String!
}
What's the problem?
EDIT: If I query for:
getMyTransactions {
id
}
Works ok I and get all the id of the query, but if I include another attribute the query fails.
In simple words - you declare createdAt type to be non-null value, but somewhere in your data createdAt is null.
createdAt: String!
! after the type name. This means that our server always expects to
return a non-null value for this field, and if it ends up getting a
null value that will actually trigger a GraphQL execution error,
letting the client know that something has gone wrong. GraphQl docs
Example
For this remote/local data (createdAt missing from the first object):
const Transaction = [
{
id: "1",
/* createdAt: "01/09/2020" */ /* missing from the data */
},
{
id: "2",
createdAt: "02/09/2020"
}
];
Executing query
query{
getMyTransactions {
id
createdAt
}
}
throw error:
"message": "Cannot return null for non-nullable field
Transaction.createdAt.",
To solve this:
Option 1: Add some resolver logic and/or add validation related to your required data.
Option 2: Remove the require from createdAt (return null allowed):

Using ID in GraphQL parametrized query

I have the following schema:
type Post {
id: ID!
text: String
}
I am using autogenerated mutations from neo4j-graphql.js, so I have access to the following mutation:
UpdatePost(
id: ID!
text: String
): Post
The issue:
When I'm using the following query:
mutation update($id: String, $text: String) {
UpdatePost(id: $id, text: $text) {
id
text
}
}
With the following parameters:
{
"id": "a19289b3-a191-46e2-9912-5a3d1b067cb2",
"text": "text"
}
I get the following error:
{
"error": {
"errors": [
{
"message": "Variable \"$id\" of type \"String\" used in position expecting type \"ID!\".",
"locations": [
{
"line": 1,
"column": 17
},
{
"line": 2,
"column": 18
}
],
"extensions": {
"code": "GRAPHQL_VALIDATION_FAILED"
}
}
]
}
}
Is there a way to convert my string ID to the actual ID type? Or circumvent this error altogether?
The error you're seeing is related to the type of your variables as specified in your query's variable definitions. It has nothing to do with the values of the variables (which appear to be correct). Based on the error message, the type of your $id variable is String, not ID as shown in the query you pasted.
Regardless, because the type of the id argument (where the $id variable is being used) is ID!, not ID, then your variable's type should also be ID!.
The ! indicates a non-null (required) type. In other words, the id argument must always be provided and it cannot be given the value null. Any variable passed the argument must also be non-null. If the variable's type is ID instead of ID!, we're telling GraphQL the variable might be omitted or have a null value, which would be incompatible with the argument where it's being used.
Note that the opposite is not true: if the argument's type was ID, then either an ID or ID! variable would be valid.
For anyone else encountering this issue, in the mutation definition you have:
mutation update($id: String, $text: String) {
UpdatePost(id: $id, text: $text) {
id
text
}
}
where you're explicitly saying the $id is a String, you need to change it to ID like so:
mutation update($id: ID, $text: String) {
UpdatePost(id: $id, text: $text) {
id
text
}
}
This is why you're seeing the error, because your query to update it's saying explicitly that ID is a type String hence the error.
In case someone else is looking for an answer, here's few example how to use ID variable in C#:
var request = new GraphQLRequest
{
Query = #"
query getToken($tokenId: ID!){{
tokens(where: {{ id: $tokenId}} orderBy: decimals, orderDirection: desc) {{
id
symbol
name
}}
}}", Variables = new
{
tokenId = "<stringValue>"
}
};
And for using lists:
query getToken($tokenIds: [ID!]){{
tokens(where: {{ id_in: $tokenIds}} orderBy: decimals, orderDirection: desc) {{
id
symbol
name
}}
}}", Variables = new
{
tokenIds = new ArrayList(<yourStringArrayListValue>)
}

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