Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST API JSON Parsing in Racket

I'm developing rest service in Racket in educational purposes and facing problem with JSON parsing. I have POST request with following body

"{\"word\": \"a\", \"desc\": \"b\"}"

Also I have request handler for this request such as

 (define (add-word-req req)
     (define post-data (request-post-data/raw req))
     (display post-data)
     (newline)

     (define post-data-expr1 (bytes->jsexpr post-data))
     (display post-data-expr1)
     (newline)
     (display (jsexpr? post-data-expr1))
     (display (hash? post-data-expr1))
     (newline)

     (define post-data-expr (string->jsexpr "{\"word\": \"a\", \"desc\": \"b\"}"))
     (display post-data-expr)
     (newline)

     (display (hash? post-data-expr))
     (newline)

     (for (((key val) (in-hash post-data-expr)))
       (printf "~a = ~a~%" key val))

     (cond 
       [(jsexpr? post-data-expr)
       ;; some conditional work
       ...
      ]
       [else 
       ...]
      )
     )

As you can see, request body and hard-coded JSON are same.

While processing request I get next output:

 "{\"word\": \"a\", \"desc\": \"b\"}"
 {"word": "a", "desc": "b"}
 #t#f
 #hasheq((desc . b) (word . a))
 #t
 desc = b
 word = a

Body is transmitted in one piece and even transformed into jsexpr, but still it is not hash! And because of it I can't use hash methods for post-data-expr1.

What is the best way to get hash from such jsexpr? Or should I use another method to obtain key/values?

Regards.

like image 480
Bohdan Ivanov Avatar asked Mar 06 '26 16:03

Bohdan Ivanov


1 Answers

This program:

#lang racket
(require json)
(string->jsexpr "{\"word\": \"a\", \"desc\": \"b\"}")
(bytes->jsexpr #"{\"word\": \"a\", \"desc\": \"b\"}")

has the output:

'#hasheq((desc . "b") (word . "a"))
'#hasheq((desc . "b") (word . "a"))

This means that bytes->jsexpr ought to work.

Can you change:

 (define post-data (request-post-data/raw req))
 (display post-data)
 (newline)

to

 (define post-data (request-post-data/raw req))
 (write post-data)
 (newline)

?

I have a feeling that the contents of the byte string is slightly different than the one you use later on.

Note:

> (displayln "{\\\"word\\\": \\\"a\\\", \\\"desc\\\": \\\"b\\\"}")
{\"word\": \"a\", \"desc\": \"b\"}

> (displayln "{\"word\": \"a\", \"desc\": \"b\"}")
{"word": "a", "desc": "b"}

The output of your (display post-data-expr1) matches the first interaction above. My guess is therefore that both backslashes and quotes are escaped in your input.

like image 70
soegaard Avatar answered Mar 08 '26 21:03

soegaard