Get the original request, no matter where you are
Dude, where’s my request?
You know the feeling: you’re deep inside some code in your web application, far away from the place where you received the initial request, but you realize: Wait, what was the original request that brought me here? You left the original request behind a long time ago. How do you get it back?
You could be really disciplined and pass along the request to every function that has anything to do, potentially, with your web application. That way, any function that potentially needs the request has it, directly. That’s not wrong; indeed, one might say that that’s really
correct. But such an approach also has the downside of polluting your code with arguments that rarely get used. There might be lots of functions that take a request as input and simply pass it along.
Here’s one approach to the problem. The idea is to use a a wrapper handler, a function that receives the initial request, sets up some initial state, and passes it along to the
Along with a wrapper handler, the other ingredient in the solution under discussion is to use Racket parameters. Parameters allow you to access values that were set up outside of your lexical scope. That is to say, parameters are available to you even though they’re not actually arguments to your functions. (We’ve discussed parameters before, in the production-vs-development problem.)
Here’s how this can play out. Imagine that we have a wrapper handler,
start. The function
start takes the initial request. That’s the natural place to give the parameter its value. That’s done using
parameterize. But before all that, we need to define the parameter in the first place.
Here’s how you put those pieces together:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
If you are anywhere in your web code, access the original request using
original-request, like so:
1 2 3 4 5 6
(define (my-cool-function x y) (let ([req (original-request)]) ;; do something with the original request, ;; even though it wasn't given as an argument ;; to this function! ))
How to organize your parameters
From a code organization point of view, consider putting your parameters in a separate file, say, parameters.rkt:
1 2 3
And then, in your web code:
1 2 3 4
If you’re dealing with code that might be called outside the context of handling a request, it’s a good idea to check that the parameter really does contain an HTTP request. Use
request? for that:
1 2 3 4 5 6 7 8 9 10 11 12 13