Skip to content

In req_body_json, top level list elements are treated differently than lower level for NULL and empty values #115

@colmanhumphrey

Description

@colmanhumphrey

If our NULL or empty list is tucked within a list, we're good:

library(httr2)

url <- "http://httpbin.org/"
req <- request(url)

body <- req |>
    req_body_json(list(a=1, b=list(x=3,y=list()), c=list(x=2, z=NULL))) |>
    req_dry_run()

#> POST / HTTP/1.1
#> Host: httpbin.org
#> User-Agent: httr2/0.1.1 r-curl/4.3.2 libcurl/7.77.0
#> Accept: */*
#> Accept-Encoding: deflate, gzip
#> Content-Type: application/json
#> Content-Length: 47
#> 
#> {"a":1,"b":{"x":3,"y":[]},"c":{"x":2,"z":null}}

So y gives [] and z gives null (or {} if we set null = "list").

However, if these are top-level, they just get eliminated (and setting null has no effect):

library(httr2)

url <- "http://httpbin.org/"
req <- request(url)

body <- req |>
    req_body_json(list(y=list(), z=NULL, x=list(a=1, b=2))) |>
    req_dry_run()
#> POST / HTTP/1.1
#> Host: httpbin.org
#> User-Agent: httr2/0.1.1 r-curl/4.3.2 libcurl/7.77.0
#> Accept: */*
#> Accept-Encoding: deflate, gzip
#> Content-Type: application/json
#> Content-Length: 19
#> 
#> {"x":{"a":1,"b":2}}

This makes it hard to send an empty array to a REST API that requires it at the top level (or maybe I'm missing something).

This could be similar to #95, in that it's because of:

data <- modify_list(req$body$data, !!!data)

Session Info
> sessionInfo()
R version 4.1.2 (2021-11-01)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Monterey 12.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] jsonlite_1.7.2   httr2_0.1.1      conflicted_1.0.4

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.8.3     crayon_1.4.2     later_1.3.0      rappdirs_0.3.3  
 [5] R6_2.5.1         magrittr_2.0.1   rlang_1.0.2      cachem_1.0.6    
 [9] cli_3.1.0        curl_4.3.2       promises_1.2.0.1 tools_4.1.2     
[13] glue_1.5.1       httpuv_1.6.5     fastmap_1.1.0    compiler_4.1.2  

Metadata

Metadata

Assignees

No one assigned

    Labels

    body 🕺bugan unexpected problem or unintended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions