- Регистрация
- 27.12.2016
- Сообщения
- 289
- Благодарностей
- 404
- Баллы
- 63
Всем добра и щедрого Деда Мороза!
ВСТУПЛЕНИЕ
В прошлых конкурсах я рассказывал о взаимодействии с MySQL и SQLite с использованием системы сопоставления данных Dapper, значительно облегчающих жизнь пользователям ZP. Правда для использования БД и Dapper, нужно иметь определенные скилы в C#, и уметь писать хотя бы самые простые SQL запросы.
Сегодняшняя статья так же будет посвящена взаимодействию с БД, но путь джедая будет совсем другим, и надеюсь, позволит применить изложенную информацию пользователям ZP, использующим в своей работе стандартные кубики для запросов (код в обучающем шабе тоже будет, но кроме сериализации JSON, без него пожалуй можно будет обойтись). Итак, как следует из названия, сегодня мы создадим собственный REST-API, для доступа к информации в базе данных, и будем использовать его для добавления и обработки данных в БД. Так как работа с API подразумевает использование структурированной инфы, работать будем с данными в формате JSON. Ну и бонусом, надеюсь читателю станут понятны основы REST API (програмный интерфейс взаимодействия с приложениями, основанный на протоколе HTTP, и используемый повсеместно — VK, sms-activate.ru, rucaptcha.com и еще тонны других веб сервисов).
К статье будет приложен шаблон, в котором присутствуют примеры всех описанных в материале запросов, выполненные на стандартном HTTP кубике.
DIRECTUS
Для работы будем юзать облачный сервис Directus.Cloud, и прежде чем приступить к практике его использрванию, несколько слов о том, что такое Directus:
Direсtus — это полноценная опенсорсная headless-CMS, доступная для установки на собственном сервере и работающая на NodeJS (о котором я тоже писал в предыдущем конкурсе — вот совпадение!). Direсtus представляет собой обертку вокруг БД, добавляющую удобный графический интерфейс для любых CRUD операций с данными. Точнее, графический интерфейс это самое простое, что есть в Directus. Так же здесь есть:
Там еще вроде CLI интерфейс для управления сервером и работы с данными есть, но с этих сторон я еще даже не заглядывал. В общем, Directus это и безголовая CMS, и backend-сервер, и платформа для создания собственной бизнес-аналитики, ну и еще наверное много чего.
Помимо облачного решения, все это можно воткнуть на свою VPS-ку или Docker и получать удовольствие, но... Работа в никсах это отдельные скилы (а до Докера у меня руки пока не дошли вообще), да и в одной статье все нюансы не описать. Сейчас я начал работу над проектом, который как раз будет использовать собственную установку Directus с использованием MySQL, пока сабж расположен на виртуалке, а в дальнейшем переедет на VPS. Опишу несколько основных этапов, которые пришлось пройти, чтобы добраться до веб-интерфейса Directus:
А мы пойдем простым путем и будем юзать готовый Directus.Cloud — платформу для создания и запуска Directus приложений, без всяких админских бубнов (тут даже БД ставить не нужно — регайся и начинай работать).
Ложечка дегтя в адрес Directus.Cloud по сравнению с selfhosted вариантом (по мере значимости и субъективно):
РЕГИСТРАЦИЯ И ПЕРВОНАЧАЛЬНЫЕ НАСТРОЙКИ
Специально для конкурса зарегал тестовый акк, которым делюсь с вами для экспериментов. Процесс реги и настроек описан в прилагаемом к статье видео.
Собственно из жизненно необходимых настроек нужны:
Так что из него можно самостоятельно и зайти на веб-морду, и погонять api-запросы (а можно и через браузер, кому так интереснее)
РАБОТА С API
Ну что же, мы подошли к созданию таблицы в БД (или, в терминологии Directus — коллекции).
Вкратце, как выглядит REST API Directus, и какие основные точки входа создаются. Точка входа любого REST API — это URL, через который осуществляются манипуляции с данными.
В общем случае, в Directus, для создания данных на сервере запросы выполняются методом POST, для получения данных — методом GET, для обновления — PATCH, а для удаления — DELETE. Все запросы к серверу выполняются с типом данных application/json. И еще один важный момент — названия коллекций и полей чувствительны к регистру. Если коллекция в Directus называется Products, а в URL или JSON указано products, вы получите ошибку.
При создании коллекции (для простоты изложения, будем считать, что коллекция сразу имеет поля и элементы) автоматически создаются эндпоинты API:
СОЗДАНИЕ КОЛЛЕКЦИИ
Создание пустой коллекции products через админку я показал в видео, с созданием же таблицы через API ситуация такая:
Полный объект collection выглядит так (ссыль на документацию):
Там, же, в доках сказано, что обязательным является лишь свойство collection, и преведены такие данные для создания коллекции articles:
Утверждается, что если эти данные пульнуть POST-запросом по URL вида https://URL_приложения/collections?access_token=ваш_токен то должна создаться пустая коллекция. Однако при отправке приведенного выше JSON возвращается ошибка с кодом INVALID_PAYLOAD и комментарием, что «Предоставленная полезная нагрузка недействительна». Если же отправить полный объект collection, в котором заполнено только свойство collection, то коллекция прекрасно создается. Написать пример создания коллекции через код + API не успеваю (много времени убил чтобы разобраться), приведенной инфы достаточно, чтобы тот, кому действительно это нужно сам придумал подходящий вариант.
СОЗДАНИЕ ПОЛЕЙ
Теперь нужно создать поля для нашей таблицы (коллекции). Как сделать это через веб-морду понятно интуитивно, а тут приведу пример создания полей через API:
Для работы с API нам понадобятся:
URL-адрес нашего приложения я сохранил в переменную проекта URL_app, а токен в переменную API_token. Так же в шаблоне есть переменные для отправки запроса (API_request) и для получения ответа (API_response), и еще API_dinamicUrl .
Для начала, нам нужен URL-адрес, при обращению к которому Directus поймет, что мы планируем создавать поля в определенной коллекции. Согласно документации, формируется он следующим образом: https://URL_приложения/fields/имя_коллекции?access_token=наш_токен_юзера_api.
Так же, нам нужны структурированные в JSON данные, в которых указанно наименование коллекции, имя и тип поля. Для поля sku, коллекции products, JSON будет таким:
Для создания поля, в общем коде обучающего шаба (namespace DirHelper) я создал классы Field и FieldMeta:
А в кубике создал экземпляр данного класса, заполнил его свойства, и преобразовал в JSON, используя встроенную в ZP библиотеку Newtonsoft:
После чего, отправил POST-запрос на URL, о котором писал выше, и в ответе получил следующую информацию:
А вот так выглядят настройки кубика POST-запроса:
Поздравляю, поле sku, коллекции products успешно создано! Остальные поля создаются аналогично, я не буду повторяться. На этом работу по созданию полей сворачиваем и приступаем к работе с данными.
ДОБАВЛЕНИЕ ЭЛЕМЕНТОВ В КОЛЛЕКЦИЮ (ТАБЛИЦУ)
Итак, у нас есть коллекция, готовая к приему данных. Чтобы добавить в нее элемент, нам вновь нужна точка входа API — URL вида https://URL_приложения/items/имя_коллекции?access_token=токен_для_юзера_api. Имя коллекции нам известно, токен есть, все остальное тоже, осталось нагенерить товаров перегнать их в JSON и сделать POST-запрос на добавление. Генерацию тут показывать не буду, приведу JSON, при отправке которого будет создаваться один элемент коллекции:
А так же JSON, для создания нескольких элементов:
Теперь попробуем получить все элементы коллекции. Для этого нам опять нужен URL, при обращении к которому Directus вернет список элементов коллекции — https://URL_приложения/items/имя_коллекции?access_token=токен_для_юзера_api.
Внимательным откроется, что URL идентичен тому, к которому мы обращались чтобы добавить элементы коллекции. А разница будет только в типе запроса — для добавления мы использовали POST, а для получения будем использовать GET. Так выглядят настройки кубика GET:
Я не буду приводить здесь весь ответ сервера, чтобы понять как выглядит JSON в нем, достаточно пары элементов:
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ ПО ID
Переходим на новый уровень — будем получать элемент коллекции по id. Отличие от предыдущего запросв только в URL, который выглядит так:
https://URL_приложения/items/имя_коллекции/id_злемента_который_нам_нужен?access_token=токен_для_юзера_api. В ответе, как и следовало ожидать, нам вернется 1 элемент коллекции, id которого соответствует тому, котрый мы указали в запросе. Если элемент с указанным id не найден, вернется ошибка такого вида:
Разрабы пишут об этой ошибке: «Чтобы предотвратить утечку информации о том, какие элементы существуют, все действия с несуществующими элементами будут возвращать ошибку FORBIDDEN».
Не знаю, правильно это или нет, но что есть то есть (лично мне хотелось бы более развернутый комментарий, по-крайней мере, если я выполняю запрос с токеном, и он валиден — пока не нашел это описание, грел голову, почему же, ..ять, «You don't have permission to access this», если у меня админские права, и я реально имею админский доступ и могу это проверить?!)...
Теперь перейдем к обновлению элемента коллекции по id. Для этого используется запрос PATCH. URL для обновления выглядит так же как и в предыдущем примере GET-запроса — https://URL_приложения/items/имя_коллекции/id_злемента_который_нам_нужен?access_token=токен_для_юзера_api, а в теле запроса указываются поля, которые нужно обновить. Например:
Прежде чем обновить элемент, нужно убедиться, что он существует (и, пожалуй, что вы меняете значение поля у того элемента, у которого собирались), иначе «You don't have permission to access this» и вырванные волосы «Почему, с¥ка? ???», или еще хлеще — получить товар «Штангенциркуль» с описанием «Заходит мягко, голова с утра не болит» и узнать об этом после того, как позвонят в дверь и попросят прокомментирвать.
А между тем, мы подошли к самому интересному — различным выборкам из коллекции по условиям.
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ ПО ЗНАЧЕНИЮ КОНКРЕТНОГО ПОЛЯ КОЛЛЕКЦИИ
И начнем с самого простого — поиска по текстовым полям точного соответствия. Я нагенерил в коллекции products всяких бредопродуктов. Например там есть коньяк, вискарь, изделие №2, штангенциркуль. Сформулирую задачу: в коллекции products нам нужно найти элементы, у которых в поле name значение соответствует значению "Вискарь". Для поиска точного соответствия в Directus имеется оператор "_eq". Теперь нам нужно составить запрос с указанием, что мы собираемся воспользоваться фильтром — https://URL_приложения/items/имя_коллекции?filter[имя_поля_в_котором_искать][_eq]=Вискарь&access_token=наш_токен
Внимательные читатели уже заметили, что после основного URL идет знак "?", который отделяет дополнительные параметры API, а эти дополнительные параметры между собой разделяются знаком амперсанда "&". Вот так и формируются API запросы. Именно таков принцип формирования точек входа для REST API, хотя в разных приложениях детали реализации все же будут отличаться.
Готовый URL будет выглядеть так: (токен писать не буду, он есть в шаблоне) Отправляю GET-запрос на этот URL и получаю JSON ответ:
А если в ответе нужны только поля id и name? Нам предоставлена возможность выбора возвращаемых полей. URL для такого запроса — https://URL_приложения/items/имя_коллекции?fields=возврашаемое_поле_1,возвращаемое_поле_2&filter[имя_поля_в_котором_искать][_eq]=Вискарь&access_token=наш_токен, или
В ответе нам возвращаются только те поля, которые мы заказывали:
А если нужно получить только 1 элемент? Пожалуйста (общий вид URL указывать больше не буду, надеюсь как он формируется понятно):
В ответе мы получим 1 элемент, имя которого соответствует значению "Вискарь".
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ КОЛЛЕКЦИИ, ЗНАЧЕНИЕ УКАЗАННОГО ПОЛЯ КОТОРЫХ НЕ СООТВЕТСТВУЕТ ТЕКСТУ ПЕРЕДАВАЕМОМУ В ЗАПРОСЕ
Для этой задачи в Directus имеется оператор "_neq" — не эквивалентен. Пример запроса для получения элементов коллекции Products, у которых значение поля name не эквивалентно "Вискарь", с лимитом возвращаемых элементов 2:
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ КОЛЛЕКЦИИ УКАЗАННОЕ ПОЛЕ КОТОРЫХ СОДЕРЖИТ ПЕРЕДАВАЕМОЕ ЗНАЧЕНИЕ
Для выборок такого рода используется оператор "_contains", которому передается подстрока для поиска:
https://frl2qid4.directus.app/items/products?fields=id,name&filter[name][_contains]=Изделие&access_token=наш_токен
При запросе по данному URL сервер вернет все элементы, поле name которых содержит значение "Изделие" (поиск регистрозависим, тмк что поля со словом "изделие" возвращены не будут)
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ КОЛЛЕКЦИИ ЗНАЧЕНИЕ УКАЗАННОГО ПОЛЯ КОТОРЫХ НАЧИНАЕТСЯ С УКАЗАННОГО ТЕКСТА
Для этих целей используется оператор _starts_with:
В ответе на данный запрос вернутся все элементы, значение поля name которых начинается с "Год". Работает с текствыми полями.
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ КОЛЛЕКЦИИ, ЧИСЛОВОЕ ЗНАЧЕНИЕ УКАЗАННОГО ПОЛЯ КОТОРЫХ БОЛЬШЕ ЧЕМ УКАЗАННОЕ В ЗАПРОСЕ
Перейдем к числам — для выборки будем использовать оператор "_gt". В коллекции products имеется поле price, в котором указана цена бредопродукта. Давайте получим элементы, у которых цена более 900 каких-то денежных единиц:
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ КОЛЛЕКЦИИ, ЧИСЛОВОЕ ЗНАЧЕНИЕ УКАЗАННОГО ПОЛЯ КОТОРЫХ МЕНЬШЕ ЧЕМ УКАЗАННОЕ В ЗАПРОСЕ
Для этого варианта фильтра применим оператор "_lt". Получим элементы, у которых цена меньше 200 денежных единиц:
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ КОЛЛЕКЦИИ УКАЗАННОЕ ПОЛЕ КОТОРЫХ СОДЕРЖИТ ЗНАЧЕНИЕ 1 И ЧИСЛОВОЕ ПОЛЕ БОЛЬШЕ ЧЕМ ЗНАЧЕНИЕ 2
А здесь мы будем ипользовать сразу 2 фильтра:
https://frl2qid4.directus.app/items/products?filter[name][_contains]=Изделие&filter[price][_gt]=800&access_token=наш_токен
Первый фильтр "filter[name][_contains]=Изделие" выбирает данные по текстовому полю, а вторым фильтром "filter[price][_gt]=800"? мы уточням, что нам нужны данные у которых значение поля price больше 800. Сюда же можно прикрутить и третмй, и четвертый фильтры.
Если в коллекции отсутствуют данные, соответствующие параметрам фильтрации (или запросу без фильтра), север возвращает пустой JSON массив:
Как видно из приведенных примеров, с помощью фильтров и их комбинаций можно получать довольно сложные выборки. Я привел лишь небольшую часть фильтров, доступных в Directus, с полным списком можно ознакомиться в документации.
ИМПОРТ/ЭКСПОРТ КОЛЛЕКЦИЙ
Через web
Доступен экспорт в .csv, json, xml. Так же можно выбрать поля, которые нужно экспортировать и указать количество экспортируемых элементов. Через API тоже можно.
ЗАКЛЮЧЕНИЕ
Я не озвучил довольно много возможностей, присутствующих из коробки в Directus — это и вебхуки, и сортировка возвращаемых данных, и возможность создания собственных эндпоинтов, создание коллекций со сложными связями, алиасы, offset...
Информация — это современная валюта, а возможность быстро обработать ее после получения — незаменимое конкурентное преимущество.
Как мне видится, практически мгновенное развертывание API в сочетании с такими мощными возможностями может существенно снизить время на разработку и пригодиться как для проверки каких-то гипотез, так и для повседневного использования в рабочих проектах в качестве альтернативы спискам, google-таблицам и прочим exel-ям даже в бесплатном варианте Directus.cloud.
ССЫЛКИ
Стартовая страница документации Directus https://docs.directus.io/getting-started/introduction.html
Коллекции Directus https://docs.directus.io/reference/system/collections.html#collections
Поля коллекций https://docs.directus.io/reference/system/fields.html#fields
Элементы коллекций https://docs.directus.io/reference/items.html#accessing-items
ВСТУПЛЕНИЕ
В прошлых конкурсах я рассказывал о взаимодействии с MySQL и SQLite с использованием системы сопоставления данных Dapper, значительно облегчающих жизнь пользователям ZP. Правда для использования БД и Dapper, нужно иметь определенные скилы в C#, и уметь писать хотя бы самые простые SQL запросы.
Сегодняшняя статья так же будет посвящена взаимодействию с БД, но путь джедая будет совсем другим, и надеюсь, позволит применить изложенную информацию пользователям ZP, использующим в своей работе стандартные кубики для запросов (код в обучающем шабе тоже будет, но кроме сериализации JSON, без него пожалуй можно будет обойтись). Итак, как следует из названия, сегодня мы создадим собственный REST-API, для доступа к информации в базе данных, и будем использовать его для добавления и обработки данных в БД. Так как работа с API подразумевает использование структурированной инфы, работать будем с данными в формате JSON. Ну и бонусом, надеюсь читателю станут понятны основы REST API (програмный интерфейс взаимодействия с приложениями, основанный на протоколе HTTP, и используемый повсеместно — VK, sms-activate.ru, rucaptcha.com и еще тонны других веб сервисов).
К статье будет приложен шаблон, в котором присутствуют примеры всех описанных в материале запросов, выполненные на стандартном HTTP кубике.
DIRECTUS
Для работы будем юзать облачный сервис Directus.Cloud, и прежде чем приступить к практике его использрванию, несколько слов о том, что такое Directus:
Direсtus — это полноценная опенсорсная headless-CMS, доступная для установки на собственном сервере и работающая на NodeJS (о котором я тоже писал в предыдущем конкурсе — вот совпадение!). Direсtus представляет собой обертку вокруг БД, добавляющую удобный графический интерфейс для любых CRUD операций с данными. Точнее, графический интерфейс это самое простое, что есть в Directus. Так же здесь есть:
- Поддержка большинства реляционных БД — MySQL, SQLite, Postgres, MSSQL, OracleDB из коробки
- Хранение файлов (например изображений или цифровых товаров) локально, или возможность подключить внешнее хранилище ()
- Авторизация пользователей
- Удобный графический интерфейс, позволяющий управлять не только контентом, но и пользователями системы, их ролями и прочими системными штуками
- Автоматическая генерация точек входа для REST и GraphQL API (причем как для управления сервером, так и для работы с данными)
- Использование API для работы с таблицами БД,
- Webhooks,
- Модульная архитектура, позволяющая создавать собственные расширения, точки входа для API (правда надо знать NodeJS и Vue.js),
- Наверное это не все, но и так очень красиво
Там еще вроде CLI интерфейс для управления сервером и работы с данными есть, но с этих сторон я еще даже не заглядывал. В общем, Directus это и безголовая CMS, и backend-сервер, и платформа для создания собственной бизнес-аналитики, ну и еще наверное много чего.
Помимо облачного решения, все это можно воткнуть на свою VPS-ку или Docker и получать удовольствие, но... Работа в никсах это отдельные скилы (а до Докера у меня руки пока не дошли вообще), да и в одной статье все нюансы не описать. Сейчас я начал работу над проектом, который как раз будет использовать собственную установку Directus с использованием MySQL, пока сабж расположен на виртуалке, а в дальнейшем переедет на VPS. Опишу несколько основных этапов, которые пришлось пройти, чтобы добраться до веб-интерфейса Directus:
- Установка и настройка сервера Linux (использовал Ubuntu server 22.4 LTS),
- Установка менеджера версий NodeJS nvm,
- Установка NodeJS (Directus желает версию не ниже 18 LTS),
- Установка и настройка сервера MySQL 8,
- Установка самого Directus и создание нового приложения
А мы пойдем простым путем и будем юзать готовый Directus.Cloud — платформу для создания и запуска Directus приложений, без всяких админских бубнов (тут даже БД ставить не нужно — регайся и начинай работать).
Ложечка дегтя в адрес Directus.Cloud по сравнению с selfhosted вариантом (по мере значимости и субъективно):
- Пока не нашел как забэкапить данные из облака, чтобы перенести их куда-нибудь (ан нет,нашел! Рассакжу ниже),
- Раз в сколько-то дней нужно заходить в админку и продлевать использование своего приложения (точно пока не выяснял как часто, но тут опять же, можно запилить автопродлеватель на ZP),
- URL бесплатной версии хрен запомнишь (типа https://jg9nmd4hfgk.directus.app),
РЕГИСТРАЦИЯ И ПЕРВОНАЧАЛЬНЫЕ НАСТРОЙКИ
Специально для конкурса зарегал тестовый акк, которым делюсь с вами для экспериментов. Процесс реги и настроек описан в прилагаемом к статье видео.
Собственно из жизненно необходимых настроек нужны:
- Получить статический токен для запросов к API от имени админа
- Создать пустую коллекцию (и то, в доках есть примеры создания через апи (об это ниже), но через веб быстрее)
- URL приложения,
- email (он же логин),
- пароль для доступа к приложению,
- ключ доступа для API
Так что из него можно самостоятельно и зайти на веб-морду, и погонять api-запросы (а можно и через браузер, кому так интереснее)
РАБОТА С API
Ну что же, мы подошли к созданию таблицы в БД (или, в терминологии Directus — коллекции).
Чтобы изучить работу с API опишем объект, для которого и будем создавать таблицу и работать с ней:
Product (товар), имеющий следующие атрибуты (поля):
Но, в процессе тестов оказалось, что одного объекта Product будет недостаточно, т.к. контроль за уникальностью id мне хотелось оставить Directus-у, а если не заполнять id при создании объекта Product, то при конвертации объекта в JSON этот id почему-то становится равным 0 (допускаю, что где-то что-то не учел, так ка делаю статью в бешеной спешке — времени совсем нет). В итоге плюнул и создал 2 класса — один для создания объектов Product:
Второй для получения данных из коллекции:
Эти классы я описал в общем коде обучающего шаблона, в пространстве имен TestData.
Product (товар), имеющий следующие атрибуты (поля):
- id,
- sku(артикул) - поле типа string,
- name (название) - поле типа string,
- descr(описание) - поле типа string,
- price (цена) - поле типа integer (для простоты сойдет и integer)
Но, в процессе тестов оказалось, что одного объекта Product будет недостаточно, т.к. контроль за уникальностью id мне хотелось оставить Directus-у, а если не заполнять id при создании объекта Product, то при конвертации объекта в JSON этот id почему-то становится равным 0 (допускаю, что где-то что-то не учел, так ка делаю статью в бешеной спешке — времени совсем нет). В итоге плюнул и создал 2 класса — один для создания объектов Product:
C#:
/// <summary>
/// Класс для создания объектов продукт. Отличие от ProductRecipient в отсутствии id,
/// т.к. id создается в БД
/// </summary>
public class ProductCreator
{
public int sku {get; set;}
public string name {get; set;}
public string descr {get; set;}
public int price {get; set;}
}
C#:
/// <summary>
/// Класс для получения объектов продукт. Отличие от ProductCreator в наличии id
/// </summary>
public class ProductRecipient
{
public int id {get; set;}
public int sku {get; set;}
public string name {get; set;}
public string descr {get; set;}
public int price {get; set;}
}
Вкратце, как выглядит REST API Directus, и какие основные точки входа создаются. Точка входа любого REST API — это URL, через который осуществляются манипуляции с данными.
В общем случае, в Directus, для создания данных на сервере запросы выполняются методом POST, для получения данных — методом GET, для обновления — PATCH, а для удаления — DELETE. Все запросы к серверу выполняются с типом данных application/json. И еще один важный момент — названия коллекций и полей чувствительны к регистру. Если коллекция в Directus называется Products, а в URL или JSON указано products, вы получите ошибку.
При создании коллекции (для простоты изложения, будем считать, что коллекция сразу имеет поля и элементы) автоматически создаются эндпоинты API:
- https://URL_приложения/collections — для получения списка всех коллекций методом GET и создания новых методом POST
- https://URL_приложения/collections/имя_коллекции — для получения конкретной коллекции методом GET, обновления коллекци методом PATCH, удаления коллекции методом DELETE
- https://URL_приложения/fields — для получения списка коллекций со всеми доступными полями методом GET,
- https://URL_приложения/fields/имя_коллекции/имя_поля — для получения данных конкретного поля конкретной коллекции методом GET, обновления конкретного поля конкретной коллекции методом PATCH, удаления конкретного поля конкретной коллекции методом DELETE
- https://URL_приложения/fields/имя_коллекции — для создания новых полей конкретной коллекции методом POST
- https://URL_приложения/items/имя_коллекции — для получения списка элементов и различных выборок по условиям конкретной коллекции методом GET, создания новых методом POST, обновления элементов конкретной коллекции методом PATCH, удаления элементов конкретной коллекции методом DELETE
СОЗДАНИЕ КОЛЛЕКЦИИ
Создание пустой коллекции products через админку я показал в видео, с созданием же таблицы через API ситуация такая:
Полный объект collection выглядит так (ссыль на документацию):
JSON:
{
"collection": "collection_name",
"meta": {
"collection": null,
"icon": null,
"note": null,
"display_template": "{{ title }}",
"hidden": false,
"singleton": false,
"translations": [],
"archive_field": null,
"archive_value": null,
"unarchive_value": null,
"archive_app_filter": false,
"sort_field": null,
"item_duplication_fields": null,
"sort": null
},
"schema": {}
}
JSON:
{
"collection": "testimonials",
"meta": {
"icon": "format_quote"
}
}
СОЗДАНИЕ ПОЛЕЙ
Теперь нужно создать поля для нашей таблицы (коллекции). Как сделать это через веб-морду понятно интуитивно, а тут приведу пример создания полей через API:
Для работы с API нам понадобятся:
- URL приложения из письма о его создании (я о нем выше писал, вот такого вида — https://ry8p7dkz.directus.app),
- токен, который был сгенерирован для юзера api,
URL-адрес нашего приложения я сохранил в переменную проекта URL_app, а токен в переменную API_token. Так же в шаблоне есть переменные для отправки запроса (API_request) и для получения ответа (API_response), и еще API_dinamicUrl .
Для начала, нам нужен URL-адрес, при обращению к которому Directus поймет, что мы планируем создавать поля в определенной коллекции. Согласно документации, формируется он следующим образом: https://URL_приложения/fields/имя_коллекции?access_token=наш_токен_юзера_api.
Так же, нам нужны структурированные в JSON данные, в которых указанно наименование коллекции, имя и тип поля. Для поля sku, коллекции products, JSON будет таким:
JSON:
{
"collection":"products",
"field":"sku",
"type":"integer"
}
C#:
/// <summary>
/// Класс для создания столбцов коллекций (таблиц)
/// </summary>
public class Field
{
public string collection {get; set;}
public string field {get; set;}
public string type {get; set;}
public FieldMeta meta {get; set;}
public Field(FieldMeta meta)
{
this.meta = meta;
}
}
/// <summary>
/// Класс для создания метаданных (используются для отображения в админке)
/// Нужен исключительно для того, чтобы при созлании поля оно отображалось в секции контент (не было скрыто в админке и его не приходилось править руками)
/// </summary>
public class FieldMeta
{
public bool hidden = false;
}
C#:
#region Создаем экземпляр класса Field
Field field = new Field();
field.collection = "products";
field.field = "sku";
field.type = "integer";
#endregion
#region Преобразуем класс Field в JSON и сохраняем в переменную проекта
project.Variables["API_request"].Value = JsonConvert.SerializeObject(field).ToString();
#endregion
#region Удаляем экземпляр класса Field
field = null;
#endregion
JSON:
{
"data":
{
"collection":"products",
"field":"sku",
"type":"integer",
"meta":null,
"schema":
{
"name":"sku","
table":"products",
"schema":"public",
"data_type":"integer",
"is_nullable":true,
"generation_expression":null,
"default_value":null,
"is_generated":false,
"max_length":null,
"comment":null,
"numeric_precision":32,
"numeric_scale":0,
"is_unique":false,
"is_primary_key":false,
"has_auto_increment":false,
"foreign_key_schema":null,
"foreign_key_table":null,
"foreign_key_column":null
}
}
}
А вот так выглядят настройки кубика POST-запроса:
Поздравляю, поле sku, коллекции products успешно создано! Остальные поля создаются аналогично, я не буду повторяться. На этом работу по созданию полей сворачиваем и приступаем к работе с данными.
ДОБАВЛЕНИЕ ЭЛЕМЕНТОВ В КОЛЛЕКЦИЮ (ТАБЛИЦУ)
Итак, у нас есть коллекция, готовая к приему данных. Чтобы добавить в нее элемент, нам вновь нужна точка входа API — URL вида https://URL_приложения/items/имя_коллекции?access_token=токен_для_юзера_api. Имя коллекции нам известно, токен есть, все остальное тоже, осталось нагенерить товаров перегнать их в JSON и сделать POST-запрос на добавление. Генерацию тут показывать не буду, приведу JSON, при отправке которого будет создаваться один элемент коллекции:
JSON:
{
"sku":7311,
"name":"Борода Деда Мороза",
"descr":"Какое-то описание очень нужного товара.",
"price":726
}
C#:
[
{
"sku":7311,
"name":"Борода Деда Мороза",
"descr":"Какое-то описание очень нужного товара.",
"price":726
}
{
"sku":3223,
"name":"Баян крокодила Гены",
"descr":"Описание прекрасного крокодильего (или крокодилового?) баяна",
"price":777
}
]
Внимательным откроется, что URL идентичен тому, к которому мы обращались чтобы добавить элементы коллекции. А разница будет только в типе запроса — для добавления мы использовали POST, а для получения будем использовать GET. Так выглядят настройки кубика GET:
Я не буду приводить здесь весь ответ сервера, чтобы понять как выглядит JSON в нем, достаточно пары элементов:
JSON:
{"data":
[
{
"id":16,
"price":327,
"descr":"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
"sku":3371,
"name":"Набор для карманного биллиарда"
},
{
"id":17,
"price":260,
"descr":"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
"sku":2705,
"name":"Носки для Добби"
}
]
}
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ ПО ID
Переходим на новый уровень — будем получать элемент коллекции по id. Отличие от предыдущего запросв только в URL, который выглядит так:
https://URL_приложения/items/имя_коллекции/id_злемента_который_нам_нужен?access_token=токен_для_юзера_api. В ответе, как и следовало ожидать, нам вернется 1 элемент коллекции, id которого соответствует тому, котрый мы указали в запросе. Если элемент с указанным id не найден, вернется ошибка такого вида:
JSON:
{
"errors":
[
{
"message":"You don't have permission to access this.",
"extensions":
{
"code":"FORBIDDEN"
}
}
]
}
Разрабы пишут об этой ошибке: «Чтобы предотвратить утечку информации о том, какие элементы существуют, все действия с несуществующими элементами будут возвращать ошибку FORBIDDEN».
Не знаю, правильно это или нет, но что есть то есть (лично мне хотелось бы более развернутый комментарий, по-крайней мере, если я выполняю запрос с токеном, и он валиден — пока не нашел это описание, грел голову, почему же, ..ять, «You don't have permission to access this», если у меня админские права, и я реально имею админский доступ и могу это проверить?!)...
Теперь перейдем к обновлению элемента коллекции по id. Для этого используется запрос PATCH. URL для обновления выглядит так же как и в предыдущем примере GET-запроса — https://URL_приложения/items/имя_коллекции/id_злемента_который_нам_нужен?access_token=токен_для_юзера_api, а в теле запроса указываются поля, которые нужно обновить. Например:
JSON:
{
"name": "Носки для Добби армированные шерстью троля"
}
А между тем, мы подошли к самому интересному — различным выборкам из коллекции по условиям.
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ ПО ЗНАЧЕНИЮ КОНКРЕТНОГО ПОЛЯ КОЛЛЕКЦИИ
И начнем с самого простого — поиска по текстовым полям точного соответствия. Я нагенерил в коллекции products всяких бредопродуктов. Например там есть коньяк, вискарь, изделие №2, штангенциркуль. Сформулирую задачу: в коллекции products нам нужно найти элементы, у которых в поле name значение соответствует значению "Вискарь". Для поиска точного соответствия в Directus имеется оператор "_eq". Теперь нам нужно составить запрос с указанием, что мы собираемся воспользоваться фильтром — https://URL_приложения/items/имя_коллекции?filter[имя_поля_в_котором_искать][_eq]=Вискарь&access_token=наш_токен
Внимательные читатели уже заметили, что после основного URL идет знак "?", который отделяет дополнительные параметры API, а эти дополнительные параметры между собой разделяются знаком амперсанда "&". Вот так и формируются API запросы. Именно таков принцип формирования точек входа для REST API, хотя в разных приложениях детали реализации все же будут отличаться.
Готовый URL будет выглядеть так: (токен писать не буду, он есть в шаблоне) Отправляю GET-запрос на этот URL и получаю JSON ответ:
JSON:
{
"data":
[
{
"id":3,
"sku":5577,
"name":"Вискарь",
"descr":"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
"price":551
},
{
"
id":5,
"sku":1261,
"name":"Вискарь",
"descr":"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
"price":114
},
{
"id":6,
"sku":9619,
"name":"Вискарь",
"descr":"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
"price":960
}
]
}
А если в ответе нужны только поля id и name? Нам предоставлена возможность выбора возвращаемых полей. URL для такого запроса — https://URL_приложения/items/имя_коллекции?fields=возврашаемое_поле_1,возвращаемое_поле_2&filter[имя_поля_в_котором_искать][_eq]=Вискарь&access_token=наш_токен, или
В ответе нам возвращаются только те поля, которые мы заказывали:
JSON:
{
"data":
[
{
"id":3,
"name":"Вискарь"
},
{
"id":5,
"name":"Вискарь"
},
{
"id":6,
"name":"Вискарь"
}
]
}
А если нужно получить только 1 элемент? Пожалуйста (общий вид URL указывать больше не буду, надеюсь как он формируется понятно):
В ответе мы получим 1 элемент, имя которого соответствует значению "Вискарь".
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ КОЛЛЕКЦИИ, ЗНАЧЕНИЕ УКАЗАННОГО ПОЛЯ КОТОРЫХ НЕ СООТВЕТСТВУЕТ ТЕКСТУ ПЕРЕДАВАЕМОМУ В ЗАПРОСЕ
Для этой задачи в Directus имеется оператор "_neq" — не эквивалентен. Пример запроса для получения элементов коллекции Products, у которых значение поля name не эквивалентно "Вискарь", с лимитом возвращаемых элементов 2:
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ КОЛЛЕКЦИИ УКАЗАННОЕ ПОЛЕ КОТОРЫХ СОДЕРЖИТ ПЕРЕДАВАЕМОЕ ЗНАЧЕНИЕ
Для выборок такого рода используется оператор "_contains", которому передается подстрока для поиска:
https://frl2qid4.directus.app/items/products?fields=id,name&filter[name][_contains]=Изделие&access_token=наш_токен
При запросе по данному URL сервер вернет все элементы, поле name которых содержит значение "Изделие" (поиск регистрозависим, тмк что поля со словом "изделие" возвращены не будут)
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ КОЛЛЕКЦИИ ЗНАЧЕНИЕ УКАЗАННОГО ПОЛЯ КОТОРЫХ НАЧИНАЕТСЯ С УКАЗАННОГО ТЕКСТА
Для этих целей используется оператор _starts_with:
В ответе на данный запрос вернутся все элементы, значение поля name которых начинается с "Год". Работает с текствыми полями.
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ КОЛЛЕКЦИИ, ЧИСЛОВОЕ ЗНАЧЕНИЕ УКАЗАННОГО ПОЛЯ КОТОРЫХ БОЛЬШЕ ЧЕМ УКАЗАННОЕ В ЗАПРОСЕ
Перейдем к числам — для выборки будем использовать оператор "_gt". В коллекции products имеется поле price, в котором указана цена бредопродукта. Давайте получим элементы, у которых цена более 900 каких-то денежных единиц:
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ КОЛЛЕКЦИИ, ЧИСЛОВОЕ ЗНАЧЕНИЕ УКАЗАННОГО ПОЛЯ КОТОРЫХ МЕНЬШЕ ЧЕМ УКАЗАННОЕ В ЗАПРОСЕ
Для этого варианта фильтра применим оператор "_lt". Получим элементы, у которых цена меньше 200 денежных единиц:
ПОЛУЧЕНИЕ ЭЛЕМЕНТОВ КОЛЛЕКЦИИ УКАЗАННОЕ ПОЛЕ КОТОРЫХ СОДЕРЖИТ ЗНАЧЕНИЕ 1 И ЧИСЛОВОЕ ПОЛЕ БОЛЬШЕ ЧЕМ ЗНАЧЕНИЕ 2
А здесь мы будем ипользовать сразу 2 фильтра:
https://frl2qid4.directus.app/items/products?filter[name][_contains]=Изделие&filter[price][_gt]=800&access_token=наш_токен
Первый фильтр "filter[name][_contains]=Изделие" выбирает данные по текстовому полю, а вторым фильтром "filter[price][_gt]=800"? мы уточням, что нам нужны данные у которых значение поля price больше 800. Сюда же можно прикрутить и третмй, и четвертый фильтры.
Если в коллекции отсутствуют данные, соответствующие параметрам фильтрации (или запросу без фильтра), север возвращает пустой JSON массив:
JSON:
{"data":[]}
ИМПОРТ/ЭКСПОРТ КОЛЛЕКЦИЙ
Через web
Доступен экспорт в .csv, json, xml. Так же можно выбрать поля, которые нужно экспортировать и указать количество экспортируемых элементов. Через API тоже можно.
ЗАКЛЮЧЕНИЕ
Я не озвучил довольно много возможностей, присутствующих из коробки в Directus — это и вебхуки, и сортировка возвращаемых данных, и возможность создания собственных эндпоинтов, создание коллекций со сложными связями, алиасы, offset...
Информация — это современная валюта, а возможность быстро обработать ее после получения — незаменимое конкурентное преимущество.
Как мне видится, практически мгновенное развертывание API в сочетании с такими мощными возможностями может существенно снизить время на разработку и пригодиться как для проверки каких-то гипотез, так и для повседневного использования в рабочих проектах в качестве альтернативы спискам, google-таблицам и прочим exel-ям даже в бесплатном варианте Directus.cloud.
ССЫЛКИ
Стартовая страница документации Directus https://docs.directus.io/getting-started/introduction.html
Коллекции Directus https://docs.directus.io/reference/system/collections.html#collections
Поля коллекций https://docs.directus.io/reference/system/fields.html#fields
Элементы коллекций https://docs.directus.io/reference/items.html#accessing-items
- Тема статьи
- Нестандартные хаки
- Номер конкурса статей
- Восемнадцатый конкурс статей
Вложения
-
25,9 КБ Просмотры: 122
Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...
Для того чтобы запустить шаблон, откройте нужную программу. Нажмите кнопку «Добавить», и выберите файл проекта, который хотите запустить.
Подробнее о том, где и как выполняется проект.
Последнее редактирование модератором: