如何使用AppSync解析器和Aurora将可选字段插入为null?

bre*_*son 3 resolver amazon-web-services graphql aws-appsync aws-aurora

我有一个可选的String字段notes,有时为空。如果为空,我想插入null,否则我想插入字符串。

这是我的解析器-

{
    "version" : "2017-02-28",
    "operation": "Invoke",
        #set($id = $util.autoId())
        #set($notes = $util.defaultIfNullOrEmpty($context.arguments.notes, 'null'))

        "payload": {
          "sql":"INSERT INTO things VALUES ('$id', :NOTES)",
          "variableMapping": {
            ":NOTES" : $notes
          },
          "responseSQL": "SELECT * FROM things WHERE id = '$id'"
        }
Run Code Online (Sandbox Code Playgroud)

}

有了这个graphql

mutation CreateThing{
  createThing() {
    id
    notes
  }
}
Run Code Online (Sandbox Code Playgroud)

我得到-

{
  "data": {
    "createRoll": {
      "id": "6af68989-0bdc-44e2-8558-aeb4c8418e93",
     "notes": "null"
   }
 }
Run Code Online (Sandbox Code Playgroud)

}

当我真的想要没有引号的null时

有了这个graphql-

mutation CreateThing{
  createThing(notes: "Here are some notes") {
    id
    notes
  }
}
Run Code Online (Sandbox Code Playgroud)

我得到-

{
  "data": {
    "createThing": {
      "id": "6af68989-0bdc-44e2-8558-aeb4c8418e93",
      "notes": "Here are some notes"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这就是我想要的。

如何在同一个字段中添加无引号的null和带引号的字符串?

Tin*_*nou 6

TL; DR,应该用来正确$util.toJson()打印$context.arguments.notes。将您的$notes作业替换为

#set($notes = $util.toJson($util.defaultIfNullOrEmpty($context.arguments.notes, null)))
Run Code Online (Sandbox Code Playgroud)

说明:

原因是VTL会打印toString()方法返回的任何内容,并且您的调用 $util.defaultIfNullOrEmpty($context.arguments.notes, 'null')将返回字符串"null",该字符串将打印为"null"

如果替换为$util.defaultIfNullOrEmpty($context.arguments.notes, null),它将返回一个null字符串。但是,VTL将打印,$notes因为这是它处理null引用的方式。为了打印null,这是的有效JSON表示形式null,我们必须将其序列化为JSON。因此正确的陈述是:

#set($notes = $util.toJson($util.defaultIfNullOrEmpty($context.arguments.notes, null)))
Run Code Online (Sandbox Code Playgroud)

全面测试:

我假设您从AWS AppSync控制台中提供的RDS示例开始并进行了修改。为了重现,我content将模式中的字段更新为可空:

type Mutation {
   ...
   createPost(author: String!, content: String): Post
   ...
}
type Post {
    id: ID!
    author: String!
    content: String
    views: Int
    comments: [Comment]
}
Run Code Online (Sandbox Code Playgroud)

并且我修改了posts表架构,因此content在那里也可以为null :(在Lambda函数内部)

function conditionallyCreatePostsTable(connection) {
  const createTableSQL = `CREATE TABLE IF NOT EXISTS posts (
    id        VARCHAR(64) NOT NULL,
    author    VARCHAR(64) NOT NULL,
    content   VARCHAR(2048),
    views     INT NOT NULL,
    PRIMARY KEY(id))`;
  return executeSQL(connection, createTableSQL);
}
Run Code Online (Sandbox Code Playgroud)

这是该createPost突变的请求模板:

    {
    "version" : "2017-02-28",
    "operation": "Invoke",
    #set($id = $util.autoId())   
    "payload": {
      "sql":"INSERT INTO posts VALUES ('$id', :AUTHOR, :CONTENT, 1)",
      "variableMapping": {
        ":AUTHOR" : "$context.arguments.author",
        ":CONTENT" : $util.toJson($util.defaultIfNullOrEmpty($context.arguments.content, null))
      },
      "responseSQL": "SELECT id, author, content, views FROM posts WHERE id = '$id'"
    }
}
Run Code Online (Sandbox Code Playgroud)

和响应模板:

$util.toJson($context.result[0])
Run Code Online (Sandbox Code Playgroud)

以下查询:

mutation CreatePost {
  createPost(author: "Me") {
    id
    author
    content
    views
  }
}
Run Code Online (Sandbox Code Playgroud)

返回:

{
  "data": {
    "createPost": {
      "id": "b42ee08c-956d-4b89-afda-60fe231e86d7",
      "author": "Me",
      "content": null,
      "views": 1
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

mutation CreatePost {
  createPost(author: "Me", content: "content") {
    id
    author
    content
    views
  }
}  
Run Code Online (Sandbox Code Playgroud)

退货

{
  "data": {
    "createPost": {
      "id": "c6af0cbf-cf05-4110-8bc2-833bf9fca9f5",
      "author": "Me",
      "content": "content",
      "views": 1
    }
  }
}
Run Code Online (Sandbox Code Playgroud)