graphql + mongoose + typescript,如何减少重复的模型定义

Posted

技术标签:

【中文标题】graphql + mongoose + typescript,如何减少重复的模型定义【英文标题】:graphql + mongoose + typescript, how to reduce model definition duplicated 【发布时间】:2019-01-15 08:01:35 【问题描述】:

我使用mongoosetypescriptgraphql 来构建我的应用程序。

我是一名全栈开发人员。

问题是我定义了模型的字段和类型五次次。

服务器端:

models/book.ts:

// first time
interface IBook extends mongoose.Document 
  title: string;
  author: string;
 

// second time
const bookSchema = new mongoose.Schema(
  title: String,
  author: String
)

const Book: mongoose.Model<IBook> = mongoose.model<IBook>('Book', bookSchema)

graphql/typeDefs.ts

const typeDefs = `
  // third time
  type Book 
    title: String!
    author: String!
  

  // fourth time
  input BookInput 
    title: String!
    author: String!
  
`

客户端:

interfaces/book.ts

// fifth time
interface IBook 
  title: string;
  author: string;

如您所见。 titleauthor 字段和类型被定义 五次 次。

主要有三个缺点:

    重复 缺乏可维护性 效率低下

有没有办法解决这个问题?我认为这几乎是一个 DRY 问题。

以下是我的想法:

    通用应用程序 - 提取客户端和服务器端使用的一些常用模块。

    制作一个工具来处理这个。

    制作一个项目生成器或命令行工具,例如ng-cli,用于静态生成模型和类型,这意味着在运行时之前

    使模型定义decoratorsyntax sugar 在运行时动态生成模型和类型

【问题讨论】:

还有解决办法吗?我喜欢使用 TypeScript 和 Mongoose,但我是 GraphQL 新手,这是我脑海中出现的第一个问题。 @kit 还没有。仍然没有找到处理这些“重复”代码的解决方案。 分别维护 mongoose 模式和 graphql 模式,因为它们具有不同的数据类型。使用 javascript 对象避免在 mongoose 中重复,使用 Types 避免在 GraphQL 中重复。 我找到了一个模块typegraphql.ml,它对我来说已经足够有用了 到目前为止,这个插件是我发现的最好的东西:graphql-code-generator.com/docs/getting-started 看起来它可以处理 graphql/typescript 重复。不幸的是,目前没有 mongoose 插件,但是有一个 MongoDB 插件。我将开始研究如何使用它来制作架构。 【参考方案1】:

我们最近遇到了这个问题,要求我们在 Mongoose 架构旁边维护一个重复的 Typescript 界面(对我们来说,这个问题完全是服务器端的,因为我们没有使用 graphql 或客户端 Typescript)

我们构建了mongoose-tsgen 来解决这个问题。它可能无法处理此处涉及的所有情况,但可以轻松引导以处理您的用例。

它会读取您的 Mongoose 模式并生成一个 index.d.ts 文件,其中包括每个文档和子文档的接口。这些接口可以直接从 mongoose 模块导入,如下所示:

import  IUser  from "mongoose"

async function getUser(uid: string): IUser 
  // `user` is of type IUser
  const user = await User.findById(uid)
  return user;


【讨论】:

【参考方案2】:

如果有人仍然想知道,

您可以将 TypeGraphQL 与 Typegoose 一起使用,使用如下装饰器在一个类中创建所有模式:

@ObjectType()
export class Book

@Field() @prop( required: true )
title!: string;

@Field() @prop( required: true )
name!: string;

【讨论】:

以上是关于graphql + mongoose + typescript,如何减少重复的模型定义的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL错误返回mongoose聚合命令的结果

GraphQL、Relay 和 Mongodb (mongoose) 如何获取数组

使用多个装饰器将 Type-GraphQL 与 Typegoose 相结合

用于特定模式的 Apollo graphql typedef

如何使用 graphql 和 mongoose 进行突变

NestJS + Mongoose + GraphQL:“填充”不起作用