使用 MongoDB 时的 Graphql 接口
Posted
技术标签:
【中文标题】使用 MongoDB 时的 Graphql 接口【英文标题】:Graphql Interfaces when using MongoDB 【发布时间】:2021-04-03 19:10:13 【问题描述】:我正在想办法使用 MongoDB 创建一个 GraphQL API,并且我正在尝试了解接口。
我明白了它背后的想法并观看了一堆关于谈话和操作方法的视频,但我看到的一件事是如何制作查询解析器。
总是这样显示:groups: () => ...
groups
将列在查询类型中,因此需要 mongodb 查询。
这是我需要找到答案的解析器:
...
里面有什么?
Query:
groups: () => ... ,
families: () => Family.find(),
members: () => Member.find(),
,
我认为我在查询时遇到的问题是:“由于groups
不是 mongodb 文档,查询会是什么?”
更多信息:
这里是完整的 typedef
export const typeDefs = gql`
interface Group
id: ID!
name: String!
type Family implements Group
id: ID!
name: String! # persons family name
numberOfPeople: Int
type Member implements Group
id: ID!
name: String! # persons first name
age: Int!
type Query
groups: [Group]
families: [Family]
members: [Member]
这是解析器
export const resolvers =
Group:
__resolveType(group, context, info)
if(group.family)
return 'Family';
if(group.member)
return 'Member';
return null;
,
,
Query:
groups: () => ... ,
families: () => Family.find(),
members: () => Member.find(),
这个想法是 Family
和 Member
是保存数据的单独文档,Group
是创建组合它们的查询的接口。
【问题讨论】:
【参考方案1】:编辑:我重新阅读了您的帖子,您在此处尝试访问的内容可能不存在。
因为在__resolveType
,您正在针对架构属性进行验证。
// Group:
__resolveType(group, context, info)
if(group.family) // property family is not defined in a group implementation.
return 'Family';
if(group.member)
return 'Member';
return null;
,
,
您可能希望对来自实现的家庭或成员的定义的唯一属性执行验证,如下所示:
// Group:
__resolveType(group, context, info)
if(group.numberOfPeople)
return 'Family';
if(group.age)
return 'Member';
return null;
,
,
然后当你查询组时。
`
groups
id
name
... on Family
numberOfPeople
... on Member
age
`
apollo docs reference
获取自动生成的接口和类型。
我找到了使用 graphql-code-generator 从您的架构中自动获取 TS 类型的最佳方法。它还有一个插件可以获取automatically generated mongoDB models
如需快速回复,请粘贴您的架构here。
快速设置打字稿:
-
安装
npm i -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-resolvers
它将安装 cli 和 typescript + typescript-resolvers 插件。
-
在您的根目录中创建
codegen.yml
并输入:
overwrite: true
schema: 'http://localhost:3500/graphql'
generates:
src/utils/codegen/graphql.ts:
plugins:
- 'typescript'
- 'typescript-resolvers'
-
执行命令:
graphql-codegen --config codegen.yml --watch src/**/*.ts
-
现在您可以执行以下操作:
// Import the types of your generated ts file.
import MutationResolvers, QueryResolvers, Resolvers from '@/utils/codegen/graphql'
const Query: QueryResolvers =
players: () => players
const Mutation: MutationResolvers =
updatePlayer: () => player
const resolvers: Resolvers =
Query,
Mutation
;
export default resolvers;
截图示例:
intellisense and autocomplete
proper validation
【讨论】:
【参考方案2】:对于任何提出这个问题的人 - 这是我必须放在 Query ...
中的代码
实际上是执行数据库查询的函数。
Groups
表示复数返回,
Group
用于单数返回
groups: async () =>
let types = mongoose.modelNames()
let total = []
for(let t of types)
let temp = await mongoose.model(t).find()
total.push(temp)
let flat = total.flat()
return flat
,
group: (_, id ) =>
return mongoose.modelNames().map(async mn =>
if (await mongoose.model(mn).exists("_id": ObjectID(id)))
return mongoose.model(mn).findOne("_id": ObjectID(id))
)
,
【讨论】:
以上是关于使用 MongoDB 时的 Graphql 接口的主要内容,如果未能解决你的问题,请参考以下文章
如何在不创建 Mongoose 模型的情况下将 GraphQL 与 Mongoose 和 MongoDB 一起使用
规范化 MongoDB/Mongoose,以简化 GraphQL Schema?
GraphQL 如何使用 Nestjs 或 type-graphql 设置查询 MongoDB ref 集合