Graphql Apollo客户端从AppSync返回空值

时间:2018-07-26 23:26:39

标签: reactjs graphql aws-appsync

我有一个AppSync api设置,具有特定的突变设置。当我在AppSync中测试该突变时,效果很好。但是,当我尝试在react应用程序中使用相同的查询时,我得到的是空值。但是,当我在浏览器的“网络”选项卡中查找时,从AppSync返回了正确的数据。

我的React应用程序中存在以下突变:

import gql from 'graphql-tag';

export default gql`
mutation CreateUser(
  $email: String!,
  $name: String
) {
  createUser(input: {
    email: $email
    name: $name
  }) {
    __typename
    id
  }
}
`;

我的React组件(为简洁起见,略作编辑):

import React, { Component } from 'react';
import MutationCreateUser from '../GraphQL/MutationCreateUser';
import { graphql } from "react-apollo";

class UserForm extends Component {

  state = {
    name: '',
    email: '',
    ... 
    err: null
  }

  ...

  submit = async () => {
    const { createUser, history } = this.props;
    const user = this.state;
    try {
      const result = await createUser({
        name: user.name,
        email: user.email
      });
      // This shows { "data": { "createUser": "null" } }
      console.log('RES', result);
    } catch (e) {
      this.setState({ err: e.message });
    }
    ... 
  }
  ... 
}

export default graphql(
  MutationCreateUser,
  {
    props: ({ mutate }) => {
      return {
        createUser: (user) => {          
          return mutate({
            variables: user
          });
        }
      }
    }
  }
)(UserForm);

当我在“网络”标签中检查查询时,我看到: {"data":{"createUser":{"__typename":"User","id":"860b7cec-e882-4242-aca0-d4865154b640"}}}

但是,在我的React组件中,我看到了: { "data": { "createUser": "null" } }

我不确定是否丢失了有关如何使用Apollo设置组件的信息,这意味着未正确加载数据。但是查询本身似乎工作正常。

数据也按预期正确存储在DynamoDB中。

这是我的请求映射:

{
  "version": "2017-02-28",
  "operation": "PutItem",
  "key": {
    "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
  },
  "attributeValues": $util.dynamodb.toMapValuesJson($ctx.args.input),
  "condition": {
    "expression": "attribute_not_exists(#id)",
    "expressionNames": {
      "#id": "id",
    },
  },
}

我的响应映射:

$util.toJson($ctx.result)

最后是我的模式:

input CreateQuestionInput {
    text: String!
    sectionId: ID!
}

input CreateScoreInput {
    score: Int!
    questionId: ID!
    userId: ID!
}

input CreateSectionInput {
    title: String
    subSection: String
}

input CreateUserInput {
    email: String!
    name: String
    jobTitle: String
    jobTitleShare: Boolean
    department: String
    level: Int
    yearRange: Int
    industry: String
    orgSize: Int
}

input DeleteQuestionInput {
    id: ID!
}

input DeleteScoreInput {
    id: ID!
}

input DeleteSectionInput {
    id: ID!
}

input DeleteUserInput {
    id: ID!
}

type Mutation {
    createSection(input: CreateSectionInput!): Section
    updateSection(input: UpdateSectionInput!): Section
    deleteSection(input: DeleteSectionInput!): Section
    createScore(input: CreateScoreInput!): Score
    updateScore(input: UpdateScoreInput!): Score
    deleteScore(input: DeleteScoreInput!): Score
    createQuestion(input: CreateQuestionInput!): Question
    updateQuestion(input: UpdateQuestionInput!): Question
    deleteQuestion(input: DeleteQuestionInput!): Question
    batchCreateQuestion(questions: [CreateQuestionInput]!): [Question]
    createUser(input: CreateUserInput!): User
    updateUser(input: UpdateUserInput!): User
    deleteUser(input: DeleteUserInput!): User
}

type Query {
    getSection(id: ID!): Section
    listSections(filter: TableSectionFilterInput, limit: Int, nextToken: String): SectionConnection
    getScore(id: ID!): Score
    listScores(filter: TableScoreFilterInput, limit: Int, nextToken: String): ScoreConnection
    getQuestion(id: ID!): Question
    listQuestions(filter: TableQuestionFilterInput, limit: Int, nextToken: String): QuestionConnection
    getUser(id: ID!): User
    listUsers(filter: TableUserFilterInput, limit: Int, nextToken: String): UserConnection
}

type Question {
    id: ID!
    text: String!
    sectionId: ID!
}

type QuestionConnection {
    items: [Question]
    nextToken: String
}

type Schema {
    query: Query
}

type Score {
    id: ID!
    score: Int!
    questionId: ID!
    userId: ID!
}

type ScoreConnection {
    items: [Score]
    nextToken: String
}

type Section {
    id: ID!
    title: String
    subSection: String
    questions: [Question]
}

type SectionConnection {
    items: [Section]
    nextToken: String
}

