so, I have a RESTful endpoint POST /token
that receives a body with username
and password
keys and return an auth token.
I wanted the following rules to be true:
1. if there is an invalid json, return 400 (malformed)
2. if the json is valid, but there’s no username or no password, or they’re not strings (spec check), then return 422 (unprocessable entity);
3. if everything is valid, but username/password match are not found in database, return 401 (unauthorized).
I have two doubts about this: from an HTTP/REST perspective, is this right? and if it is, how would I implement it in liberator? the authorized?
decision comes before processable?
, so the only way I can see this working is doing the whole logic inside post!
or sth like that
I could throw 404 instead of 401 as well and it should work...
it kinda makes sense, as the resource token
really does not exist for that username+password. but it feels hacky
you’ve got two options to “flip” the order of authorized?
and processable?
@caio you can parse the body in authorized?
and in case that fails, return true
and store a flag in the context, e.g. {::parse-json-failes? true}
. In processable?
check for that flag.
the other way is to defer the authorization check until processable?
and return a response with a (forced) status code 401. Simply return (ring-response {:your-normal “response”} {:status 401})
. This anything in the second map overrides what liberator would generate in the ring response
But that's hacking the state machine. The need to hack it to make it work seems like a bad sign
the state mashine is opinionated. that’s ok 🙂
I, personally, would return 422 if the json is unprocessable.
yeah my feeling’s always been that malformed was for the HTTP request itself, not the body… but all said and done it’s pretty arbitrary
Idk. If the content type is application/json and the body nontains invalid json, I'd say it's malformed (maybe the body is a valid XML and the content type header is the wrong one - there's no way for the backend to know)
If you can parse the json, you have an entity. If it's missing required fields, then it's unprocessable, even though it's a valid entity
But yeah, the standards are really broad. The unauthorized really seems like a stretch (there're no auth headers), but 422 also looks bad: the credentials were processed, it's just that there were no user to generate a token from
Meh. I think I'll return 418 - I'm a teapot
Does liberator have support for that? 😂
:teapot?
decision handler
Nope. But you can once again use ring-response
to force a status code. Yada supports it imho.