Циклические запросы GraphQL с отношениями один-ко-многим

Я изучаю GraphQL, создавая простое приложение на Python, в основном запускает сканирование nmap, сохраняет вывод в базу данных и может быть запрошен GraphQL API. Кажется, я немного запутался в том, как работает GraphQL.

У меня есть несколько таблиц, которые являются отношениями один-ко-многим: user has many scans, scans have results, results have hosts, hosts have ports, hosts have os. Что я определил с помощью sqlalchemy и использовал graphene

Теперь в моей схеме GraphQL у меня есть:

class Scans(SQLAlchemyObjectType):
    class Meta:
        model = ScansModel


class ScanResult(SQLAlchemyObjectType):
    class Meta:
        model = ScanResultModel


class Hosts(SQLAlchemyObjectType):
    class Meta:
        model = HostInfoModel


class Ports(SQLAlchemyObjectType):
    class Meta:
        model = PortInfoModel


class Os(SQLAlchemyObjectType):
    class Meta:
        model = OsInfoModel

class Query(graphene.ObjectType):
    user = graphene.Field(User)
    scans = graphene.List(Scans)
    scan_results = graphene.List(ScanResult)
    hosts = graphene.List(Hosts)
    ports = graphene.List(Ports)
    os = graphene.Field(Os)

    def resolve_scans(self, info):
        query = Scans.get_query(info)
        return query

Теперь, когда я делаю запрос GraphQL, я могу запрашивать сканирование, результаты, информацию о хосте, портинфо, osinfo, без необходимости иметь преобразователи для этих полей. У меня создалось впечатление, что для каждого из этих полей потребуется преобразователь.

Кроме того, мне кажется, что я могу выполнять циклические запросы (так что из scanresults я могу запросить scans, а из scans я могу запросить user) из-за внешних ключей и таблицы отношений.

Это правильное поведение, или я неправильно понимаю, как работает GraphQL?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Что такое Apollo Client и зачем он нужен?
Что такое Apollo Client и зачем он нужен?
Apollo Client - это полнофункциональный клиент GraphQL для JavaScript-приложений, который упрощает получение, управление и обновление данных в...
0
0
1 054
2

Ответы 2

Я знаю, что преобразователи для каждого поля с SQLAlchemyObjecType обрабатываются внутри библиотеки.

когда я использую mongoengine без использования MongoengineObjectType, я кодирую вот так.

class Query(graphene.ObjectType):

    department = graphene.List(of_type=DepartmentField,
                           name=graphene.String(default_value = "all"))

    role = graphene.List(of_type=RoleField,
                     name=graphene.String(default_value = "all"))

    employee = graphene.List(of_type=EmployeeField,
                         name=graphene.String(default_value = "all"))

    def resolve_department(self, info, name):
        if name == "all":
            department = [construct(DepartmentField, object) for object in DepartmentModel.objects]
            return department
        else:
            department = DepartmentModel.objects.get(name=name)
            return [construct(DepartmentField, department)]

    def resolve_role(self, info, name):
            .
            .
            .

Что вам нужно сделать:


class ScanResult(SQLAlchemyObjectType):
    class Meta:
        model = ScanResultModel

    scans = graphene.List(Scans, description = "Scans from results.")

    def resolve_scans(self, info):
        query = Scans.get_query(info)
        return query.filter(ScansModel.my_id == self.scans_id).all()

Это, вероятно, позволит вам создавать такие запросы, как:

{
  scanresult{
    edges {
      node {
         id
         scans{
            id
         }
      }
    }
}

Другие вопросы по теме