简体   繁体   English

阿波罗服务器+续集错误不可为空的字段

[英]apollo server + sequelize error non-nullable field

i'm running a apollo server with sequelize as orm to a postgres database.我正在运行一个 apollo 服务器,它的 sequelize 为 orm 到 postgres 数据库。 This is the schema:这是模式:

    type Tag {
        id: ID!
        name: String!
    }

    type Service {
        id: ID!
        name: String!
        slug: String!
        tags: [Tag!]!
    }

the resolver:解析器:

        findServicesByTag: async(_, { tag }, { models }) => {
            const res = await models.Service.findAll({
                where: {
                    '$Tags.name$': tag
                }
                ,include: [
                    {
                        model: models.Tag,
                        as: 'Tags'
                    }
                ]
            })
            console.log(res)
            return res
        }

But when execute this query但是当执行这个查询时

query {
  findServicesByTag(tag: "restaurant")
  {
    id name slug
    tags {
      name
    }
  }
}

i get the message "Cannot return null for non-nullable field Service.id."我收到消息“无法为不可为空的字段 Service.id 返回 null。”

The console.log istruction print this data: console.log 指令打印此数据:

[ Service {
    dataValues: { id: 1, name: 'Restaurant X', Tags: [Array] },
    _previousDataValues: { id: 1, name: 'Restaurant X', Tags: [Array] },
    _changed: Set {},
    _options:
     { isNewRecord: false,
       _schema: null,
       _schemaDelimiter: '',
       include: [Array],
       includeNames: [Array],
       includeMap: [Object],
       includeValidated: true,
       attributes: [Array],
       raw: true },
    isNewRecord: false,
    Tags: [ [Tag] ] },
  Service {
    dataValues: { id: 2, name: 'Restaurant Y', Tags: [Array] },
    _previousDataValues: { id: 2, name: 'Restaurant Y', Tags: [Array] },
    _changed: Set {},
    _options:
     { isNewRecord: false,
       _schema: null,
       _schemaDelimiter: '',
       include: [Array],
       includeNames: [Array],
       includeMap: [Object],
       includeValidated: true,
       attributes: [Array],
       raw: true },
    isNewRecord: false,
    Tags: [ [Tag] ] } ]

It seems like apollo is unable to handle this data, it does not query for the subsequent tags entity.似乎 apollo 无法处理此数据,它不会查询后续标签实体。

You should use instance.get method to get dataValues .您应该使用instance.get方法来获取dataValues

Model instances operate with the concept of a dataValues property, which stores the actual values represented by the instance. Model 实例使用dataValues属性的概念进行操作,该属性存储实例表示的实际值。

Then, you need to define alias: 'tags' for the model association since the graphql type object - service has the tags field.然后,您需要为 model 关联定义alias: 'tags' ,因为 graphql 类型为 object - service具有tags字段。 Make sure they are mapped correctly.确保它们被正确映射。

A working example using "sequelize": "^5.21.3" and "apollo-server": "^2.19.0" .使用"sequelize": "^5.21.3""apollo-server": "^2.19.0"的工作示例。

model.ts

import { sequelize } from '../../db';
import { Model, DataTypes } from 'sequelize';

class Service extends Model {}
Service.init(
  {
    id: {
      primaryKey: true,
      type: DataTypes.INTEGER,
      autoIncrement: true,
      allowNull: false,
    },
    name: DataTypes.STRING,
    slug: DataTypes.STRING,
  },
  { sequelize },
);

class Tag extends Model {}
Tag.init(
  {
    id: {
      primaryKey: true,
      type: DataTypes.INTEGER,
      autoIncrement: true,
      allowNull: false,
    },
    name: DataTypes.STRING,
  },
  { sequelize },
);

Service.belongsToMany(Tag, { through: 'Service_Tag', as: 'tags' });
Tag.belongsToMany(Service, { through: 'Service_Tag', as: 'services' });

