简体   繁体   English

graphql-具有不同参数的相同查询

[英]graphql- same query with different arguments

Can the below be achieved with graph ql: we have getusers() / getusers(id=3) / getusers(name='John) .可以使用图形 ql 实现以下内容:我们有getusers() / getusers(id=3) / getusers(name='John) Can we use same query to accept different parameters (arguments)?我们可以使用相同的查询来接受不同的参数(参数)吗?

I assume you mean something like:我假设你的意思是这样的:

type Query {
    getusers: [User]!
    getusers(id: ID!): User
    getusers(name: String!): User
}

IMHO the first thing to do is try.恕我直言,首先要做的是尝试。 You should get an error saying that Query.getusers can only be defined once, which would answer your question right away.您应该收到一条错误消息,指出Query.getusers只能定义一次,这将立即回答您的问题。

Here's the actual spec saying that such a thing is not valid: http://facebook.github.io/graphql/June2018/#example-5e409这是实际规范说这样的事情是无效的: http : //facebook.github.io/graphql/June2018/#example-5e409

Quote:引用:

Each named operation definition must be unique within a document when referred to by its name.每个命名操作定义在通过其名称引用时在文档中必须是唯一的。

Solution解决方案

From what I've seen, the most GraphQL 'y way to create such an API is to define a filter input type, something like this:根据我所见,创建此类 API 的最GraphQL方法是定义过滤器输入类型,如下所示:

input UserFilter {
    ids: [ID]
    names: [String]
}

and then:进而:

type Query {
    users(filter: UserFilter)
}

The resolver would check what filters were passed (if any) and query the data accordingly.解析器将检查通过了哪些过滤器(如果有)并相应地查询数据。

This is very simple and yet really powerful as it allows the client to query for an arbitrary number of users using an arbitrary filter.这非常简单但非常强大,因为它允许客户端使用任意过滤器查询任意数量的用户。 As a back-end developer you may add more options to UserFilter later on, including some pagination options and other cool things, while keeping the old API intact.作为后端开发人员,您可以稍后向UserFilter添加更多选项,包括一些分页选项和其他很酷的东西,同时保持旧 API 不变。 And, of course, it is up to you how flexible you want this API to be.而且,当然,这取决于您希望此 API 有多灵活。

But why is it like that?但为什么会这样呢?

Warning!警告! I am assuming some things here and there, and might be wrong.我在这里和那里假设了一些事情,可能是错误的。

GraphQL is only a logical API layer, which is supposed to be server-agnostic. GraphQL 只是一个逻辑 API 层,它应该是与服务器无关的。 However, I believe that the original implementation was in JavaScript ( citation needed ).但是,我相信最初的实现是在 JavaScript 中(需要引用)。 If you then consider the technical aspects of implementing a GraphQL API in JS, you might get an idea about why it is the way it is.如果您随后考虑在 JS 中实现 GraphQL API 的技术方面,您可能会了解为什么会这样。

Each query points to a resolver function.每个查询都指向一个解析器函数。 In JS resolvers are simple functions stored inside plain objects at paths specified by the query/mutation/subscription name.在 JS 中,解析器是简单的函数,它们存储在由查询/变异/订阅名称指定的路径中的普通对象中。 As you may know, JS objects can't have more than one path with the same name.您可能知道,JS 对象不能有多个同名的路径。 This means that you could only define a single resolver for a given query name, thus all three getusers would map to the same function Query.getusers(obj, args, ctx, info) anyway.这意味着您只能为给定的查询名称定义一个解析器,因此无论如何,所有三个getusers都会映射到同一个函数Query.getusers(obj, args, ctx, info)

So even if GraphQL allowed for fields with the same name, the resolver would have to explicitly check for whatever arguments were passed, ie if (args.id) { ... } else if (args.name) { ... } , etc., thus partially defeating the point of having separate endpoints.因此,即使 GraphQL 允许具有相同名称的字段,解析器也必须明确检查传递的任何参数,即if (args.id) { ... } else if (args.name) { ... } ,等等,从而部分地击败了具有单独端点的点。 On the other hand, there is an overall better (particularly from the client's perspective) way to define such an API, as demonstrated above.另一方面,有一种总体上更好的方式(特别是从客户的角度来看)来定义这样的 API,如上所示。

Final note最后说明

GraphQL is conceptually different from REST, so it doesn't make sense to think in terms of three endpoints (/users, /users/:id and /users/:name), which is what I guess you were doing. GraphQL 在概念上与 REST 不同,因此从三个端点(/users、/users/:id 和 /users/:name)的角度来思考是没有意义的,我猜你正在这样做。 A paradigm shift is required in order to unveil the full potential of the language.为了揭示语言的全部潜力,需要进行范式转变。

a request of the type works:该类型的请求有效:

Query {
    first:getusers(), 
    second:getusers(id=3)
    third:getusers(name='John)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM