[Feedback requested] WIP: Add HEAD handling to router and controller #273
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is an initial implementation of #269, looking for feedback. Things I think should be added before this PR is ready to merge:
1. Using
get_head
in the same router as eitherget
orhead
is probably programmer error, as one of those handlers will trump the other one.The way I wrote it,
get_head
is checked afterget
andhead
. So if you specify bothget
andget_head
, but nothead
, in a router, then all GET requests will be handled by theget
handler, and HEAD requests will be handled by theget_head
handler. If you specify bothhead
andget_head
, but notget
, then HEAD requests will be handled by thehead
handler while GET requests will be handled by theget_head
handler. And if you specify all three, then theget_head
handler will never be called.I don't think the computation expression syntax will allow us to throw up a compile-time error if
get_head
is present in the same router as eitherget
orhead
, but a runtime warning might be a good idea, as well as a note in the documentation.2.
exists
in controller currently doesn't dictate return type. Should it dictate a return type ofbool
? Or rather,Task<bool>
?If
exists
is written in the way I currently have it, where it handles a generic return type called'ExistsOutput
, then the user is responsible for turning "Yes, the item exists" into a 200 OK response, and "No, it doesn't exist" into a 404 NOT FOUND response. (Or there might be other responses desired, such as 403 FORBIDDEN in some cases). If we change theexists
operation to expect a function returningTask<bool>
, then the user just has to return true (which Saturn would change to 200 OK) or false (which Saturn would change to 404 NOT FOUND). Simpler for the user, but someone wanting to return 403 FORBIDDEN would have to do that in a controller plugin since theexists
operation wouldn't do it for him.I'm leaning towards saying that the
exists
operation should expect a function returningTask<bool>
, and then Saturn will take care of turning that into a 200/404 response. Would welcome feedback on this one.3. Unit tests are a good idea, and I haven't written them yet. Should test, among other things:
get_head
handles both GET and HEAD requests, and HEAD requests end up with bodiless responses thanks to what ASP.NET does for you. (That last part might be more of an acceptance test)get_head
in same router ashead
:head
handles HEAD requests whileget_head
handles GET requestsget_head
in same router asget
:get
handles GET requests whileget_head
handles HEAD requestsexists
in controller4. Saturn documentation needs to be updated to document the new
head
andget_head
operations in router CEs andexists
in controller CEs.I won't be able to work on documentation for a week or two, I think. If someone else wants to do it before then, I'd welcome the help.