type Subscription {
    onCreateSection(id: ID, title: String): Section
        @aws_subscribe(mutations: ["createSection"])
    onUpdateSection(id: ID, title: String): Section
        @aws_subscribe(mutations: ["updateSection"])
    onDeleteSection(id: ID, title: String): Section
        @aws_subscribe(mutations: ["deleteSection"])
    onCreateScore(
        id: ID,
        score: Int,
        questionId: ID,
        userId: ID
    ): Score
        @aws_subscribe(mutations: ["createScore"])
    onUpdateScore(
        id: ID,
        score: Int,
        questionId: ID,
        userId: ID
    ): Score
        @aws_subscribe(mutations: ["updateScore"])
    onDeleteScore(
        id: ID,
        score: Int,
        questionId: ID,
        userId: ID
    ): Score
        @aws_subscribe(mutations: ["deleteScore"])
    onCreateQuestion(id: ID, text: String, sectionId: ID): Question
        @aws_subscribe(mutations: ["createQuestion"])
    onUpdateQuestion(id: ID, text: String, sectionId: ID): Question
        @aws_subscribe(mutations: ["updateQuestion"])
    onDeleteQuestion(id: ID, text: String, sectionId: ID): Question
        @aws_subscribe(mutations: ["deleteQuestion"])
    onCreateUser(
        id: ID,
        email: String,
        jobTitle: String,
        jobTitleShare: Boolean,
        department: String
    ): User
        @aws_subscribe(mutations: ["createUser"])
    onUpdateUser(
        id: ID,
        email: String,
        jobTitle: String,
        jobTitleShare: Boolean,
        department: String
    ): User
        @aws_subscribe(mutations: ["updateUser"])
    onDeleteUser(
        id: ID,
        email: String,
        jobTitle: String,
        jobTitleShare: Boolean,
        department: String
    ): User
        @aws_subscribe(mutations: ["deleteUser"])
}

input TableBooleanFilterInput {
    ne: Boolean
    eq: Boolean
}

input TableFloatFilterInput {
    ne: Float
    eq: Float
    le: Float
    lt: Float
    ge: Float
    gt: Float
    contains: Float
    notContains: Float
    between: [Float]
}

input TableIDFilterInput {
    ne: ID
    eq: ID
    le: ID
    lt: ID
    ge: ID
    gt: ID
    contains: ID
    notContains: ID
    between: [ID]
    beginsWith: ID
}

input TableIntFilterInput {
    ne: Int
    eq: Int
    le: Int
    lt: Int
    ge: Int
    gt: Int
    contains: Int
    notContains: Int
    between: [Int]
}

input TableQuestionFilterInput {
    id: TableIDFilterInput
    text: TableStringFilterInput
    sectionId: TableIDFilterInput
}

input TableScoreFilterInput {
    id: TableIDFilterInput
    score: TableIntFilterInput
    questionId: TableIDFilterInput
    userId: TableIDFilterInput
}

input TableSectionFilterInput {
    id: TableIDFilterInput
    title: TableStringFilterInput
}

input TableStringFilterInput {
    ne: String
    eq: String
    le: String
    lt: String
    ge: String
    gt: String
    contains: String
    notContains: String
    between: [String]
    beginsWith: String
}

input TableUserFilterInput {
    id: TableIDFilterInput
    email: TableStringFilterInput
    jobTitle: TableStringFilterInput
    jobTitleShare: TableBooleanFilterInput
    department: TableStringFilterInput
    level: TableIntFilterInput
    yearRange: TableIntFilterInput
    industry: TableStringFilterInput
    orgSize: TableIntFilterInput
}

input UpdateQuestionInput {
    id: ID!
    text: String
    sectionId: ID
}

input UpdateScoreInput {
    id: ID!
    score: Int
    questionId: ID
    userId: ID
}

input UpdateSectionInput {
    id: ID!
    title: String
}

input UpdateUserInput {
    id: ID!
    email: String
    jobTitle: String
    jobTitleShare: Boolean
    department: String
    level: Int
    yearRange: Int
    industry: String
    orgSize: Int
}

type User {
    id: ID!
    email: String
    jobTitle: String
    jobTitleShare: Boolean
    department: String
    level: Int
    yearRange: Int
    industry: String
    orgSize: Int
}

type UserConnection {
    items: [User]
    nextToken: String
}

该请求在AppSync中有效:

enter image description here

1 个答案:

答案 0 :(得分:0)

由于数据已正确存储在DynamoDB中,因此响应映射模板中可能存在类型不匹配的情况。请使用ALL作为设置为您的API启用Cloudwatch日志记录。然后,您可以在CloudWatch日志中查看评估后的响应映射模板,然后将ctx.result.data与用户类型的形状进行比较。

如果仍然无法正常运行,请在此处发布您的架构和映射模板,以便最终尝试复制它。谢谢。