Merge pull request #198 from jhallbachner/json

Add BodyFormat Selector and Support Json-Encoded Api Requests In Sandbox
This commit is contained in:
William Durand 2013-06-18 06:46:45 -07:00
commit 01044bb7ac
6 changed files with 80 additions and 5 deletions

View File

@ -46,6 +46,10 @@ class Configuration implements ConfigurationInterface
->scalarNode('enabled')->defaultTrue()->end() ->scalarNode('enabled')->defaultTrue()->end()
->scalarNode('endpoint')->defaultNull()->end() ->scalarNode('endpoint')->defaultNull()->end()
->scalarNode('accept_type')->defaultValue('')->end() ->scalarNode('accept_type')->defaultValue('')->end()
->enumNode('body_format')
->values(array('form', 'json'))
->defaultValue('form')
->end()
->arrayNode('request_format') ->arrayNode('request_format')
->addDefaultsIfNotSet() ->addDefaultsIfNotSet()
->children() ->children()

View File

@ -34,6 +34,7 @@ class NelmioApiDocExtension extends Extension
$container->setParameter('nelmio_api_doc.sandbox.endpoint', $config['sandbox']['endpoint']); $container->setParameter('nelmio_api_doc.sandbox.endpoint', $config['sandbox']['endpoint']);
$container->setParameter('nelmio_api_doc.sandbox.request_format.method', $config['sandbox']['request_format']['method']); $container->setParameter('nelmio_api_doc.sandbox.request_format.method', $config['sandbox']['request_format']['method']);
$container->setParameter('nelmio_api_doc.sandbox.accept_type', $config['sandbox']['accept_type']); $container->setParameter('nelmio_api_doc.sandbox.accept_type', $config['sandbox']['accept_type']);
$container->setParameter('nelmio_api_doc.sandbox.body_format', $config['sandbox']['body_format']);
$container->setParameter('nelmio_api_doc.sandbox.request_format.default_format', $config['sandbox']['request_format']['default_format']); $container->setParameter('nelmio_api_doc.sandbox.request_format.default_format', $config['sandbox']['request_format']['default_format']);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));

View File

@ -50,6 +50,11 @@ class HtmlFormatter extends AbstractFormatter
*/ */
private $acceptType; private $acceptType;
/**
* @var string
*/
private $bodyFormat;
/** /**
* @var array * @var array
*/ */
@ -108,6 +113,14 @@ class HtmlFormatter extends AbstractFormatter
$this->acceptType = $acceptType; $this->acceptType = $acceptType;
} }
/**
* @param string $bodyFormat
*/
public function setBodyFormat($bodyFormat)
{
$this->bodyFormat = $bodyFormat;
}
/** /**
* @param string $method * @param string $method
*/ */
@ -179,6 +192,7 @@ class HtmlFormatter extends AbstractFormatter
'enableSandbox' => $this->enableSandbox, 'enableSandbox' => $this->enableSandbox,
'requestFormatMethod' => $this->requestFormatMethod, 'requestFormatMethod' => $this->requestFormatMethod,
'acceptType' => $this->acceptType, 'acceptType' => $this->acceptType,
'bodyFormat' => $this->bodyFormat,
'defaultRequestFormat' => $this->defaultRequestFormat, 'defaultRequestFormat' => $this->defaultRequestFormat,
'date' => date(DATE_RFC822), 'date' => date(DATE_RFC822),
'css' => file_get_contents(__DIR__ . '/../Resources/public/css/screen.css'), 'css' => file_get_contents(__DIR__ . '/../Resources/public/css/screen.css'),

View File

@ -259,6 +259,10 @@ configure this sandbox using the following parameters:
enabled: true # default: true, you can set this parameter to `false` to disable the sandbox enabled: true # default: true, you can set this parameter to `false` to disable the sandbox
endpoint: http://sandbox.example.com/ # default: /app_dev.php, use this parameter to define which URL to call through the sandbox endpoint: http://sandbox.example.com/ # default: /app_dev.php, use this parameter to define which URL to call through the sandbox
accept_type: application/json # default null, if set, the value is automatically populated as the Accept header accept_type: application/json # default null, if set, the value is automatically populated as the Accept header
body_format: form # default form, determines whether to send x-www-form-urlencoded data or json-encoded data in sandbox requests
request_format:
method: format_param # default format_param, alternately accept_header, decides how to request the response format
default_format: json # default json, alternately xml, determines which content format to request back by default
The bundle provides a way to register multiple `input` parsers. The first parser that can handle the specified The bundle provides a way to register multiple `input` parsers. The first parser that can handle the specified
input is used, so you can configure their priorities via container tags. Here's an example parser service registration: input is used, so you can configure their priorities via container tags. Here's an example parser service registration:

