繁体   English   中英

AWS Graphql lambda 查询

[英]AWS Graphql lambda query

我没有为此应用程序使用 AWS AppSync 我已经创建了 Graphql 架构,我已经制作了自己的解析器。 对于每个创建、查询,我都做了每个 Lambda 函数。 我使用了 DynamoDB 单表概念,它是全局二级索引。

对我来说可以,创建一个 Book 项目。 在 DynamoDB 中,该表如下所示: 在此处输入图像描述 .

我遇到了返回 Graphql 查询的问题。 从 DynamoDB 表中获取Items后,我必须使用 Map function 然后返回基于 Graphql typeItems 我觉得这不是有效的方法。 Idk 查询数据的最佳方式。 我也收到 null 作者和作者的查询。

这是我的gitlab-branch

这是我的 Graphql 架构

 import { gql } from 'apollo-server-lambda'; const typeDefs = gql` enum Genre { adventure drama scifi } enum Authors { AUTHOR } # Root Query - all the queries supported by the schema type Query { """ All Authors query """ authors(author: Authors): [Author] books(book: String): [Book] } # Root Mutation - all the mutations supported by the schema type Mutation { createBook(input: CreateBook:): Book } """ One Author can have many books """ type Author { id: ID: authorName: String book: [Book]: } """ Book Schema """ type Book { id: ID: name: String price: String publishingYear: String publisher: String author: [Author] description: String page: Int genre: [Genre] } input CreateBook { name: String price: String publishingYear: String publisher: String author: [CreateAuthor] description; String page; Int genre: [Genre] } input CreateAuthor { authorName: String! } `; export default typeDefs;

这是我创建的图书项目

 import AWS from 'aws-sdk'; import { v4 } from 'uuid'; import { CreateBook } from '../../generated/schema'; async function createBook(_: unknown, { input }: { input: CreateBook }) { const dynamoDb = new AWS.DynamoDB.DocumentClient(); const id = v4(); const authorsName = input.author && input.author.map(function (item) { return item['authorName']; }); const params = { TableName: process.env.ITEM_TABLE? process.env.ITEM_TABLE: '', Item: { PK: `AUTHOR`, SK: `AUTHORS#${id}`, GSI1PK: `BOOKS`, GSI1SK: `BOOK#${input.name}`, name: input.name, author: authorsName, price: input.price, publishingYear: input.publishingYear, publisher: input.publisher, page: input.page, description: input.description, genre: input.genre, }, }; await dynamoDb.put(params).promise(); return {...input, id, }; } export default createBook;

这是查询所有书的方式

 import AWS from 'aws-sdk'; async function books(_: unknown, input: { book: string }) { const dynamoDb = new AWS.DynamoDB.DocumentClient(); const params = { TableName: process.env.ITEM_TABLE? process.env.ITEM_TABLE: '', IndexName: 'GSI1', KeyConditionExpression: 'GSI1PK =:hkey', ExpressionAttributeValues: { ':hkey': `${input.book}`, }, }; const { Items } = await dynamoDb.query(params).promise(); const allBooks = // NEED TO MAP THE FUNcTION THEN RETURN THE DATA BASED ON GRAPHQL //QUERIES. Items && Items.map((i) => { const genre = i.genre.filter((i) => i); return { name: i.name, author: i.author, genre, }; }); return allBooks; } export default books;

这是我的作者查询和控制台结果的图像

在此处输入图像描述

 import AWS from 'aws-sdk'; import { Author, Authors } from '../../generated/schema'; async function authors( _: unknown, input: { author: Authors } ): Promise<Author> { const dynamoDb = new AWS.DynamoDB.DocumentClient(); const params = { TableName: process.env.ITEM_TABLE? process.env.ITEM_TABLE: '', KeyConditionExpression: 'PK =:hkey', ExpressionAttributeValues: { ':hkey': `${input.author}`, }, }; const { Items } = await dynamoDb.query(params).promise(); console.log({ Items }); // I can see the data but don't know how to returns the data like this below type without using map function // type Author { // id: ID: // authorName: String // book; [Book]. // } return Items; // return null in Graphql play ground. } export default authors;

编辑:当前旋转变压器 map

// resolver map - src/resolvers/index.ts
const resolvers = {
  Query: {
    books,
    authors,
    author,
    book,
  },
  Mutation: {
    createBook,
  },
};

TL;DR您缺少一些解析器。 您的查询解析器正在尝试完成缺失解析器的工作。 您的解析器必须以正确的形状返回数据。

换句话说,您的问题在于配置 Apollo Server 的解析器。 据我所知,没有什么 Lambda 特定的。

编写并注册缺少的解析器。

例如,GraphQL 不知道如何“解决”作者的书籍。 Author {books(parent)}条目添加到 Apollo Server 的解析器 map 相应的解析器 function 应该根据您的架构要求返回书籍对象列表(即[Books] )。 Apollo 的文档有一个类似的例子,你可以修改。

这是一个重构的author查询,带有将被调用的解析器的注释:

query author(id: '1') {     # Query { author } resolver
  authorName
  books {                   # Author { books(parent) } resolver
    name
    authors {               # Book { author(parent) } resolver
      id
    }
  }
}

Apollo Server 在查询执行期间使用解析器 map 来决定为给定查询字段调用哪些解析器。 map 看起来像您的架构并非巧合。 解析器函数使用parent、arg、context 和 info arguments 调用,这为您的函数提供了从数据源获取正确记录的上下文。

// resolver map - passed to the Apollo Server constructor
const resolvers = {
  Query: {
    books,
    authors,
    author,
    book,
  },

  Author: {
    books(parent) { getAuthorBooks(parent); }, // parent is the author - resolver should return a list of books
  },

  Book: {
    authors(parent) { getBookAuthors(parent); }, // parent is the book - resolver should return a list of authors
  },
};

您的查询解析器正试图做太多的工作。

解析所有子字段不是作者查询解析器的工作。 Apollo Server 将在查询执行期间多次调用多个解析器:

您可以将 GraphQL 查询中的每个字段视为 function 或返回下一个类型的上一个类型的方法。 事实上,这正是 GraphQL 的工作原理。 每种类型的每个字段都由 function 支持,称为解析器,由 GraphQL 服务器开发人员提供。 当一个字段被执行时,会调用相应的解析器来产生下一个值

Apollo Server 将此称为解析器链 将使用Author作为parent参数调用books(parent)解析器。 您可以使用作者 ID 来查找她的书籍。

您的解析器返回值必须与架构一致。

确保您的解析器以架构所需的形状返回数据。 您的author解析器显然返回了 map {Items: [author-record]} ,但您的架构说它需要是一个列表。

(如果我是你,我会将作者查询签名从author(PK: String, SK: String): [Author]更改为对调用者更友好的东西,例如author(id: ID): Author 。返回 Object,而不是列表。在解析器 function 中隐藏 DynamoDB 实现细节。Apollo Server 有一个被序列化为 StringID标量类型。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM