How to get a list of query parameters of request using web-server/http/request-structs

I am trying to get my head around writing simple web applications in Racket.

How do I get a list of query parameters sent as part of the request from the request struct, assuming the servlet below:

(define (first-page request)
  ; The line below prints all the bindings, but I would like to find only the 
  ; binding:form values that were sent through url query string.
  (println (request-bindings/raw request)) ; <- this prints all the bindings
  (http-response-str "<h1>This is the first page!</h1>"))

TIA
Rouan

I have a front-end which sends requests using URLSearchParams, and then extracts them with request-bindings. Idk if that gives you the separation you want, however; a quick test shows that my bindings come in as binding:form values.

(I do wish the docs offered alternatives for what they consider to be broken bindings extractors in section 4.2 Bindings of the Web Applications document.)

1 Like

Hello @benknoble ,
seems your links are broken (no URL and i can not clik on them) even if they display in blue. (or something wrong somewhere?) :thinking:
Regards,
Damien

Is it the post data you are after?

Not the post data.

Data from the query parameters:

http://localhost/first-page?name=rvd
                           ^^^^^^^^^

I do get a binding:form value of (binding:form #"name" #"rvd") by using the code:

(request-bindings/raw request)

But if I send some data using query parameters, and some data in the body with a POST request, everything ends up as binding forms with no way of distinguishing which values came from POST data and which came from query parameters.

The other issue as @benknoble mentioned is that the docs tell us about a couple of binding functions (4 HTTP: Hypertext Transfer Protocol) and then recommend that we don't use them but the docs do not tell us what the alternative is.

If you want just the query params in that case, you should be able to get them off of the request-uri.

Thanks @bogdan,

I guess I could do that. I can roll my own functions to use the request-uri to figure out which bindings are from the query parameters of the url and which bindings are POST bindings.

There is an edge case where it is possible to send the same key through POST and query parameters in the same request and both bindings show up with the same key. Now they are a bit harder to distinguish.

I guess I just expected what I am trying to do to be basic stuff built into the web server libraries from the start so I do not have to roll my own :slight_smile:

Sorry, I'm not sure I follow. The url struct you receive from request-uri will only contain the query params (and their values) sent in the URL. The bindings you get from request-post-data/raw will contain only the urlencoded data sent as the body of the request. So, you can exactly distinguish between body data and URI params by using those two fields. The request-bindings/raw field merges them because that's often pretty convenient. I agree that the APIs exposed here are not ideal (and I have my own helpers for this and related use cases), though.

1 Like

Ok, I had a look at request-post-data/raw. But it just gives me the unparsed key/values as a single stringy value. Where I could get separate key/value pairs from the bindings, which is more convenient :slight_smile:

So lets say I send some data through post:

curl -d 'name=rvd&filter=y' -X POST http://localhost:8000/first

If I go through the bindings I get the separate key/value pairs. Noice :slight_smile:

(request-bindings/raw request)
; => (list (binding:form #"name" #"rvd")
;          (binding:form #"filter" #"y"))

If I look at the post-data, I get back that 1 stringy value and would have to do the parsing myself:

(request-post-data/raw request)
; => #"name=rvd&filter=y"

@bogdan thanks for the link to koyo. That looks super interesting. Will have a look at that.

I guess the answers so far are:

  • use bindings if you don't have to care where the data comes from.
  • If you specifically want to look at URL query params or POST data, the data is there but process it yourself by writing some helper functions.

Thanks for pointing this out—Discourse ate the Markdown syntax in my email and tried to create "nested links" (like [my link text]([the-actual-link](the-actual-link))), which clearly don't work.

I've corrected the OP; mailing list readers may want to visit to see where the links go :sweat_smile:

2 Likes