Представьте себе запрос GraphQL следующим образом:
Query {
projects(platforms: [String], languages: [String])
}
И граф Neo4j, содержащий узлы, помеченные Project
, Platform
и Language
.
Когда ни один из необязательных аргументов не передан, распознаватель должен вернуть список всех проектов в графе без фильтрации (возможно, с разбиением на страницы в будущем). Когда один или все аргументы переданы, они должны быть применены в базовом запросе; то есть мы должны получить проекты, которые реализованы на данных языках или для данных платформ.
Я использую драйвер Bolt.Sips для Neo4j в своем бэкэнде Elixir, и этот драйвер предлагает минимальные функциональные возможности для переноса языка запросов Cypher, поэтому по большей части мне нужно писать запросы самостоятельно. Пока у меня есть эта реализация преобразователя, поскольку мне еще предстоит реализовать второй аргумент:
def get_projects!(_parent, %{languages: _} = args, _resolution) do
"""
match (node:Project)<-[:LANGUAGE_FOR]-(l:Language)
where l.name in {props}.languages
return node
"""
|> generic_query!(%{props: args})
end
def get_projects!(_parent, _args, _resolution) do
get_all_entities_of_type!("Project")
end
, где generic_query!/2
и get_all_entities_of_type!/1
- просто оболочки для выполнения запроса Bolt.Sips.
Мой вопрос: каков наилучший способ построения запроса Cypher в этом случае? Должен ли я просто написать набор функций, которые будут создавать строку запроса перед выполнением? Может быть, это просто мое общее отсутствие опыта GraphQL, и схемы запросов, подобные этой, должны создаваться по-другому? Любые советы будут оценены.