(async function test() {
  try {
    await sequelize.sync({ force: true });
    //seed
    await Service.bulkCreate(
      [
        { name: 'Restaurant X', slug: 'a', tags: [{ name: 'restaurant' }, { name: 'b' }] },
        { name: 'Restaurant Y', slug: 'b', tags: [{ name: 'c' }] },
        { name: 'Restaurant Z', slug: 'c', tags: [{ name: 'restaurant' }] },
      ],
      { include: [{ model: Tag, as: 'tags' }] },
    );
  } catch (error) {
    console.log(error);
  }
})();

export { Service, Tag };

app.ts : app.ts

import { ApolloServer, gql } from 'apollo-server';
import * as models from './model';

const typeDefs = gql`
  type Tag {
    id: ID!
    name: String!
  }

  type Service {
    id: ID!
    name: String!
    slug: String!
    tags: [Tag!]!
  }

  type Query {
    findServicesByTag(tag: String!): [Service]!
  }
`;

const resolvers = {
  Query: {
    async findServicesByTag(_, { tag }, { models }) {
      const res = await models.Service.findAll({
        where: {
          '$tags.name$': tag,
        },
        include: [
          {
            model: models.Tag,
            as: 'tags',
          },
        ],
      });
      const data = res.map((v) => v.get({ plain: true }));
      return data;
    },
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: {
    models,
  },
});

server.listen().then(({ url }) => {
  console.log(`🚀  Server ready at ${url}`);
});

Test GraphQl query using curl :使用curl测试 GraphQl 查询:

 ⚡  curl 'http://localhost:4000/graphql' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'Origin: chrome-extension://flnheeellpciglgpaodhkhmapeljopja' --data-binary '{"query":"\nquery{\n  findServicesByTag(tag: \"restaurant\"){\n    id\n    name\n    slug\n    tags {\n      \tname\n\t\t}\n  }\n}","variables":{}}' --compressed
{"data":{"findServicesByTag":[{"id":"1","name":"Restaurant X","slug":"a","tags":[{"name":"restaurant"}]},{"id":"3","name":"Restaurant Z","slug":"c","tags":[{"name":"restaurant"}]}]}}

Data records in the database:数据库中的数据记录:

node-sequelize-examples=# select * from "Service";
 id |     name     | slug 
----+--------------+------
  1 | Restaurant X | a
  2 | Restaurant Y | b
  3 | Restaurant Z | c
(3 rows)

node-sequelize-examples=# select * from "Tag";
 id |    name    
----+------------
  1 | restaurant
  2 | b
  3 | c
  4 | restaurant
(4 rows)
node-sequelize-examples=# select * from "Service_Tag";
 ServiceId | TagId 
-----------+-------
         1 |     1
         1 |     2
         2 |     3
         3 |     4
(4 rows)

暂无
暂无

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

相关问题 无法在续集中插入具有不可为空外键的行 - Unable to insert row with non-nullable foreign key in sequelize 为什么在执行更改时会收到“无法为不可为空的字段返回 null”错误? - Why am I getting a “Cannot return null for non-nullable field” error when doing a mutation? GraphQL 查询返回错误“不能为不可为空的字段返回空值” - GraphQL query returns error "Cannot return null for non-nullable field" GraphQL 错误:无法为不可为空的字段 Mutation.deleteComment 返回 null - GraphQL Error: Cannot return null for non-nullable field Mutation.deleteComment 让TS抱怨与非空字段的空比较? - Getting TS to complain about null comparison to a non-nullable field? 无法为 GraphQL 查询中的不可空字段返回 null - Cannot return null for non-nullable field in a GraphQL query Prisma API返回关系但客户端返回“不能为非可空字段返回null”。 - Prisma API returns relation but client returns “cannot return null for non-nullable field..” 为什么这会抛出“不能为不可为空的字段 Query.hello 返回 null。”? - Why does this throw "Cannot return null for non-nullable field Query.hello."? graphql 解析器返回 无法从 nodejs 中的异步 function 为非空字段返回 null - graphql resolver return Cannot return null for non-nullable field from asynchronous function in nodejs 为什么 graphql 返回“不能返回 null of non-nullable field mutation.createAccnt” - why is graphql returning “cannot return null of non-nullable field mutation.createAccnt”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM