Недавно я решил включить документацию Swagger в нашу заявку. Хотя Swagger предоставляет инструменты, помогающие клиентам интегрироваться с вашим REST API, наиболее мощная функция, на мой взгляд, заключается в том, что он действует как «живая документация» для API. Добавление Swagger в мое приложение имело несколько приятных побочных эффектов:
Идиоматическое Clojure поощряет использование структур данных, таких как карты. Это работает очень хорошо, потому что перевод JSON в / из Clojure Map, и постоянство становится прямым, независимо от того, используете ли вы org.clojure / java.jdbc или сохраняете базу данных документов, такую как MongoDB. Однако проблема с этим подходом заключается в том, что понимание ваших сущностей становится трудным. Для этого вам часто приходится прибегать к DDL, а в случае некоторых баз данных у вас может даже не быть этого. В случаях, когда вы используете миграции — ваш DDL может быть разбросан по многим миграциям с течением времени. Поддержка Swagger, предоставляемая metosin / compojure-api, использует призму / схему для определения вашего API. Вот пример того, как «Активность» и список «Активностей» выглядят в приложении «Мои ведомости»:
1
2
3
4
5
6
7
|
(def Activity { :id s/Num :name s/Str :description s/Str :activitytype (s/ enum "Daily" "Hourly" ) }) (def Activities [Activity]) |
Призматическая схема предоставляет другие функции, такие как необязательность атрибутов, необязательность значений, настраиваемые типы схем и т. Д. См. README для получения дополнительной информации.
Теперь, когда у меня есть единственное место, куда я могу пойти, чтобы полностью понять, как выглядят мои сущности / объекты-значения. Те же объекты / значения-объекты используются в моих определениях маршрута для определения REST API.
1
2
3
4
5
6
7
8
9
|
(GET* "/activity" [] : return Activities :summary "All activities in the system" (ok (auth #(controller/get-activities)))) (PUT* "/activity" [] :body [activity Activity] :summary "Update an activity" (ok (auth #(controller/update-activity activity)))) |
Здесь я создаю два маршрута для запросов GET и PUT HTTP. В случае GET я верну активность, а в случае PUT ожидаю активность в теле и ничего не верну. В обоих случаях я возвращаю HTTP-код ОК. Вызов «auth» позволяет мне аутентифицировать пользователя до того, как будет выполнен вызов на контроллер. API Compojure может генерировать полный интерфейс Swagger, позволяя разработчикам-клиентам исследовать и вызывать API (если, конечно, у них есть правильный доступ!).
Сгенерированный интерфейс Swagger выглядит следующим образом.
API Compojure проверяет каждый запрос / ответ на соответствие модели, так что любое нарушение API приведет к сбою. Это подводит меня ко второму побочному эффекту; Вы можете проверить модель по вашим тестам! В моем случае я проверяю модель по моим контроллерам:
1
2
3
4
5
|
(defn ^:always-validate get-activities :- Activities [] (model/get-activities)) (defn ^:always-validate update-activity [activity :- Activity] (model/update-activity activity)) |
Использование метаданных ^:always-validate
проверит мои тесты по модели. В этом случае мои функциональные тесты тестируют систему от контроллеров до базы данных, что позволяет мне применять схему во время сборки.
Clojure — это динамический язык. Одна из его основных критических замечаний — отсутствие типов. Хотя проект Typed Clojure проделал хорошую работу, я думаю, что библиотека Prismatic Schema обеспечивает очень хороший компромисс, и тот факт, что она прекрасно сочетается с Swagger, является обледенением.
Ссылка: | Схемы Clojure (Prismatic) — это Swagger от нашего партнера JCG Mashooq Badar из блога Crafted Software . |