Skip to content

Migration from Swagger 1.2 to 2.0

Michael Blume edited this page May 6, 2015 · 13 revisions

Do I have to do this?

Compojure-api version before 0.20.0 use the Swagger 1.2 format while 0.20.0 and above use Swagger 2.0. So, if you have a web-api using pre 0.20.0, this is for you.

Everything explodes?

Should not, the deprecated macros are still there and old swagger-parameters are mapped to new ones, but these all will be removed later on you should upgrade now. All deprecated things will cause warnings to STDOUT, either at compile-time (swaggered-macro) or at runtime (the swagger-docs-parameters).

One thing, that might happen is that Schema names clash. In Swagger 1.2, all Schemas were scoped only to a single api. With Swagger 2.0, all apis share same Schema definitions. So, if you had several apis that defined a Schema User with different values, they will clash. Ring-swagger sees this and throws a friendly exception at you:

java.lang.IllegalArgumentException: Looks like you're trying to define two models with the same name (User), but different properties: {:name java.langString} & {:nimi java.lang.String} This might happen if you anonymously manipulate a named schema (see #39). Extract to another named schema or use schema-tools.core -transformers.

Steps

Update the dependencies

Compojure-api

Clojars Project

Swagger-ui

Clojars Project

or latest from NPM

Compile your routes

by evaluating the defapis. There are two meta-data handlers that have changed. If you have used them, the route compilation fails. If it does, convert the new metadata-keys with the mapping below:

  • :nickname --> :operationId
  • :notes --> :description

Dry-run you app

Most probably your app now starts and if so, should works as before, but you are getting loads of warnings to STDOUT about the deprecated stuff.

Swagger 2.0 Information model

The swagger-docs input format has changed in align to the new spec. If you have defined any parameters to it, they should be changed.

Note: you can now pass any valid Swagger data in via swagger-docs. To ensure your data is valid swagger spec, you should validate it.

Old

(swagger-docs
  :title "Cool api"
  :apiVersion "1.0.0"
  :description "Compojure Sample Web Api"
  :termsOfServiceUrl "http://www.metosin.fi"
  :contact "[email protected]"
  :license "Eclipse 1.0"
  :licenseUrl "http://www.eclipse.org/legal/epl-v10.html")

New

(swagger-docs
  {:info {:title "Cool api"
          :version "1.0.0"
          :description "Compojure Sample Web Api"
          :termsOfService "http://www.metosin.fi"
          :contact {:name "Pizzaman"
                    :email "[email protected]"
                    :url "http://www.metosin.fi"}
          :license {:name "Eclipse 1.0"
                    :url "http://www.eclipse.org/legal/epl-v10.html"}})

The new version still supports the optional first string parameter - the path.

You should now get rid of the DEPRECATED: swagger-docs - :license is deprecated, see docs for details. -warnings.

Remove the swaggered-macro

Routes are collected now from the root, by the compojure.api.routes/api-root macro. If you use defapi, it does it for you. With 2.0, apis are categorized by tags, which can either be anonymous or defined. Defined tags are presented with the swagger-docs. Tags are set via meta-data either to endpoints or to mid-route via context*.

Old

(defapi app
  (swagger-ui)
  (swagger-docs)
  (swaggered "api"
    :description "the beer api"
    (context "/api" []
      (GET* "/ipa" []
        (ok {:sider false})))))

New with anonymous tags

(defapi app
  (swagger-ui)
  (swagger-docs)
  (context* "/api" []
    :tags ["api"]
    (GET* "/beer" []
      (ok {:sider false}))))

New with named tags

(defapi app
  (swagger-ui)
  (swagger-docs
    {:tags [{:name "api", :description "the beer api"}]})
  (context* "/api" []
    :tags ["api"]
    (GET* "/beer" []
      (ok {:sider false}))))

You should now get rid of the DEPRECATED: swaggered is deprecated and removed soon, see docs for details. warnings.

Clean up the defroutes* mess

With the awesome backtick, the #42 is finally fixed.

You don't now have to import all models from different files to the namespace where the defapi resides, just the defroutes* Vars as one would expect. Also, defroutes* are automatically referenced over a Var, so one can reload just those routes in a REPL and see the changed results. Swagger-routes are still re-calculated when the api-root is reloaded.

Finalizing

All is good when no DEPRECATED -warnings apper on STDOUT.

Publish

The new default swagger-spec location has changed from /api/api-docs to /swagger.json, so if your clients depend on the spec-url and you haven't specified it manually with swagger-docs, distribute the new uri.

Enjoy!