Можно ли достичь следующего с помощью графика ql:
у нас есть getusers() / getusers(id=3) / getusers(name='John). Можем ли мы использовать один и тот же запрос для приема разных параметров (аргументов)?


Я предполагаю, что вы имеете в виду что-то вроде:
type Query {
getusers: [User]!
getusers(id: ID!): User
getusers(name: String!): User
}
ИМХО первое, что нужно сделать, это попробовать. Вы должны получить сообщение об ошибке, в котором говорится, что Query.getusers можно определить только один раз, что сразу же ответит на ваш вопрос.
Вот фактическая спецификация, в которой говорится, что такая вещь недействительна: http://facebook.github.io/graphql/June2018/#example-5e409
Цитировать:
Each named operation definition must be unique within a document when referred to by its name.
Решение
Из того, что я видел, самый GraphQL'y способ создать такой API - это определить тип ввода фильтра, примерно так:
input UserFilter {
ids: [ID]
names: [String]
}
а потом:
type Query {
users(filter: UserFilter)
}
Сопоставитель проверит, какие фильтры были переданы (если есть), и запросит данные соответственно.
Это очень просто и в то же время очень мощно, поскольку позволяет клиенту запрашивать произвольное количество пользователей с помощью произвольного фильтра. Как внутренний разработчик, вы можете позже добавить в UserFilter дополнительные параметры, в том числе некоторые параметры разбивки на страницы и другие интересные вещи, сохранив при этом старый API. И, конечно же, вам решать, насколько гибким вы хотите, чтобы этот API был.
Но почему это так?
Предупреждение! Я предполагаю некоторые вещи здесь и там и могу ошибаться.
GraphQL - это всего лишь логический уровень API, который должен быть независимым от сервера. Однако я считаю, что исходная реализация была на JavaScript (нужна цитата). Если вы затем рассмотрите технические аспекты реализации GraphQL API в JS, вы можете понять, почему это так.
Каждый запрос указывает на функцию распознавателя. В преобразователях JS есть простые функции, хранящиеся внутри простых объектов по путям, указанным в имени запроса / мутации / подписки. Как вы, возможно, знаете, у JS-объектов не может быть более одного пути с одинаковым именем. Это означает, что вы можете определить только один преобразователь для данного имени запроса, поэтому все три getusers в любом случае будут отображаться на одну и ту же функцию Query.getusers(obj, args, ctx, info).
Таким образом, даже если GraphQL допускает поля с одинаковыми именами, преобразователь должен будет явно проверять, какие аргументы были переданы, то есть if (args.id) { ... } else if (args.name) { ... } и т. д., Тем самым частично нарушая идею наличия отдельных конечных точек. С другой стороны, есть в целом лучший (особенно с точки зрения клиента) способ определения такого API, как показано выше.
Заключительное примечание
GraphQL концептуально отличается от REST, поэтому нет смысла думать о трех конечных точках (/ users, / users /: id и / users /: name), что, как я полагаю, вы делали. Требуется смена парадигмы, чтобы раскрыть весь потенциал языка.
запрос типа работает:
Query {
first:getusers(),
second:getusers(id=3)
third:getusers(name='John)
}