Fork me on GitHub

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.