reitit

https://cljdoc.org/d/metosin/reitit/ https://github.com/metosin/reitit/
Tanel 2020-06-05T06:30:26.056900Z

Not sure if this is a bug or not, but I have an endpoint that takes in an XML message as the whole body. I have the following route (with coercion):

["/foo" {:swagger {:tags ["foo"]
                       :consumes ["application/xml"]}}
     ["/bar"
      {:post {:parameters {:body string?}
              :handler foo/bar-handler}}]]
But calling the endpoint (either via swagger or directly) throws a spec error:
$ curl -v -X POST "<http://localhost:8080/foo/bar>" -H "accept: application/json" -H "Content-Type: application/xml" -d "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;&lt;foo&gt;1&lt;/foo&gt;" | jq .

{
  "spec": "(spec-tools.core/spec {:spec clojure.core/string?, :type :string, :leaf? true})",
  "problems": [
    {
      "path": [],
      "pred": "clojure.core/string?",
      "val": null,
      "via": [],
      "in": []
    }
  ],
  "type": "reitit.coercion/request-coercion",
  "coercion": "spec",
  "value": null,
  "in": [
    "request",
    "body-params"
  ]
}
Using some? or identity instead of string? also fail. Swagger shows correctly that this endpoint consumes XML though, with a nice empty XML template where you can fill in the body.

ikitommi 2020-06-05T07:08:58.060100Z

@tanel.kriik if you don’t have a middleware that reads the XML into :body-params that doesn’t work, as the params are nil. You can add the swagger parameter manually into endpoint with something like : :swagger {:parameters [{:in :body, :name "xml", :required true, :schema {}]]}and say (slurp (:body request)) to read the xml-string in your handler.

ikitommi 2020-06-05T07:09:49.061200Z

… or create a middleware that checks the content-type and for xml, slurps it and pushes the string into :body-params so that the parameter coercion can read it from there.