Всем добрый день!
Сегодня речь пойдет об API сборки. Напомню, что сердцем обновленной сборки является API на базе GraphQL. Если кто еще не видел, можно поиграться здесь: https://shopmodx.ru/db/
Как все это работает? В GraphQL есть две основные составляющие:
1. Схема, то есть структура данных, которые в принципе могут быть запрошены. К примеру, вот схема заказа, а вот схема отдельной позиции в заказе.
Давайте разберем это на примере товарной позиции.
Большинство таких объектов - производные от класса GraphQLObjectType (хотя есть и другие классы, но мы их не будем сейчас разбирать здесь). В таких объектах два обязательных поля: name и fields. И вот тут сразу отмечу пару тонкостей. Во-первых, в рамках всей GraphQL-схемы имена объектов должны быть уникальными. Нельзя иметь в схеме два объекта с одним именем, даже если все поля в них разные. Это необходимо для правильного разбора структуры, так как граф позволяет формировать многоуровневые запросы с зависимостями и еще на уровне сбора схемы проверяет все ли везде в порядке. Плюс ко всему на основе общей структуры генерируется документация по сформированному АПИ.
Во-вторых, в качестве полей допустимо использовать не только простые поля типа GraphQLInt, GraphQLString и т.п., но и другие объекты. В данном примере это Product с типом MODXResourceType, экспортируемый из ../modResource, который, в свою очередь, экспортирует этот тип из компонента modx-react.
Да, все это довольно запутанно, но зато, как я убедился уже не раз в работе с различными проектами, потом не приходится бегать по всему проекту и искать ответы на вопросы что можно получить по АПИ, а что нет. Даже на тех проектах, где предоставлялась документация, на практике оказывалось, что документация часто не соответствует действительности (разработчик внес изменения в АПИ, а в документацию забыл). Здесь же документация генерируется на лету. А если где-то в схеме оказалась какая-то ошибка, то вы в принципе запроса не выполните, пока не устраните ошибку. И даже если у вас все хорошо, то есть валидация и по типам данных, то есть в АПИ прописан для поля тип данных число, а в ответе от источника пришла строка. Все, граф на это заругается, и правильно сделает. Так что на выходе потом имеющийся порядок компенсирует все мучения.
Здесь уточню, что хотя мы в поле прописали только одну сущность - Product, на выходе мы в этом месте получим всю структуру объекта Product.
Вторая часть графа - это уже непосредственно тело запроса. К примеру, если у вас есть аккаунт на гитхабе, вы можете поиграться с их конструктором запросов https://developer.github.com/v4/explorer/
И здесь можно увидеть небольшую разницу в работе: у них вы можете редактировать запрос и тут же получать ответ в соответствии со структурой этого запроса. Здесь же редактирование запроса почти ничего не дает. Все потому что в ShopModxBox на сервер отправляется не зам запрос, а только название отдельной операции и параметры. Пример:
query OwnOrder - это название отдельной операции.
$orderGetProducts:Boolean = false и т.п. - это входящие переменные (с указанием типа данных и значения по умолчанию).
Это непосредственно тело запроса:
...Order - это конструкция передачи вывода в заранее определенный фрагмент (выше его код так же приведен).
@storage - директива, но директивы мы рассмотрим как-нибудь позже.
Так вот, все эти запросы описаны заранее и обрабатываются на стороне сервер, то есть передавая на сервер запрос OwnOrder, граф находит эту операцию в подготовленном листинге запросов и собирает указанные данные. Вот весь этот листинг в компоненте shopmodx-react: https://github.com/MODX-Club/shopmodx-react/blob/master/components/ORM/query.js
Но тут встает вопрос: а как же на конечном проекте расширять эти запросы, если они уже заранее прописаны в обновляемом компоненте?
Для решения этой задачи я выпустил сегодня новый компонент react-cms-graphql-utils, в составе которого имеется полезная функция mergeQuery https://github.com/MODX-Club/react-cms-graphql-utils/blob/master/src/mergeQuery.js
Передаем в нее базовый список запросов и кастомный, mergeQuery производит разбор одного и другого на отдельные сущности и мержит их, перетирая имеющиеся и дополняя новыми. Свои кастомные запросы можно писать сюда: https://github.com/MODX-Club/ShopModxBox/blob/5559089d68a1ae75b641492d4ef6395180e508fd/assets/components/modxsite/templates/shopmodx/v4.0/app/modules/Site/components/ORM/query.js#L6
Позже я покажу реальные кейсы с применением всего этого.
Отдельный урок про GraphQL был здесь: https://modxclub.ru/topics/react-js.-urok-%E2%84%962.-zaprosyi-s-pomoshhyu-graphql-2693.html