如何构造我的graphql模式,以允许检索可能的下拉值?

时间:2019-08-15 23:00:17

标签: graphql

我正在尝试从我的graphQL api中获取多个下拉菜单的可能值。

例如,说我有一个类似的架构:

type Employee {
  id: ID!
  name: String!
  jobRole: Lookup!
  address: Address!
}

type Address {
  street: String!
  line2: String
  city: String!
  state: Lookup!
  country: Lookup!
  zip: String!
}

type Lookup {
  id: ID!
  value: String!
}

jobRole 城市都是具有预定值列表的字段,这些值在应用程序周围的各种下拉菜单中都是必需的

在这种情况下,模式设计的最佳实践是什么?我正在考虑以下选项:

query {
  lookups {
    jobRoles {
      id
      value
    }
  }
}

这具有数据驱动的优点,因此我可以更新我的工作角色而不必更新我的架构,但是我看到这变得麻烦。我仅添加了一些业务对象,并且在我的模式中已经有大约25种不同类型的查找,并且随着向API中添加更多数据,我将需要以某种方式维护用于正确字段的正确查找,处理在多个地方使用的常规查询与仅适用于一个字段的超特定查询等。

是否还有其他人遇到过类似的问题,是否有一个很好的设计模式来解决?

出于记录原因,出于两个原因,我不想使用带有自省的枚举。

  1. 由于现有数据中的查找数量众多,因此需要非常频繁的模式更新
  2. 有了一个枚举,您只会得到一个值,我需要一个将用作数据库中主键的代码和一个将在UI中显示的描述性值。
//bad
enum jobRole {
  MANAGER
  ENGINEER
  SALES
}
//needed
[
  {
    id: 1,
    value: "Manager"
  },
  {
    id: 2,
    value: "Engineer"
  },
  {
    id: 3,
    value: "Sales"
  }
]

编辑 我想举一个为什么枚举可能无法正常工作的例子。我们有很多描述,这些描述应该出现在包含特殊字符的下拉列表中。

// Client Type
[
  {
    id: 'ENDOW',
    value: 'Foundation/Endowment'
  },
  {
    id: 'PUBLIC',
    value: 'Public (Government)'
  },
  {
    id: 'MULTI',
    value: 'Union/Multi-Employer'
  }
]

还有其他一些更糟糕的情况,它们具有<,>,%等。其中一些是完整的句子,因此在这种情况下,枚举的限制性命名确实不起作用。我倾向于只进行一堆查询查询并将每个查询视为一个独立的业务对象

2 个答案:

答案 0 :(得分:0)

如果需要,您仍然可以使用枚举。

  1. 内省查询可以像在其他查询中一样在客户端使用。根据您在服务器端使用哪种实现/框架,您可能必须在生产中显式启用自省功能。您的客户端可以在应用加载时查询可能的枚举值-不管架构更改了多少次,客户端都将始终显示正确的枚举值。
  2. 枚举值不限于所有大写字母,尽管它们不能包含空格。因此,您可以拥有 $credentials = ['email' => $request->username, 'password' => $request->password]; //Since we are not using guard web in API request, we have to add it here ( // guard('web') ) to access the Auth::attempt function, // the Auth::attempt needs web guard and crsf token, but using it here bypasses // the post with crsf. if (Auth::guard('web')->attempt($credentials, false, false)) { dd('user is OK'); }else{ dd('user is NOT OK'); } ,但不能拥有Engineer。也就是说,如果用下划线代替空格,则可以转换客户端的值。
  3. 我无法使用非JavaScript实现,但是GraphQL.js支持为每个枚举值分配一个Human Resources属性。此属性仅在内部使用。例如,如果您收到枚举作为参数,则将得到value而不是2。同样,您将在解析器中返回Engineer而不是2。您可以看到如何使用Apollo Server here完成此操作。

答案 1 :(得分:0)

我找到了一种使枚举按我需要的方式工作的方法。我可以将其放入description

这是我的gql模式定义

enum ClientType {
    """
    Public (Government)
    """
    PUBLIC
    """
    Union/Multi-Employer
    """
    MULTI
    """
    Foundation/Endowment
    """
    ENDOW
}

当我像这样进行内省查询时检索到

{
  __type(name: "ClientType") {
    enumValues {
      name
      description
    }
  }
}

我得到的数据与我正在寻找的确切结构相同!

{
    "data": {
        "__type": {
            "enumValues": [{
                "name": "PUBLIC",
                "description": "Public (Government)"
            }, {
                "name": "MULTI",
                "description": "Union/Multi-Employer"
            }, {
                "name": "ENDOW",
                "description": "Foundation/Endowment"
            }]
        }
    }
}

正是我需要的。我可以使用在说明中找到的所有特殊字符,数字等。如果有人想知道如何使我的架构与数据库保持同步,我有一个简单的代码生成脚本,该脚本查询存储此信息的表并生成一个导出所有这些枚举的enums.ts文件。每当数据更新时(这种情况很少发生),我只要重新运行代码生成器并将模式更改发布到生产中即可。