Problem (BaseX 12) serializing a map with json:serialize() in combination with the http-client module

Tuesday, 8 July 2025 · 6 messages
AN
Andreas Hengsbach | nexoma8 Jul 2025 12:03 #

Hi everyone,

I have found a problem when serializing a map to JSON.

I use the following map as request body for the http-client:

map { 'username' : "aaa", 'password' : "bbb", 'grant_type' : 'password' } => json:serialize()

In 10.4 everything works fine. In 12.0 this now leads to an error when I send the request. (Response from service: <code type="number">400</code><message>Invalid json message received</message>)

It seems that the request body is being escaped twice when interacting with the http client. If I omit json:serialize(), it works fine in BaseX 12.

I would expect json:serialize() to recognize the map(*) data type and serialize it correctly.

Best regards Andreas

AH
Andreas Hengsbach8 Jul 2025 12:32 #

btw: I found out that this leads directly to an exception.

map { 'username' : "aaa", 'password' : "bbb", 'grant_type' : 'password' } => inspect:type()

AH
Andreas Hengsbach8 Jul 2025 14:52 #

Hello, it's me again.

I can't actually find a way to transport a JSON as a request body except with a map, which obviously always has a json representation as well.

My current workaround for my code base is to convert the serialized form back into a map using xquery:eval.

let $requestBody := element { 'json' } {
    attribute { 'type' } { 'object' },
    element { 'the' } {
      attribute { 'type' } { 'object' },
      element { 'shit' } {
        attribute { 'type' } { 'object' },
        element { 'is' } {
          attribute { 'type' } { 'array' },
          element { '_' } {
            attribute { 'type' } { 'object' },
            element { 'on' } {
              attribute { 'type' } { 'object' },
              element { 'the' } {
                "steam"
              }
            }
          },
          element { '_' } {
            attribute { 'type' } { 'object' },
            element { 'what' } {
              attribute { 'type' } { 'object' },
              element { 'the' } {
                "f..."
              }
            }
          }
        }
      }
    }
  }
  return $requestBody => json:serialize() => xquery:eval()
CG
Christian Grün8 Jul 2025 15:38 #

Hi Andreas,

Thanks for your observations. A new snapshot is available, containing the fix for the copy expression [1]; an updated version for inspect:type will follow soon (this bug is only due to the generatation of the output for the InfoView panel).

With regard to your third question: In a previous 11.x version of BaseX, the behavior of http:send-request was changed, making th explicite json:serialize call obsolete (it should have been better documented).

Here’s one way to send XML JSON representations to the server with the current version:

(: Query :)
http:send-request(
  <http:request method='post'><http:body media-type='application/json'/></http:request>,
  'http://localhost...',
  <json>a</json>
)
(: RESTXQ endpoint :)
declare %rest:path('test') %rest:POST('{$x}') function local:f($x) { };
Quoted text · Andreas Hengsbach · 38 lines
Von: Andreas Hengsbach <andreas.hengsbach at nexoma.de> Gesendet: Dienstag, 8. Juli 2025 14:52 An: basex-talk at mailman.uni-konstanz.de <basex-talk at mailman.uni-konstanz.de> Betreff: [basex-talk] Re: Problem (BaseX 12) serializing a map with json:serialize() in combination with the http-client module Hello, it's me again. I can't actually find a way to transport a JSON as a request body except with a map, which obviously always has a json representation as well. My current workaround for my code base is to convert the serialized form back into a map using xquery:eval. let $requestBody := element { 'json' } { attribute { 'type' } { 'object' }, element { 'the' } { attribute { 'type' } { 'object' }, element { 'shit' } { attribute { 'type' } { 'object' }, element { 'is' } { attribute { 'type' } { 'array' }, element { '_' } { attribute { 'type' } { 'object' }, element { 'on' } { attribute { 'type' } { 'object' }, element { 'the' } { "steam" } } }, element { '_' } { attribute { 'type' } { 'object' }, element { 'what' } { attribute { 'type' } { 'object' }, element { 'the' } { "f..." } } } } } } } return $requestBody => json:serialize() => xquery:eval()
GR
Gunther Rademacherin reply to Andreas Hengsbach, 8 Jul 2025, 12:328 Jul 2025 16:23 #

Hi Andreas,

thank you for reporting this, too. It is now being handled by https://github.com/BaseXdb/basex/pull/2456

Best regards, Gunther

Quoted text · Andreas Hengsbach · 13 lines
> Gesendet: Dienstag, 8. Juli 2025 um 12:32 > Von: "Andreas Hengsbach" <andreas.hengsbach at nexoma.de> > An: basex-talk at mailman.uni-konstanz.de > Betreff: [basex-talk] Re: Problem (BaseX 12) serializing a map with json:serialize() in combination with the http-client module > > btw: I found out that this leads directly to an exception. > > map { > 'username' : "aaa", > 'password' : "bbb", > 'grant_type' : 'password' > } => inspect:type() >
AH
Andreas Hengsbachin reply to Christian Grün, 8 Jul 2025, 15:388 Jul 2025 17:20 #

Oh boy...

I could have had that quicker. I never tried to put it non-serialized in the request-body and was convinced that it had something to do with the new construction of maps.

But I would actually consider that a groundbreaking change, because if the request-body receives already serialized data, it arrives incorrectly at the endpoint.

You wrote that it could have been better documented. I have just searched in vain for a reference to these changes.

I would like to suggest that this be included in the changelogs or displayed more prominently there.

Anyway, thanks Christian for the clarification. It saves me a lot of trouble.

Beste regards, Andreas


⚡Generated with XQuery