Как реализовать запрос с аргументами для поля пользовательского типа

Я хочу реализовать разбиение на страницы в полях настраиваемого типа с использованием аргументов.

Используя примерную схему, подобную этой:

      type Book {
    title: String!
    year: Int!
}

type Author {
    name: String!
    books(page: Int, size: Int, sort: String): [Book!]!
}

type Query {
    allAuthors: [Author!]!
}

Как реализовать запрос наbooks(page: Int, size: Int, sort: String): [Book!]!с Spring GraphQL? Я знаю, что запросы для типаQueryреализованы в аннотированном классе с аннотированными методами, но, похоже, это не работает для моей передачи данныхAuthorDtoсорт.

Приложение не выдает исключение или предупреждение при запуске или во время выполнения, но использование запроса просто дает мне общую ошибку, сообщающую мне, что оно не реализовано.

      {
  "errors": [
    {
      "message": "The field at path '/allAuthors[0]/books' was declared as a non null type, but the code involved in retrieving data has wrongly returned a null value.  The graphql specification requires that the parent field be set to null, or if that is non nullable that it bubble up null to its parent and so on. The non-nullable type is '[Book!]' within parent type 'Author'",
      "path": [
        "allAuthors",
        0,
        "books"
      ],
      "extensions": {
        "classification": "NullValueInNonNullableField"
      }
    }
  ],
  "data": null
}

Я пытался использовать@SchemaMappingв объекте передачи данных вот так:

      data class AuthorDto(
   private val author: Author // author is the actual Author model class
) {

   val name: Int
       get(): author.name

    @SchemaMapping(typeName = "Author", field = "books")
    fun getBooks(
        @Argument page: Int? = null,
        @Argument size: Int? = null,
        @Argument sort: String? = null,
    ): List<Book> {
        // my implementation for creating the list with pagination
    }
}

Однако Spring, похоже, не подбирает реализацию. Поскольку этот класс использует мою модель данныхAuthorкласс в конструкторе (как в примере https://github.com/spring-projects/spring-graphql/blob/1.0.x/samples/webmvc-http/src/main/java/io/spring/sample/graphql/project/Project.java), я не могу аннотировать его с помощью@Controllerи делать это тоже не имело бы никакого смысла для меня в первую очередь.

Я использую Kotlin, но был бы признателен за решения о том, как это сделать на Java.

1 ответ

Чтобы реализовать запросallAuthorsс Spring для GraphQL у вас должен быть следующий метод в вашем@Controller-аннотированный класс:

      @Controller
public class MyGraphqlController {
    @QueryMapping
    List<AuthorDto> allAuthors(){
        // implementation for creating the list with pagination
    }
}

Имейте в виду пару вещей:

  1. The AuthorDtoкласс (класс данных, запись Java и т. д.) должен иметь те же поля, что и те, которые определены в вашем файле , что на данный момент не так.

  2. В вашейschema.graphqlsопределение, я вижу, что у него есть массивBook, что нормально, но у этого поля есть аргументы

            books(page: Int, size: Int, sort: String): [Book!]!
    

Я не уверен, что это разрешено внутри определения пользовательского типа в GraphQL (type Book{...}), который не является запросом, изменением или подпиской.


РЕДАКТИРОВАТЬ

Взяв во вниманиеbooksвнутриAuthor, я никогда не использовал@Argumentвнутри@SchemaMappingкромеQueryилиMutation. Я бы попробовал это под вашим@QueryMapping:

      @SchemaMapping
List<Book> books(Author author, @Argument Integer page, @Argument Integer size, @Argument String sort){     
    // your logic
}
Другие вопросы по тегам