Pass deep prop to shallow input - graphql

If I have a query user and it takes uuid but my variables are deep user.uuid can I pass uuid to the user query?
query User($user.uuid: string) {
user (uuid:$user.uuid) {
createdAt
}
}
Query Variables:
{
"user":{
"uuid": "abc"
}
}

No, the current GraphQL spec does not support referencing properties of a variable if that variable is an object. You may pass in object variables, but they may only be used where an input object is expected, for example, given a schema like:
type Mutation {
createUser(input: UserInput!): User!
}
input UserInput {
email: String!
}
we can do
mutation ($input: UserInput!) {
createUser(input: $input) {
email
}
}
However, if the expected input is a scalar:
type Mutation {
createUser(email: String!): User!
}
we must provide the scalar as a separate variable:
mutation ($email: String!) {
createUser(email: $email) {
email
}
}

Related

GraphQL mutation takes an array as an input parameter and returns a json String

I'm trying to implement mutation query with an array as a parameter and String as a return type.
Here is my schema file:
input OrganizationInput {
orgId: String!
orgName: String!
}
type Mutations {
importOrganizations(input: [OrganizationInput]): String
}
Here is my mutation:
mutation importOrganizations($orgs: [OrganizationInput]) {
importOrganizations(
input: {
orgId: id,
orgName: name
}
)
}
This code doesn't work, but I don't know how to do it properly.
Maybe someone more experienced in GraphQL could help me?
Do you have any errors that can help?
Anyways your mutation need to return fields, e.g.:
mutation importOrganizations($orgs: [OrganizationInput]) {
importOrganizations(
input: {
orgId: id,
orgName: name
})
{
id
name
}
}

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 - variable not defined by operation

My GraphQL schema is defined as:
type Query {
getEntity(id: Int!): Entity
getEntityUsers(entityId: Int!, statusId: Int): [User]
}
type Entity {
id: Int!
name: String!
email: String!
logo: String
createdAt: DateTime!
updatedAt: DateTime!
users(statusId: Int): [User]
}
As you can see I have two ways of getting users for an Entity object. The one that is currently working for my query is the getEntityUsers root resolver method. This query looks like this:
query getEntityUsers($entityId: Int!, $statusId: Int) {
users: getEntityUsers(entityId: $entityId, statusId: $statusId) {
...
}
}
.. with the variables:
{
entityId: 1,
statusId: 2
}
Is there anyway to make the other way work by allowing me to pass in the statusId? Right now the query looks like this:
query getEntity($id: Int!) {
entity: getEntity(id: $id) {
...
users (statusId: 2) {
...
}
}
}
This obviously works with the variables:
{
id: 1
}
But, what if I wanted to use this second method and change the statusId? Is there anyway to pass in the statusId if it's not defined on the root resolver?
I have tried the query:
query getEntity($id: Int!) {
entity: getEntity(id: $id) {
...
users (statusId: $statusId) {
...
}
}
}
.. with the variables:
{
id: 1,
statusId: 2
}
But I just get the error: Variable "$statusId" is not defined by operation "getEntity". Is there anyway to do this?
Every operation (query or mutation) must explicitly define any variables you use inside that operation. So if you have a variable called $statusId, the type for this variable must be specified as part of your operation definition:
query getEntity($id: Int!, $statusId: Int) {
# your selection set here
}
Where those variables are used within your query (whether at the root level, or elsewhere) is irrelevant -- they must always be defined as part of your operation definition.

Can an Apollo Mutation return a custom result object?

The result returned from an Apollo mutation is typically a type or a subset of fields from a type, and this is usually great. So my mutation:
const addUserMutation = gql`
mutation createUser($email: String!, $permissions: [CreatePermissionInput]) {
createUser(input: {email: $email, permissions: $permissions}) {
id
created
lastUpdated
uid
email
permissions {
who
...
}
}
}
`
Which is calling:
extend type Mutation {
createUser(input: CreateUserInput!): User
}
Will return the user with the fields listed.
Problem is, I want to know if the user that we just tried to create already existed or not. So how can I edit the response to include this flag? Can you have a mutation return, say, an object like:
{
exists: true,
user: { ... }
}
So I can do this:
this.props.submit({
variables: {
email,
permissions,
},
}).then(({ result }) => {
console.log(result)
// > { exists: true, user: [USER OBJECT] }
})
I get that this will break the auto cache update but sometimes you need the response from an update to tell you more.
Create an additional type for the return result of mutation
type UserPayLoad {
exists:Boolean
user:User
}
extend type Mutation {
createUser(input: CreateUserInput!): UserPayLoad
}
Just try this. This may help you

Take result from one query / mutation and pipe to another

I'm wondering if there's a way in GraphiQL that will let me pipe the result from one query / mutation into another query / mutation. Here's an example where the login mutation is used to get a viewer and the viewer would be used to query the addresses for that user. Is this possible with GraphQL / GraphiQL.
mutation {
login(credentials: {
email: "me#me.com",
password: "password123",
passwordConfirmation: "password123"
}) {
viewer
}
}
query {
addresses(viewer:viewer) {
city
}
}
The purpose of the selection set in the mutations is to be able to fetch data that has changed as a result of the mutation. But it also makes it possible to fetch related data, as long as you can access is through the mutation result type.
Let's assume we have following types:
type Address {
city: String
}
type User {
addresses: [Address]
}
If the result (payload) type of the login mutation includes a field viewer of type User that refers to the successfully logged in user, you can query any field of the User in the result of the mutation:
mutation {
login(credentials: {
email: "me#me.com",
password: "password123",
passwordConfirmation: "password123"
}) {
viewer {
addresses {
city
}
}
}
}

Resources