Как создать схему graphql, которую можно искать в разных полях?
Я тестирую Сангрию, чтобы построить сервер GraphQL / Relay. У меня очень простой пользовательский класс:
case class User(
id: Int,
username: String,
gender: Gender.Value)
Я хочу разрешить запросы по идентификатору или имени пользователя. Я создал схему, которая позволяет это, но поля имеют разные имена:
val Query = ObjectType(
"Query", fields[UserRepo, Unit](
Field("user", OptionType(User),
arguments = ID :: Nil,
resolve = ctx => ctx.ctx.getUser(ctx arg ID)),
Field("userByUsername", OptionType(User),
arguments = Username :: Nil,
resolve = ctx => ctx.ctx.getUserByUsername(ctx arg Username))
))
К сожалению, мне нужно запросить их с разными именами полей, user
а также userByUsername
Например:
curl -G localhost:8080/graphql
--data-urlencode 'query={userByUsername(username: "Leia Skywalker") {id, username, gender}}'
или же
curl -G localhost:8080/graph
--data-urlencode "query={user(id: 1025) {id, username, gender}}"
Как я могу создать схему, которая позволяет одно поле с именем user
быть опрошен либо на ID или имя пользователя? Например, оба следующих элемента должны возвращать один и тот же объект пользователя:
curl -G localhost:8080/graphql
--data-urlencode 'query={user(username: "Leia Skywalker") {id, username, gender}}'
или же
curl -G localhost:8080/graph
--data-urlencode "query={user(id: 1025) {id, username, gender}}"
1 ответ
Я наконец-то решил это:
val ID = Argument("id", OptionInputType(IntType), description = "id of the user")
val Username = Argument("username", OptionInputType(StringType), description = "username of the user")
val Query = ObjectType(
"Query", fields[UserRepo, Unit](
Field("user", OptionType(User),
arguments = List(ID, Username),
resolve = ctx => ctx.ctx.getUser(ctx.argOpt(ID), ctx.argOpt(Username)))
))
А также getUser
похоже:
def getUser(id: Option[Int], username: Option[String]): Option[User] = {
if (id.isEmpty && username.isEmpty) {
None
}
else {
id.flatMap(i => users.find(_.id == i))
.orElse(username.flatMap(u => users.find(_.username == u)))
}
}