具有特定 id 值的嵌套 GraphQL 查询是否可行?

Rob*_*_LY 7 graphql

我已经成功构建了一个允许嵌套查询的 GraphQL API。使用国家和州的通用示例,我可以执行如下查询:

    query{
      country(id:"Q291bnRyeTo0Nw==") {
        states {
          edges {
            node {
              id,
              name,
              area,
              population
            }
          }
        }
       }
     }
Run Code Online (Sandbox Code Playgroud)

我发现我似乎无法做到的是:

query{
      country(id:"Q291bnRyeTo0Nw==") {
        state(id:"U3RhdGU6MzM=") {
          edges {
            node {
              id,
              name,
              area,
              population
            }
          }
        }
      }
    }
Run Code Online (Sandbox Code Playgroud)

GraphQL 是否有办法在一个查询中指定特定的父项和特定的子项?

罗伯特

更新:为了 Da​​niel 的利益,这是我当前的 GraphQL 查询代码:

from .models import Country as CountryModel
from .models import State as StateModel

class Query(graphene.AbstractType):

    country = graphene.Field(Country, id=graphene.String())
    countries = graphene.List(Country)

    state = graphene.Field(State, id=graphene.String())
    states = graphene.List(State)

    def resolve_country(self, args, context, info):
        id = args.get('id')

        if id is not None:
            return CountryModel.objects.get(id=Schema.decode(id))
    
        return None

    def resolve_countries(self, args, context, info):
        return CountryModel.objects.all()

    def resolve_state(self, args, context, info):
        id = args.get('id')

        if id is not None:
            return StateModel.objects.get(id=Schema.decode(id))
    
        return None

    def resolve_states(self, args, context, info):
        return StateModel.objects.all()
Run Code Online (Sandbox Code Playgroud)

Dan*_*den 8

您需要为countryRoot Query 上的state字段和 Country 类型上的字段定义一个解析器。这是一个示例,您可以将其复制并粘贴到Launchpad 中并查看它的运行情况。

像 Graphene 这样的设置会有点不同,但想法是一样的:country查询返回的对象对于state类型下的每个字段都可用于解析器。您使用id传递给state字段的参数来过滤该对象上的数据(在本例中,返回的对象具有一个states属性)并返回适当的状态。

import { makeExecutableSchema } from 'graphql-tools';

const countries = [
  {
    id: 1,
    name: 'bar',
    states: [
      {
        name: 'foo',
        id: 20
      }
    ]
  },
  { id: 2 },
];

const typeDefs = `
  type Query {
    country(id: Int!): Country
  }
  type Country {
    id: Int
    state(id: Int!): State
  }
  type State {
   id: Int
   name: String
  }
`

const resolvers = {
  Query: {
    country: (obj, args, context) => {
      return countries.find(country => country.id === args.id)
    },
  },
  Country: {
    state: (obj, args, context) => {
      return obj.states.find(state => state.id === args.id)
    },
  }
}

export const schema = makeExecutableSchema({
  typeDefs,
  resolvers,
})
Run Code Online (Sandbox Code Playgroud)

编辑:假设返回的对象CountryModel.objects.get(id=Schema.decode(id))包含一个states状态列表属性,您应该能够执行以下操作:

class Country(graphene.ObjectType):
  state = graphene.Field(State,
                          id=graphene.String()
                          )
  # other fields
  def resolve_state(self, args, context, info):
    id = args.get('id')
    if id is not None:
        return list(filter(lambda x: x.id == id, self.states)
    return None
Run Code Online (Sandbox Code Playgroud)