2017-05-25 68 views
1

我对GraphQL非常新颖。我试图传递一个像这样的对象作为参数:GraphQL--传递非特定对象的对象作为参数

{ 
    filters: { 
    status: 'approved', 
    id: { 
     LESS_THAN: 200 
    } 
    } 
} 

或者这个对象可以是这样的;

{ 
    filters: { 
    status: ['approved', 'pending'], 
    id: 200 
    } 
} 

我知道所有的属性可以在这个对象,但所有这些属性可以是一个字符串/ int或一个对象。

我试图去定义它像这一点,但它显然没有奏效:

args: { 
    filters: { type: new GraphQLNonNull(new GraphQLNonNull(GraphQLString)) }, 
}, 

我试图定义一个GraphQL型GraphQLInputObjectType的说法。

const OffersFiltersType = new GraphQLInputObjectType({ 
    name: 'Filters', 
    description: '...', 
    fields:() => ({}) 
    id: { 
     type: new GraphQLNonNull({ 
     name: 'Id', 
     description: '...', 
     fields: { 

     } 
     }), 
     resolve: (offer) => offer.id 
    }, 
    }), 
}); 

但是我怎么能指定这种类型,我的id可以是一个int或一个对象?

这是我的查询定义:

const QueryType = new GraphQLObjectType({ 
    name: 'Query', 
    description: '...', 
    fields:() => ({ 
    offers: { 
     type: OffersType, 
     args: { 
     limit: { type: GraphQLInt }, 
     page: { type: GraphQLInt }, 
     sort: { type: GraphQLString }, 
     filters: { [HERE] } 
     }, 
     resolve: (root, args, context, info) => { 
     const gqlFields = graphqlFields(info); 
     const fields = Object.keys(gqlFields.offer); 
     const queryArgs = args; 

     queryArgs.fields = fields; 

     return getOffers(queryArgs); 
     } 
    }, 
    }), 
}); 

这是我用的SuperAgent

const getOffers = (args) => { 
    const queryArgs = args; 

    if (typeof queryArgs.limit !== 'undefined') { 
    queryArgs.limit = args.limit; 
    } else { 
    queryArgs.limit = Number.MAX_SAFE_INTEGER; 
    } 

    return new Promise((fulfill, reject) => { 
    request 
     .get(API_URL) 
     .query(qs.stringify(args)) 
     .end((err, res) => { 
     if (err) { 
      reject(err); 
     } 

     fulfill(res); 
     }); 
    }); 
}; 

我需要这个对象来构建我的决心功能的查询请求。感谢大家的帮助!我只需要简单的建议!

回答

1

这是不允许的,由设计:https://github.com/graphql/graphql-js/issues/303

GraphQL不支持未知属性名称,主要是因为它将使模式毫无意义。给出的例子是一个简单的拼写错误:

如果有查询query ($foo: String) { field(arg: $foo) }和变量{ "fooo": "abc" },目前我们将此标记为错误,但我们可能会错过这个错字,如果我们没有引发错误。

该模式旨在确保服务器和客户端之间的兼容性,即使在不同版本之间,并允许未知属性也会破坏该模式。

GraphQL-JS库中有一个merge request open for this,但它是still being debated,并且存在与拼写错误和一般不一致的问题。

返回原语或对象的想法会遇到类似的问题。在接受对象时,您需要列出您期望的属性,并且查询将针对该模式验证这些属性。必须提前知道属性及其类型和空值,以便您(和解析器)能够生成查询,并且在验证时肯定需要知道。

如果您可以接受基元或对象,则必须指定该对象上的字段,但这些字段不可能存在于基元上。这是一个问题。

+0

我知道所有的属性名称(我将它添加到我的问题),但我怎么能定义参数可以是一个int或一个对象? –

+0

对于数组,您应该要求该字段始终是一个数组,并且只需使用一个元素的数组。我不认为允许一个字段是一个原始对象或对象也是一个好主意,你可能需要它永远是一个对象,并使一些子字段可选。 – ssube