diff --git a/CHANGELOG.md b/CHANGELOG.md index 5144ae1e..ab78036e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - `stacked` is now ignored on chart types that cannot stack, instead of displaying an empty chart. - Screen readers now announce the title of the modal component instead of an unnamed dialog. - `sqlpage.request_body` and `sqlpage.request_body_base64` now return NULL when the request has no body. A body that cannot be read, such as one exceeding the payload limit, is now reported as an error instead of being silently replaced with an empty body. + - `sqlpage.fetch_with_meta` now correctly documents server JSON responses sent under `json_body`, not `body`. ## v0.45 diff --git a/examples/official-site/sqlpage/migrations/58_fetch_with_meta.sql b/examples/official-site/sqlpage/migrations/58_fetch_with_meta.sql index 296071d2..c406c3f7 100644 --- a/examples/official-site/sqlpage/migrations/58_fetch_with_meta.sql +++ b/examples/official-site/sqlpage/migrations/58_fetch_with_meta.sql @@ -11,7 +11,19 @@ VALUES ( 'Sends an HTTP request and returns detailed metadata about the response, including status code, headers, and body. This function is similar to [`fetch`](?function=fetch), but returns a JSON object containing detailed information about the response. -The returned object has the following structure: +When the response declares a `content-type` of `application/json`, the parsed body is returned under `json_body`: +```json +{ + "status": 200, + "headers": { + "content-type": "application/json", + "content-length": "1234" + }, + "json_body": { "name": "ditto" } +} +``` + +For every other content type, the body is returned as a string under `body`: ```json { "status": 200, @@ -19,8 +31,7 @@ The returned object has the following structure: "content-type": "text/html", "content-length": "1234" }, - "body": "a string, or a json object, depending on the content type", - "error": "error message if any" + "body": "..." } ``` @@ -42,8 +53,8 @@ where -- Extract data from the response json body select ''card'' as component; select - json_extract($response, ''$.body.name'') as title, - json_extract($response, ''$.body.abilities[0].ability.name'') as description + json_extract($response, ''$.json_body.name'') as title, + json_extract($response, ''$.json_body.abilities[0].ability.name'') as description from $response; ``` diff --git a/examples/official-site/your-first-sql-website/index.sql b/examples/official-site/your-first-sql-website/index.sql index fe380cdc..9c2460e0 100644 --- a/examples/official-site/your-first-sql-website/index.sql +++ b/examples/official-site/your-first-sql-website/index.sql @@ -23,7 +23,7 @@ SET req = '{ "timeout_ms": 200 }'; SET api_results = sqlpage.fetch_with_meta($req); -SET sqlpage_version = COALESCE(json_extract($api_results, '$.body.tag_name'), ''); +SET sqlpage_version = COALESCE(json_extract($api_results, '$.json_body.tag_name'), ''); SELECT 'hero' as component, 'Your first SQL Website' as title, diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 31823de8..0fd8d875 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -149,12 +149,21 @@ pub fn start_echo_server(shutdown: oneshot::Receiver<()>) -> (JoinHandle<()>, u1 let listener = std::net::TcpListener::bind("localhost:0").unwrap(); let port = listener.local_addr().unwrap().port(); let server = HttpServer::new(|| { - App::new().default_service(fn_service(|mut req: ServiceRequest| async move { - let meta = format_request_line_and_headers(&req); - let body = format_body(&mut req).await; - let resp = build_echo_response(body, meta); - Ok(req.into_response(resp)) - })) + App::new() + .route( + "/json", + web::to(|body: web::Bytes| async move { + HttpResponse::Ok() + .insert_header((header::CONTENT_TYPE, "application/json")) + .body(body) + }), + ) + .default_service(fn_service(|mut req: ServiceRequest| async move { + let meta = format_request_line_and_headers(&req); + let body = format_body(&mut req).await; + let resp = build_echo_response(body, meta); + Ok(req.into_response(resp)) + })) }) .workers(1) .listen(listener) diff --git a/tests/sql_test_files/data/fetch_with_meta_json_body.sql b/tests/sql_test_files/data/fetch_with_meta_json_body.sql new file mode 100644 index 00000000..a53f8328 --- /dev/null +++ b/tests/sql_test_files/data/fetch_with_meta_json_body.sql @@ -0,0 +1,5 @@ +set url = 'http://localhost:' || $echo_port || '/json'; +set fetch_req = '{"method":"POST","url":"' || $url || '","body":{"hello":"world"}}'; +set res = sqlpage.fetch_with_meta($fetch_req); + +select '"json_body":{"hello":"world"}' as expected_contains, $res as actual;