graphql +猫鼬+打字稿,如何减少重复的模型定义

时间:2018-08-08 06:46:53

标签: graphql graphql-js

我使用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在运行时动态生成模型和类型

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

也许结合使用typegoosegraphql-compose-mongoose可以达到目的吗?

答案 2 :(得分:0)

万一有人还在想,

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

@ObjectType()
export class Book{

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

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