最近,我决定将Swagger文档包含到我们的时间表应用程序中。 尽管Swagger提供了可帮助客户与REST API集成的工具,但在我看来,最强大的功能是它充当API的“活动文档”。 将Swagger添加到我的应用程序中会产生一些令人愉快的副作用:
习惯用法Clojure鼓励使用诸如地图之类的数据结构。 之所以能很好地工作,是因为无论您是使用org.clojure / java.jdbc还是将其持久化到文档数据库(例如MongoDB),JSON都可以与Clojure Map进行双向转换,并且持久性会变得更加直接。 但是,这种方法的问题在于理解实体变得困难。 为此,您通常需要使用DDL,对于某些数据库,您甚至可能没有。 在使用迁移的情况下,随着时间的流逝,您的DDL可能分散在许多迁移中。 metosin / compojure-api提供的Swagger支持使用方括号 /模式来定义您的API。 这是我的时间表应用程序中的活动和活动列表的示例:
(def Activity {
:id s/Num
:name s/Str
:description s/Str
:activitytype (s/enum "Daily" "Hourly") })
(def Activities [Activity])
Prismatic Schema提供了其他功能,例如属性可选性,值可选性,自定义模式类型等。有关更多详细信息,请参见README 。
现在,我有了一个地方可以完全了解我的实体/值对象的外观。 在我的路由定义中使用了相同的实体/值对象来定义REST API。
(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 OK代码。 通过“ auth”调用,可以在对控制器进行调用之前对用户进行身份验证。 Compojure API可以生成完整的Swagger UI,允许客户端开发人员探索和调用该API(当然,如果他们具有正确的访问权限!)。
生成的Swagger UI如下所示。
Compojure API会针对模型验证每个请求/响应,以便任何违反API的操作都会导致失败。 这给我带来了第二个副作用。 您可以根据测试验证模型! 就我而言,我对照控制器验证了模型:
(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配合得很好,这锦上添花。
翻译自: https://www.javacodegeeks.com/2015/09/clojure-prismatic-schemas-are-swagger.html