【问题标题】:graphql + mongoose + typescript, how to reduce model definition duplicatedgraphql + mongoose + typescript,如何减少重复的模型定义
【发布时间】: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 字段和类型被定义 五次 次。

主要有三个缺点:

  1. 重复
  2. 缺乏可维护性
  3. 效率低下

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

以下是我的想法:

  1. 通用应用程序 - 提取客户端和服务器端使用的一些常用模块。
  2. 制作一个工具来处理这个。

    • 制作一个项目生成器或命令行工具,例如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 插件。我将开始研究如何使用它来制作架构。

标签: graphql graphql-js


【解决方案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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-21
      • 2018-01-18
      • 1970-01-01
      • 2016-01-12
      • 2021-09-10
      • 2019-02-03
      • 2018-06-22
      • 2019-03-30
      相关资源
      最近更新 更多