compojure-api allows you to define the return
schema:
(s/defschema Pizza
{:name s/Str})
(GET "/pizza/:id" [id]
:return Pizza
:summary "returns a Pizza"
(ok (get-pizza id)))
My issue is when the get-pizza
fn returns a 404 {:status 404 :body {:message "Invalid id provided"}}
the response (to the requester) is that that 404 does not match the Pizza
schema:
{
"errors": {
"name": "missing-required-key",
"status": "disallowed-key",
"body": "disallowed-key"
}
}
The docs show that you can provide multiple response schemas but I am unclear on what my get-pizza
fn should return in order to utilize those schemas. Their example uses the ring-http-response lib to generate the return values, but there is no difference between my return value for get-pizza
and the ring-http-response 'not found' fn.
Truthfully I would rather not use the :responses
param if possible because I can already foresee all the code duplication. Before specifying the :return
Schema I was able to have my get-pizza
fn return a 404 and be correctly passed onto the requester but once I added the Schema I was no longer able to do that. I considered having the return value be :return (s/one Pizza Error)
where Error
would be a generically defined error map but I don't see why I would do this for every route if all calls could in theory return a 500.
Note: The reason I switched to utilizing the :return
param is that it makes the generated swagger-ui docs much prettier & easier to understand.
You have a small issue in your code I assume as you didn't show implementation of your
get-pizza [id]
function.You return
{:status 404 :body {:message "Invalid ID provided}}
which is then wrapped into HTTP 200 response by(ok (get-pizza id))
.Your
get-pizza
function should return a pizza or nil if not found. Your HTTP response should be generated based on that in your route:The original example from compojure-api repo has a bit different implementation where for
nil
values fromget-pizza
it will still return HTTP 200 response with empty response body. According to your question you would return 404 instead and the code above should meet your requirement.