SpringBoot GraphQL字段名称不匹配

nuypyhwy  于 2024-01-06  发布在  Spring
关注(0)|答案(2)|浏览(175)

似乎.graphqls文件中定义的名称必须与POJO中的字段名称匹配。有没有一种方法可以注解字段,这样它们就不必这样做了?
例如,我在graphqls文件中有这样的内容

  1. type Person {
  2. personId: ID!
  3. name: String!
  4. }

字符串
在我的实体POJO中,

  1. @Id
  2. @Column(name="PERSON_ID")
  3. @JsonProperty("person_id")
  4. private int personId;
  5. @Column(name="NAME")
  6. @JsonProperty("name")
  7. private String name;


因此,目的是将字段名设置为personId,数据库将其存储为名为PERSON_ID的列,并将其序列化为JSON,GraphQL为person_id
但是graphql是用schema的语言进行通信的。所以它将其序列化为personId,这与schema字段匹配,但这不是目的。我可以将schema更改为person_id,但我也需要更改字段.这不是世界末日,但以这种方式命名字段是相当“un-javalike”的。
我正在使用这个库:

  1. compile group: 'com.graphql-java', name: 'graphql-spring-boot-starter', version: '5.0.2'


我还在注解库中看到了@GraphQLName注解,但我肯定漏掉了什么,因为它没有达到我的预期,或者我用错了。
有什么办法可以解决这个问题吗?或者我应该换个名字?

pw136qt2

pw136qt21#

GraphQL Java默认使用PropertyDataFetcher来解析字段值(参见data fetching section in the docs)。当顶级字段数据提取器返回的数据对象包含与数据对象属性名称匹配的子字段时,此数据提取器可以开箱即用。
但是,您可以为任何字段定义自己的数据提取器,并使用您需要的任何规则。
如果你想要一个像这样的模式

  1. type Person {
  2. person_id: ID!
  3. name: String!
  4. }

字符串
你的实体是这样的:

  1. class Person {
  2. private int personId;
  3. private String name;
  4. // getters and setters
  5. }


您可以为字段personId编写一个简单的自定义数据提取器

  1. private RuntimeWiring buildWiring() {
  2. return RuntimeWiring.newRuntimeWiring()
  3. // query root data fetchers wiring
  4. .type(newTypeWiring("Person")
  5. .dataFetcher("person_id", environment -> {
  6. Person person = environment.getSource();
  7. return person.getPersonId();
  8. })
  9. )
  10. // maybe other wirings
  11. .build();
  12. }

展开查看全部
a0zr77ik

a0zr77ik2#

您可以始终定义WiringFactory并提供默认的DataFetcher。在此示例中,新的DataFetcher使用反射来查找具有与字段名称匹配的JsonProperty注解的方法。如果没有,则使用内置的PropertyDataFetcher。

  1. @Bean
  2. public RuntimeWiringConfigurer runtimeWiringConfigurer() {
  3. return wiringBuilder -> wiringBuilder
  4. .wiringFactory(new WiringFactory() {
  5. @Override
  6. public DataFetcher<Object> getDefaultDataFetcher(FieldWiringEnvironment fieldWiringEnvironment) {
  7. return dataFetchingEnvironment -> Arrays.stream(dataFetchingEnvironment.getSource().getClass().getDeclaredMethods()).filter(
  8. method -> (method.getName().contains("get") && method.getAnnotation(JsonProperty.class).value().equals(dataFetchingEnvironment.getField().getName()))
  9. ).map(
  10. method -> {
  11. try {
  12. return method.invoke(dataFetchingEnvironment.getSource());
  13. } catch (IllegalAccessException | InvocationTargetException e) {
  14. throw new UncheckedExecutionException(e);
  15. }
  16. }
  17. ).findAny().orElseGet(
  18. () -> new PropertyDataFetcher<>(dataFetchingEnvironment.getField().getName()).get(dataFetchingEnvironment)
  19. );
  20. }
  21. })
  22. .scalar(buildObjectScalar());
  23. }

字符串

展开查看全部

相关问题