Context
My app specification has a callback using expressions from x-www-form-urlencoded ({$request.body#/url}).
The URL parameter is not decoded from FORM Url-Encode (it works when using JSON)
Current Behavior
Callback not executed:
[15:34:01] › [CALLBACK] ℹ info actions: > Executing "post" callback to ?token=...
[15:34:01] › [CALLBACK] ✖ error actions: Request failed: Only absolute URLs are supported
Expected Behavior
The callback should execute the same way as it does for a JSON request.
[4:23:48 PM] › [CALLBACK] ℹ info actions: > Executing "post" callback to http://localhost:4011/notify?token=ssecurre...
[4:23:48 PM] › [CALLBACK] ✖ error actions: Request failed: request to http://localhost:4011/notify?token=ssecurre failed, reason:
(SSL error because of localhost env)
Possible Workaround/Solution
If I dump request, I can find custom path around my JSON:
{
method: 'post',
url: { path: '/invoices/123/subscribe', baseUrl: undefined, query: {} },
headers: {
host: '127.0.0.1:4010',
'user-agent': 'curl/8.7.1',
accept: '*/*',
'content-type': 'application/x-www-form-urlencoded',
'content-length': '57'
},
body: {
_tag: 'Right',
right: { url: 'http://localhost:4011/notify', token: 'ssecurre' }
}
}
(packages/http/src/mocker/callback/callbacks.ts:runCallback)
_tag and right are added by packages/http/src/validator/validators/body.ts:deserializeFormBody)
Steps to Reproduce
Use callback example and change application/json validation to x-www-form-urlencoded.
{
"openapi": "3.0.0",
"paths": {
"/invoices/{id}/subscribe": {
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The id of the invoice about which you want to receive notifications",
"schema": {
"$ref": "#/components/schemas/invoiceId"
}
}
],
"post": {
"summary": "Subscription to events about given invoice",
"requestBody": {
"required": true,
"content": {
"application/x-www-form-urlencoded": {
"schema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri"
},
"token": {
"type": "string"
}
},
"required": [
"url",
"token"
]
}
}
}
},
"responses": {
"202": {
"description": "Successfully subscribed to events about given invoice",
"content": {
"text/plain": {
"examples": {
"ok": {
"value": "ok"
}
}
}
}
}
},
"callbacks": {
"actions": {
"{$request.body#/url}?token={$request.body#/token}": {
"post": {
"summary": "Receive notification about certain invoice",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/notification"
}
}
}
},
"responses": {
"200": {
"description": "Notification successfully processed",
"content": {
"text/plain": {
"examples": {
"ok": {
"value": "ok"
}
}
}
}
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"invoiceId": {
"type": "integer",
"format": "int64"
},
"notification": {
"type": "object",
"properties": {
"invoiceId": {
"$ref": "#/components/schemas/invoiceId"
},
"action": {
"type": "string",
"enum": [
"paid",
"expired",
"failure"
]
}
},
"required": [
"invoiceId",
"action"
]
}
}
}
}
Run prism:
prism mock mock.json -v=trace
Launch curl:
curl -v -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "url=http://localhost:4011/notify" \
--data-urlencode "token=ssecurre" \
http://127.0.0.1:4010/invoices/123/subscribe
Environment
- Version used: 5.14.2
- Environment name and version: NodeJS v25.2.1
- Operating System and version (desktop or mobile): MacOS
Context
My app specification has a callback using expressions from x-www-form-urlencoded (
{$request.body#/url}).The URL parameter is not decoded from FORM Url-Encode (it works when using JSON)
Current Behavior
Callback not executed:
Expected Behavior
The callback should execute the same way as it does for a JSON request.
(SSL error because of localhost env)
Possible Workaround/Solution
If I dump request, I can find custom path around my JSON:
{ method: 'post', url: { path: '/invoices/123/subscribe', baseUrl: undefined, query: {} }, headers: { host: '127.0.0.1:4010', 'user-agent': 'curl/8.7.1', accept: '*/*', 'content-type': 'application/x-www-form-urlencoded', 'content-length': '57' }, body: { _tag: 'Right', right: { url: 'http://localhost:4011/notify', token: 'ssecurre' } } }(packages/http/src/mocker/callback/callbacks.ts:runCallback)
_tagandrightare added bypackages/http/src/validator/validators/body.ts:deserializeFormBody)Steps to Reproduce
Use callback example and change
application/jsonvalidation tox-www-form-urlencoded.{ "openapi": "3.0.0", "paths": { "/invoices/{id}/subscribe": { "parameters": [ { "name": "id", "in": "path", "required": true, "description": "The id of the invoice about which you want to receive notifications", "schema": { "$ref": "#/components/schemas/invoiceId" } } ], "post": { "summary": "Subscription to events about given invoice", "requestBody": { "required": true, "content": { "application/x-www-form-urlencoded": { "schema": { "type": "object", "properties": { "url": { "type": "string", "format": "uri" }, "token": { "type": "string" } }, "required": [ "url", "token" ] } } } }, "responses": { "202": { "description": "Successfully subscribed to events about given invoice", "content": { "text/plain": { "examples": { "ok": { "value": "ok" } } } } } }, "callbacks": { "actions": { "{$request.body#/url}?token={$request.body#/token}": { "post": { "summary": "Receive notification about certain invoice", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/notification" } } } }, "responses": { "200": { "description": "Notification successfully processed", "content": { "text/plain": { "examples": { "ok": { "value": "ok" } } } } } } } } } } } } }, "components": { "schemas": { "invoiceId": { "type": "integer", "format": "int64" }, "notification": { "type": "object", "properties": { "invoiceId": { "$ref": "#/components/schemas/invoiceId" }, "action": { "type": "string", "enum": [ "paid", "expired", "failure" ] } }, "required": [ "invoiceId", "action" ] } } } }Run prism:
Launch curl:
Environment