How do I fetch a URL in Racket?
The landscape for making HTTP requests in Racket is surprisingly fussy. There’s the
net/http library, which is built-in to Racket. And there’s the
http package. The former might be too simple for your needs, and the latter might seem too clumsy. What to do?
Why is it so hard to just fetch a URL?
To my knowledge, there’s currently no very simple, do-what-I-mean HTTP client for Racket. But here’s a simple code snippet that may help. After the code there’s a discussion of what this snippet is doing.
To use this function, load the code and then try:
(or any other URL, for that matter). The function has a simple interface. Only one argument is mandatory, namely, a URL. Reasonable assumptions are made about the low-level HTTP details (e.g., we assume that the HTTP method you want to use is GET), but you can change them by using suitable keyword arguments.
This code is based on Greg Hendershott’s
http package. That package is, in my judgment, the best candidate for an HTTP client for Racket.
http package isn’t built-in to Racket, so make sure you do raco pkg install http.)
There are a number of functions in the http package, but the two in focus here are
call/output-request. To decide which one you should use, ask yourself:
Do I need to send data along with my request?
If so (as is usually the case with HTTP POST and PUT), use the package’s
call/output-request function. If not (e.g., you’re just using GET, DELETE, OPTIONS), use
(A more general purpose function,
call/requests, is also available in the http package, but I find that function fussier to use. I prefer to use the two aforementioned functions instead.)
Here’s a simple invocation:
(call/input-request "1.1" "GET" "http://twofour54.com" empty read-entity/bytes)
Here’s a simple POST request:
(call/output-request "1.1" "POST" "http://twofour54.ae" #"abc" #f empty read-entity/bytes)
My code simply delegates to one of these two functions from the
http package, depending on a reasonable guess about what data you’d like to send. Namely, if it looks like you’re not trying to send any data, then we use
call/input-request. Otherwise, we use