Вслед за анонсом проекта Spring GraphQL и выходом майлстоуна 1.0 мы публикуем этот пост с более подробной информацией. Если вы только приступаете к работе, перейдите к справочной документации и прочтите раздел Boot Starter или запустите примеры. Если вы хотите узнать больше о языке GraphQL, в сети есть много хороших ресурсов на эту тему. Можно начать с graphql.org/learn. Язык GraphQL широко применяется — согласно статье InfoQ о трендах в архитектуре за 2020 год, он находится на ранней стадии принятия большинством. Он является альтернативой REST API, больше ориентированному на данные, и представляет собой язык схем и запросов для клиентов. О привлекательности с точки зрения клиента явно свидетельствует отчет State of JS. В этой статье описано, почему GitHub использует GraphQL. Как написал Энди Марек (Andy Marek) во вводной статье в своем блоге, Spring GraphQL задумывался как преемник проекта GraphQL Java Spring от разработчиков GraphQL Java. По этой причине изначально в нашем совместном проекте мы стремились реализовать сопоставимый функционал и наилучшим образом совместить GraphQL Java и Spring. Для этого мы создали следующую базовую поддержку: обработчики HTTP — доступны как для Spring MVC, так и для WebFlux, построены на функциональных API конечных точек WebMvc и WebFlux; обработчики WebSocket — по протоколу от graphql-ws с поддержкой потоков подписки GraphQL; веб-перехват — возможность перехватывать каждый запрос GraphQL, проверять заголовки HTTP и изменять ExecutionInput или ExecutionResult в GraphQL; стартер Boot — объединение всех этих функций в работоспособное приложение. Помимо этого, мы уделили внимание таким ключевым аспектам, как безопасность, тестирование и метрики. URL-адрес конечной точки GraphQL, как обычно, легко защитить. Для более точечного обеспечения безопасности приложения могут дополняться аннотациями Spring Security в методах извлечения данных. Для этого необходимо, чтобы контекст безопасности Spring распространялся на методы извлечения данных, и, хотя реализация GraphQL Java нейтральна по отношению к потокам, выполняемые компоненты сами могут быть асинхронными и вызывать переключение потоков. В связи с этим мы добавили поддержку распространения контекста с уровня веб-инфраструктуры через механизм GraphQL — к компонентам выборки данных. Сюда входят контексты ThreadLocal и Reactor для приложений Spring MVC и WebFlux соответственно. После внедрения этих функций Spring Security не требует какой-либо дополнительной специализированной интеграции. В примерах webmvc-http и webflux-security продемонстрировано использование Spring Security. Spring GraphQL позволяет приложениям создавать несколько независимых компонентов GraphQlExceptionResolver для обработки исключений ошибок GraphQL, включаемых в ответ GraphQL. Также он по умолчанию предоставляет тип ErrorType для классификации ошибок с общими категориями, например BAD_REQUEST, UNAUTHORIZED, FORBIDDEN, NOT_FOUND или INTERNAL_ERROR. Тестировать запросы GraphQL можно с помощью WebTestClient, просто отправляя и получая текст в формате JSON. Однако из-за особенностей GraphQL этот подход менее удобен, чем он должен быть. Вот почему в Spring GraphQL предусмотрен класс WebGraphQlTester, определяющий порядок тестирования запросов GraphQL. Он предлагает следующее: проверка значений 200 (OK) в ответах GraphQL; проверка на отсутствие непредвиденных ошибок под ключом errors в ответе; расшифровка значений по ключу data в ответе; расшифровка разных частей ответа с помощью JsonPath; тестирование подписок. Во всех примерах используется GraphQlTester. При наличии стартера spring-boot-starter-actuator собираются метрики для запросов GraphQL, включая таймеры запросов и DataFetcherexecution, а также счетчик ошибок. Querydsl обеспечивает гибкий и типобезопасный подход к выражению предикатов запросов. Spring GraphQL основан на расширении Spring Data Querydsl, что упрощает создание DataFetcher с поддержкой Querydsl. Оно подготавливает Predicate Querydsl из параметров запроса GraphQL и использует его для выборки данных из JPA, MongoDB и LDAP. В примере webmvc-http используется Querydsl. GraphQL предоставляет язык схем для составления корректных запросов и визуальный редактор GraphiQL, способствует применению общего словаря в разных командах разработчиков и предлагает другие удобства. Также он затрагивает извечную дилемму о том, что первично — схема или объект. Мы считаем, что предпочтение следует отдавать принципу schema-first («сначала схема»). Он облегчает взаимодействие между людьми с техническим и нетехническим образованием, помогает в использовании инструментов, упрощает отслеживание изменений и т. д. Кроме того, нет однозначного сопоставления между схемой GraphQL и типами Java. Тем не менее возможна генерация кода — для начала работы, для создания запросов клиентами и т. д. Такие фреймворки, как Netflix DGS, имеют отличную поддержку этих функций, их можно использовать с Spring GraphQL. Мы планируем выпустить второй майлстоун до выхода SpringOne, намеченного на 2–3 сентября. На основе первых отзывов мы определили ряд задач, которые будут решены во втором майлстоуне, включая поддержку клиента GraphQL, регистрацию BatchLoader, загрузку файлов и многое другое. Этап майлстоунов продлится до выхода Spring Boot 2.6 в ноябре, после чего стартер Boot планируется переместить в репозиторий Spring Boot для включения в Boot 2.7. Мы планируем довести API до стабильного состояния и перейти к этапу релиз-кандидата (RC) позже в этом году. Для этого нам нужны ваши отзывы. Протестируйте наш проект, и если столкнетесь с проблемами, занесите их в наш трекер (или напишите, были ли исправлены какие-то из существующих недочетов). Дополнительные сведения о возможностях Spring GraphQL см. в справочной документации. В этом году команды разработчиков GraphQL Java и Spring совместно выступят на конференции SpringOne, которая второй год подряд будет бесплатной и пройдет в онлайн-формате. Зарегистрируйтесь, чтобы присутствовать на нашем выступлении и иметь возможность пообщаться с докладчиками и участниками конференции. Материал подготовлен в рамках специализации «Java Developer».   Переводчик, редактор