使用 Graphql-js 模式克服代码重复

Posted

技术标签:

【中文标题】使用 Graphql-js 模式克服代码重复【英文标题】:Overcoming code duplication with Graphql-js schemas 【发布时间】:2019-05-03 23:21:27 【问题描述】:

我正在使用 GraphQL-Js 和 Mongo 学习 GraphQL。

我发现 GraphQL 模式存在大量代码重复。

我的 GraphQL 输入对象如下所示:

const PricingInputType = new GraphQLInputObjectType(
  name: 'PricingInput',
  fields: () => (
    expires:  type: GraphQLInt ,
    private:  type: GraphQLBoolean ,
    monthly:  type: GraphQLInt ,
    scanEnvelope:  type: GraphQLInt ,
    initalScan:  type: GraphQLInt ,
    perPage:  type: GraphQLInt ,
    forwardMail:  type: GraphQLInt ,
    forwardParcel:  type: GraphQLInt ,
    shred:  type: GraphQLInt ,
    perMonthPerGram:  type: GraphQLInt ,
    freeStorePerGram:  type: GraphQLInt ,
    setup:  type: GraphQLInt ,
    idFree:  type: GraphQLInt 
  )
);

const PlanInputType = new GraphQLInputObjectType(
  name: 'PlanInput',
  fields: () => (
    id:  type: GraphQLString ,
    planName:  type: GraphQLString ,
    pricing:  type: PricingInputType 
  )
);

const Mutation = new GraphQLObjectType(
  name: 'Mutation',
  fields: 
      addPlan: 
          type: PlanType,
          args: 
            Plan:  type: PlanInputType 
          ,
          resolve(parent, args)
            //TO DO. UPSERT TO MONGO
              return true;
          
      
    
);

我的查询对象如下所示:

const PricingType = new GraphQLObjectType(
  name: "Pricing",
  fields: () => (
    expires:  type: GraphQLInt ,
    private:  type: GraphQLBoolean ,
    monthly:  type: GraphQLInt ,
    scanEnvelope:  type: GraphQLInt ,
    initalScan:  type: GraphQLInt ,
    perPage:  type: GraphQLInt ,
    forwardMail:  type: GraphQLInt ,
    forwardParcel:  type: GraphQLInt ,
    shred:  type: GraphQLInt ,
    perMonthPerGram:  type: GraphQLInt ,
    freeStorePerGram:  type: GraphQLInt ,
    setup:  type: GraphQLInt ,
    idFree:  type: GraphQLInt 
  )
);

const PlanType = new GraphQLObjectType(
  name: "Plan",
  fields: () => (
    id:  type: GraphQLString ,
    planName:  type: GraphQLString ,
    pricing:  type: PricingType 
  )
);

const RootQuery = new GraphQLObjectType(
  name: "RootQueryType",
  fields: 
    plans: 
      type: new GraphQLList(PlanType),
      resolve(parent, args) 
        return Plans.find();
      
    
  
);

现在我的 Mongo 架构如下所示:

var plansSchema = new Schema(
  planName:  
    type: String,
    required: [true, "Plan name is required"]
  ,
  pricing: 
    monthly: Number,
    scanEnvelope: Number,
    initalScan: Number,
    perPage: Number,
    forwardMail: Number,
    forwardParcel: Number,
    shred: Number,
    perMonthPerGram: Number,
    freeStorePerGram: Number,
    setup: Number,
    idFree: Number
  ,
  expires: Number,
  private: Boolean,
  deleted: Boolean,
  date:  type: Date, default: Date.now ,
);

module.exports =  mongoose.model('plans', plansSchema);

如您所见,我在 3 个地方复制了代码。如果我决定按季度而不是按月收费,我需要在 3 个地方更改 Monthly 属性!?

有更好的模式吗?或者这只是这样做的方法?

【问题讨论】:

【参考方案1】:

您可以查看我的answer 来回答类似的问题。它使用 package 依赖 GraphQL“查询对象”来生成其他所有内容,因此放弃 mongoose 直接使用 MongoDB。

【讨论】:

以上是关于使用 Graphql-js 模式克服代码重复的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 https://newsapi.org/ 克服 CORS 问题 [重复]

GraphQL 模式中的特殊字符

如何克服反模式“大泥球”?

在实现生产者/消费者模式时使用 Task.Yield 克服 ThreadPool 饥饿

GraphQL-js Node/Express:如何在 GraphQL 查询中传递字符串对象?

破折号巧妙地克服了重复的回调