Skip to content

Commit

Permalink
Merge pull request #41 from metosin/distinct_schemas
Browse files Browse the repository at this point in the history
Distinct schemas
  • Loading branch information
ikitommi committed Apr 13, 2015
2 parents 81e90fe + 555c71f commit 6986797
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 12 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
## x.x.x
## 0.19.5 (13.4.2015)

- throw `IllegalArgumentException` if multiple different schemas have a same name. Fixes [#39](https://github.com/metosin/ring-swagger/issues/39)
- drop import of `javax.servlet ServletContext`, causing reflection on Servlet Apps.
- updated dependencies:

```clojure
[prismatic/plumbing "0.4.2"] is available but we use "0.4.1"
[metosin/schema-tools "0.4.0"] is available but we use "0.3.0"
```

## 0.19.4 (8.4.2015)
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,25 @@ If ring-swagger can't transform the Schemas into JSON Schemas, by default a `Ill
can ignore the errors (missing schema elements will be ignored from
the generated JSON Schema).

### Model names

Prismatic Schema names are used to name the Swagger Body & Response models. Nested schemas are traversed and all found sub-schemas are generated automatically a name (so that they can be referenced in the JSON Schema).

If multiple such schemas have same name but have different value, an describive `IllegalArgumentException` is raised. This can happen if one transforms schemas via normal `clojure.core` functions:

```clojure
(s/defschema User {:id s/Str, :name s/Str})
(def NewUser (dissoc User :id))

(meta User)
; {:name Kikka}

(meta NewUser)
; {:name Kikka} <- fail!
```

There are better schema transformers functions available at [schema-tools](https://github.com/metosin/schema-tools).

### Adding support for custom Schema elements

JSON Schema generation is supported by the `ring.swagger.json-schema/json-type` multimethod. One can register own schema types by installing new methods for it's dispatch:
Expand Down
4 changes: 2 additions & 2 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject metosin/ring-swagger "0.19.4"
(defproject metosin/ring-swagger "0.19.5"
:description "Swagger Spec for Ring Apps"
:url "https://github.com/metosin/ring-swagger"
:license {:name "Eclipse Public License"
Expand All @@ -9,7 +9,7 @@
[cheshire "5.4.0"]
[slingshot "0.12.2"]
[metosin/ring-http-response "0.6.1"]
[metosin/schema-tools "0.3.0"]
[metosin/schema-tools "0.4.0"]
[prismatic/schema "0.4.0"]
[prismatic/plumbing "0.4.2"]
[clj-time "0.9.0"]
Expand Down
23 changes: 16 additions & 7 deletions src/ring/swagger/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,28 @@
(let [schemas (atom {})]
(walk/prewalk
(fn [x]
(when-let [schema (and
(plain-map? x)
(s/schema-name x))]
(swap! schemas assoc schema (if (var? x) @x x)))
(when-let [schema-name (and
(plain-map? x)
(s/schema-name x))]
(let [old-schema (@schemas schema-name)
schema (if (var? x) @x x)]
(when (and old-schema
(not= old-schema schema))
(throw
(IllegalArgumentException.
(str
"Looks like you're trying to define two models with the same name ("
schema-name "), but different properties: " old-schema " & " schema " "
"This might happen if you anonymously manipulate a named schema (see #39). "
"Extract to another named schema or use schema-tools.core -transformers."))))
(swap! schemas assoc schema-name schema)))
x)
x)
@schemas))

;; TODO: use keywords instead of symbols
(defn transform-models [schemas]
(->> schemas
(map collect-models)
(apply merge)
collect-models
(map (juxt key (comp transform val)))
(into {})))

Expand Down
3 changes: 1 addition & 2 deletions src/ring/swagger/swagger2.clj
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@

(defn transform-models [schemas]
(->> schemas
(map collect-models)
(apply merge)
collect-models
(map (juxt (comp str key) (comp transform val)))
(into {})))

Expand Down
7 changes: 7 additions & 0 deletions test/ring/swagger/swagger2_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,10 @@
"/resp" [:responses 203] identity #"Response.*" valid-reference
"/resp" [:responses 204] :items #"Response.*" (just {:items valid-reference , :type "array"})
"/resp" [:responses 205] :items #"Response.*" (just {:items valid-reference , :type "array", :uniqueItems true}))))

(fact "multipla different schemas with same name"
(let [model1 (s/schema-with-name {:id s/Str} 'Kikka)
model2 (s/schema-with-name {:id s/Int} 'Kikka)
swagger {:paths {"/body" {:post {:parameters {:body {:1 model1, :2 model2}}}}}}]
(fact "with defaults"
(validate swagger) => (throws IllegalArgumentException))))

0 comments on commit 6986797

Please sign in to comment.