View File

@ -48,6 +48,9 @@
<call method="setAcceptType"> <call method="setAcceptType">
<argument>%nelmio_api_doc.sandbox.accept_type%</argument> <argument>%nelmio_api_doc.sandbox.accept_type%</argument>
</call> </call>
<call method="setBodyFormat">
<argument>%nelmio_api_doc.sandbox.body_format%</argument>
</call>
<call method="setAuthentication"> <call method="setAuthentication">
<argument>%nelmio_api_doc.sandbox.authentication%</argument> <argument>%nelmio_api_doc.sandbox.authentication%</argument>
</call> </call>

View File

@ -16,6 +16,11 @@
<div id="header"> <div id="header">
<a href="{{ path('nelmio_api_doc_index') }}"><h1>{{ apiName }}</h1></a> <a href="{{ path('nelmio_api_doc_index') }}"><h1>{{ apiName }}</h1></a>
<div id="sandbox_configuration"> <div id="sandbox_configuration">
body format:
<select id="body_format">
<option value="x-www-form-urlencoded"{{ bodyFormat == 'form' ? ' selected' : '' }}>Form Data</option>
<option value="json"{{ bodyFormat == 'json' ? ' selected' : '' }}>JSON</option>
</select>
request format: request format:
<select id="request_format"> <select id="request_format">
<option value="json"{{ defaultRequestFormat == 'json' ? ' selected' : '' }}>JSON</option> <option value="json"{{ defaultRequestFormat == 'json' ? ' selected' : '' }}>JSON</option>
@ -87,6 +92,31 @@
toggleButtonText($btn); toggleButtonText($btn);
}; };
var unflattenDict = function (body) {
var found = true;
while(found) {
found = false;
for (var key in body) {
var okey;
var value = body[key];
var dictMatch = key.match(/^(.+)\[([^\]]+)\]$/);
if(dictMatch) {
found = true;
okey = dictMatch[1];
var subkey = dictMatch[2];
body[okey] = body[okey] || {};
body[okey][subkey] = value;
delete body[key];
} else {
body[key] = value;
}
}
}
return body;
}
$('.tabs li').click(function() { $('.tabs li').click(function() {
var contentGroup = $(this).parents('.content'); var contentGroup = $(this).parents('.content');
@ -153,6 +183,7 @@
method = method.split('|').sort().pop(); method = method.split('|').sort().pop();
} }
// set default requestFormat
var requestFormat = $('#request_format').val(); var requestFormat = $('#request_format').val();
var requestFormatMethod = '{{ requestFormatMethod }}'; var requestFormatMethod = '{{ requestFormatMethod }}';
if (requestFormatMethod == 'format_param') { if (requestFormatMethod == 'format_param') {
@ -161,6 +192,13 @@
headers['Accept'] = 'application/' + requestFormat; headers['Accept'] = 'application/' + requestFormat;
} }
// set default bodyFormat
var bodyFormat = $('#body_format').val();
if(!('Content-type' in headers)) {
headers['Content-type'] = 'application/'+bodyFormat;
}
// retrieve all the parameters to send // retrieve all the parameters to send
$('.parameters .tuple', $(this)).each(function() { $('.parameters .tuple', $(this)).each(function() {
var key, value; var key, value;
@ -183,6 +221,7 @@
if (value) { if (value) {
headers[key] = value; headers[key] = value;
} }
}); });
// fix parameters in URL // fix parameters in URL
@ -212,11 +251,21 @@
endpoint = $('#api_endpoint').val(); endpoint = $('#api_endpoint').val();
} }
// prepare final parameters
var body = {};
if(bodyFormat == 'json' && method != 'GET') {
body = unflattenDict(params);
body = JSON.stringify(body);
} else {
body = params;
}
var data = content.length ? content : body;
// and trigger the API call // and trigger the API call
$.ajax({ $.ajax({
url: endpoint + url, url: endpoint + url,
type: method, type: method,
data: content.length ? content : params, data: data,
headers: headers, headers: headers,
crossDomain: true, crossDomain: true,
beforeSend: function (xhr) { beforeSend: function (xhr) {