Response: унификация ответов
Response – библиотека унификации ответов для clojure.
Ответ – результат исполнения вычислительного процесса, представленный в виде данных, независимый от языка разработки.
Неисправность – ответ, возникший в результате негативных или не запланированных последствий.
Библиотека предоставляет следующие возможности:
-
Создание положительных и отрицательных типов ответов (неисправностей) в виде структуры данных, независимо от языка разработки;
-
Проверочные функции, макросы, работающие с ответами;
-
Расширяемость. Возможность создания собственных положительных и отрицательных типов ответов;
-
Преобразование ответов в Ring-структуру, с соответствующим HTTP-кодом.
Семантические коды ответов
При взаимодействии в распределенной среде разработчики часто используют типы ошибок, привязанные к языку программирования или придумывают цифровые коды ошибок, как например в HTTP 1xx, 2xx, и т.д.
Данная библиотека предлагает использовать семантические коды ответов. Большинство ошибок в распределённой среде сводятся к следующим семантическим категориям ответов:
Категория ответа |
Семантика |
Повторный вызов |
Метод исправления |
"success" |
Запрос успешно выполнен. |
Нет |
Нет |
"incorrect" |
Запрос содержит неверные параметры или данные запроса. |
Нет |
Необходимо устранить ошибки в параметрах запроса или данных на стороне отправителя. |
"unsupported" |
Запрос содержит неподдерживаемый метод, протокол или версию API на стороне получателя. |
Нет |
Отправителю необходимо устранить ошибки в запросе. Например, уточнить версию API или имя метода или использовать правильный протокол. |
"unauthorized" |
Запрос отклонён, т.к. отправитель не предоставил получателю сведения о правах доступа. Например: не предоставлен токен доступа, анонимная или устаревшая сессия при вызове. |
Нет |
Отправителю необходимо создать сессию или представить данные для авторизации (например токен), или совершить предварительные действия для предоставления получателю сведений о правах доступа отправителя. |
"forbidden" |
Запрос отклонён, т.к. отправителю явно запрещено выполнение данного запроса (нет прав). |
Нет |
Отправителю необходимо получить права доступа на выполнение данного запроса или предоставить другие данные для авторизации. |
"unavailable" |
Получатель сейчас недоступен и не может обработать запрос. |
Да |
Отправителю необходимо убедиться, что получатель работает нормально (если это возможно) и повторить запрос позднее. |
"not found" |
Запрашиваемые данные отправителем не найдены у получателя. |
Нет |
Отправителю необходимо уточнить параметры запроса. Например, уточнить идентификатор запрашиваемой сущности или изменить условия запроса. |
"conflict" |
Запрос содержит конфликтующие данные, которые не могут быть приняты получателем. |
Нет |
Отправителю необходимо синхронизировать конфликтные данные с получателем. Например, уточнить версию сущности данных в БД, исправить метку времени, проверить существование записи данных и т.д. |
"busy" |
Запрос не может быть обработан в данный момент, т.к. не хватает ресурсов у получателя или он загружен другой работой. |
Да |
Отправителю необходимо повторить запрос позднее. |
"error" |
Общая ошибка при выполнении запроса. Запрос содержит испорченные данные, которые не могут быть прочитаны получателем или ошибка в канале связи. |
Нет |
Отправителю необходимо устранить ошибки в запросе или проверить канал связи до получателя. |
"interrupted" |
Запрос прерван на стороне отправителя. |
Да |
Отправитель может послать запрос заново. |
Проект org.rssys/response создан на основе Шаблона библиотеки.
Перед началом работы с проектом см. раздел Установка зависимостей.
Подключение библиотеки
В файл CLI/deps.edn добавьте в секцию :deps {…} координаты:
org.rssys/response {:git/tag "v0.1.1" :git/sha "c0ed55c" :git/url "https://gitflic.ru/project/red-stars-systems/response.git"}
Использование библиотеки
Для работы с библиотекой необходимо выполнить импорт.
(require '[org.rssys.response :as r])
;; Обычные данные не являются неисправностями
(every? r/success? [123 [] nil {:a 1} (Object.)])
;; => true
;; Исключение является неисправностью
(r/problem? (Exception.))
;; => true
(r/success? (Exception.))
;; => false
Реестр неисправностей
По-умолчанию, библиотека содержит следующий реестр неисправностей:
:busy
:conflict
:error
:forbidden
:incorrect
:interrupted
:not-found
:unauthorized
:unavailable
:unsupported
Для расширения реестра неисправностей необходимо их добавить:
(swap! r/*registry conj :another.company/incorrect)
После этого:
(-> (r/as :another.company/incorrect :my-data) r/problem?) ;; => true
Положительные ответы
В библиотеке предусмотрены конструкторы положительных ответов:
;; В качестве `x` может быть любое значение, включая nil, структура данных или объект
(def x 123)
(r/as-success x) ;; => #response[:success 123]
(r/as-accepted x) ;; => #response[:accepted 123]
(r/as-created x) ;; => #response[:created 123]
(r/as-deleted x) ;; => #response[:deleted 123]
(r/as-found x) ;; => #response[:found 123]
(r/as-updated x) ;; => #response[:updated 123]
Любые данные не являются неисправностью:
(-> (r/as :my-type :my-data) r/problem?) ;; => false
Конструкторы неисправностей
В библиотеке предусмотрены стандартные конструкторы неисправностей:
;; В качестве `x` может быть любое значение, включая nil, структура данных или объект
(def x 123)
(r/as-error x) ;; => #response[:error 123]
(r/as-not-found x) ;; => #response[:not-found 123]
(r/as-busy x) ;; => #response[:busy 123]
(r/as-conflict x) ;; => #response[:conflict 123]
(r/as-incorrect x) ;; => #response[:incorrect 123]
(r/as-forbidden x) ;; => #response[:forbidden 123]
(r/as-interrupted x) ;; => #response[:interrupted 123]
(r/as-unauthorized x) ;; => #response[:unauthorized 123]
(r/as-unavailable x) ;; => #response[:unavailable 123]
(r/as-unsupported x) ;; => #response[:unsupported 123]
Получение Ring-структур
(require '[org.rssys.response.http :as http])
(http/as-http (r/as-success {:a 1})) ;; => {:status 200 :headers {} :body {:a 1}}
(http/as-http (r/as-not-found 123)) ;; => {:status 404 :headers {} :body 123}
;; Для Ring-структур можно задавать заголовки через метаданные
(http/as-http (with-meta (r/as-unauthorized) {:http/headers {:location "http://aaa.bbb"}}))
;;=> {:status 401
;; :headers {:location "http://aaa.bbb"}
;; :body nil}
Примеры использования
(:type (r/as-created 123)) ;; => :created
(:data (r/as-created 123)) ;; => 123
(r/as-not-found 123) ;; => #response[:not-found 123]
(r/problem? (r/as-not-found 123)) ;; => true
(r/problem? (r/as-created 123)) ;; => false
@(r/as-created 123) ;; => 123
(-> (r/as-created 123) (with-meta {:a 1}) (meta)) ;; => {:a 1}
(r/safe (/ 1 0) #(r/as-error (ex-message %))) ;; => #response[:error "Divide by zero"]
(r/-> 42 inc r/as-error inc) ;; => #response[:error 43]
(r/->> 44 inc r/as-error inc) ;; => #response[:error 45]
Раздел для разработчиков
Цели проекта
Для настройки целей проекта используйте файлы bb.edn
и build.clj
.
Для вывода списка целей проекта запустите команду bb tasks
:
clean Очистить содержимое папки target
build Собрать дистрибутив библиотеки в виде jar файла
install Установить локально jar файл (требуется pom.xml файл)
deploy Опубликовать jar файл в публичный репозиторий
release Сделать выпуск: присвоить тэг выпуска, сделать сборку, опубликовать в репозиторий
test Запустить тесты
repl Запустить Clojure REPL
outdated Проверить устаревшие зависимости
outdated:fix Проверить устаревшие зависимости и обновить
format Форматировать исходный код
lint Проверить исходный код линтером
docmd Конвертация README.adoc в Markdown формат
requirements Установить зависимости необходимые проекту
Установка зависимостей
Для работы над проектом необходимо однократно выполнить установку зависимостей в среде Alt Linux p10.
Получение прав sudo
Установка разрешения на запуск sudo
для текущего пользователя:
SUDO_USER=`whoami`; su -c "echo '$SUDO_USER ALL=(ALL:ALL) ALL' > /etc/sudoers.d/$SUDO_USER"
Установка Babashka
-
Скачать и распаковать babashka:
-
Для aarch64
curl -O https://cdn01.rssys.org/babashka/babashka-1.3.186-linux-aarch64-static.tar.gz tar xvf babashka-1.3.186-linux-aarch64-static.tar.gz
-
для amd64/x86_64:
curl -O https://cdn01.rssys.org/babashka/babashka-1.3.186-linux-amd64-static.tar.gz tar xvf babashka-1.3.186-linux-amd64-static.tar.gz
-
-
Установка babashka:
sudo mv ./bb /usr/local/bin/ rm -f bb babashka*
Установка JDK
Скрипт установки автоматизирует установку OpenJDK 21 в ОС Alt Linux.
jdk21-install.sh
bb <(curl -s https://cdn01.rssys.org/bin/install-jdk.bb)
Установка bb как утилиты clojure
Скрипт установки автоматизирует установку babashka
в качестве утилиты clojure
и clj
install-deps.sh
bb <(curl -s https://cdn01.rssys.org/bin/install-clj.bb)
Установка инструмента управления шаблонами
Установка инструмента работы с шаблонами Leiningen/Boot/clj-template deps-new
clojure -Ttools install io.github.seancorfield/deps-new '{:git/tag "v0.5.2"}' :as new
Данный инструмент будет установлен в каталог ~/.gitlibs/libs/
Лицензия
© 2023 Михаил Ананьев.
Данный проект распространяется под Открытой лицензией на программное обеспечение РЭД СТАРС СИСТЕМС 1.0
Текст лицензии находится в файле LICENSE или по ссылке.
Описание
Библиотека организации единообразной структуры ответа в программе