Skip to content

Loading…

[WIP] Add WADL support #99

Closed
wants to merge 1 commit into from

5 participants

@willdurand
Nelmio member

This PR adds a Web Application Description Language formatter. It's the only language that describes REST services like WSDL for SOAP web services.

It becomes really useful when you want to generate clients, it's a common practice in Java world, and I think it can be great to promote this description language.

Should be mergeable once #98 has been accepted.

@stof stof commented on an outdated diff
Controller/ApiDocController.php
((22 lines not shown))
+
+ $content = $this->get($serviceId)->format($extractedDoc);
+
+ return new Response($content, 200, array(
+ 'Content-Type' => $this->getMimeType($request, $_format),
+ ));
+ }
+
+ private function getMimeType(Request $request, $_format)
+ {
+ switch ($_format) {
+ case 'wadl':
+ $_format = 'xml';
+ break;
+
+ case 'markdown':
@stof
stof added a note

missing indentation level

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@stof stof commented on an outdated diff
Controller/ApiDocController.php
((26 lines not shown))
+ 'Content-Type' => $this->getMimeType($request, $_format),
+ ));
+ }
+
+ private function getMimeType(Request $request, $_format)
+ {
+ switch ($_format) {
+ case 'wadl':
+ $_format = 'xml';
+ break;
+
+ case 'markdown':
+ $_format = 'txt';
+ break;
+
+ default:
@stof
stof added a note

default is useless here as you don't have anything in it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@willdurand willdurand Add WADL formatter
- Override HtmlFormatter
- Update DumpCommand
- Refactor the controller to serve other formats
ad77064
@evillemez

For this to be very useful for generating clients, we'll need to standardize the potential values in the dataType property for parameters returned by the various parsers, like we discussed in IRC a while back. This would need to happen anyway in order for me to implement Swagger.

I have some work started on this, but got bogged down with other things, unfortunately. I'll start an issue and see if I can get back to it.

@willdurand willdurand closed this
@hectorh30

Was this dropped or did it get merged somewhere else?

@willdurand
Nelmio member

Dropped by now.

@Bladrak

@willdurand was it dropped by lack of participation? I'd be interested in contributing if that were the case.

@willdurand
Nelmio member

Well, things changed a lot since I created this PR, and I never took the time to update it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 19, 2012
  1. @willdurand

    Add WADL formatter

    willdurand committed
    - Override HtmlFormatter
    - Update DumpCommand
    - Refactor the controller to serve other formats
View
2 Command/DumpCommand.php
@@ -21,7 +21,7 @@ class DumpCommand extends ContainerAwareCommand
/**
* @var array
*/
- protected $availableFormats = array('markdown', 'json', 'html');
+ protected $availableFormats = array('markdown', 'json', 'html', 'wadl');
protected function configure()
{
View
31 Controller/ApiDocController.php
@@ -12,15 +12,40 @@
namespace Nelmio\ApiDocBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class ApiDocController extends Controller
{
- public function indexAction()
+ const FORMATTER_ID = 'nelmio_api_doc.formatter.%s_formatter';
+
+ public function indexAction(Request $request, $_format)
{
$extractedDoc = $this->get('nelmio_api_doc.extractor.api_doc_extractor')->all();
- $htmlContent = $this->get('nelmio_api_doc.formatter.html_formatter')->format($extractedDoc);
- return new Response($htmlContent, 200, array('Content-Type' => 'text/html'));
+ if (!$this->has($serviceId = sprintf(self::FORMATTER_ID, $_format))) {
+ $serviceId = sprintf(self::FORMATTER_ID, 'html');
+ $_format = 'html';
+ }
+
+ $content = $this->get($serviceId)->format($extractedDoc);
+
+ return new Response($content, 200, array(
+ 'Content-Type' => $this->getMimeType($request, $_format),
+ ));
+ }
+
+ private function getMimeType(Request $request, $_format)
+ {
+ switch ($_format) {
+ case 'wadl':
+ return 'application/vnd.sun.wadl+xml';
+
+ case 'markdown':
+ $_format = 'txt';
+ break;
+ }
+
+ return $request->getMimeType($_format);
}
}
View
1 DependencyInjection/Configuration.php
@@ -23,6 +23,7 @@ public function getConfigTreeBuilder()
->root('nelmio_api_doc')
->children()
->scalarNode('name')->defaultValue('API documentation')->end()
+ ->scalarNode('base_url')->defaultValue('http://example.com/')->end()
->arrayNode('request_listener')
->beforeNormalization()
->ifTrue(function ($a) { return is_bool($a); })
View
1 DependencyInjection/NelmioApiDocExtension.php
@@ -29,6 +29,7 @@ public function load(array $configs, ContainerBuilder $container)
$config = $processor->processConfiguration($configuration, $configs);
$container->setParameter('nelmio_api_doc.api_name', $config['name']);
+ $container->setParameter('nelmio_api_doc.base_url', $config['base_url']);
$container->setParameter('nelmio_api_doc.sandbox.enabled', $config['sandbox']['enabled']);
$container->setParameter('nelmio_api_doc.sandbox.endpoint', $config['sandbox']['endpoint']);
$container->setParameter('nelmio_api_doc.sandbox.request_format.method', $config['sandbox']['request_format']['method']);
View
10 Formatter/HtmlFormatter.php
@@ -21,19 +21,19 @@ class HtmlFormatter extends AbstractFormatter
protected $apiName;
/**
- * @var string
+ * @var EngineInterface
*/
- protected $endpoint;
+ protected $engine;
/**
* @var string
*/
- protected $defaultRequestFormat;
+ private $endpoint;
/**
- * @var EngineInterface
+ * @var string
*/
- protected $engine;
+ private $defaultRequestFormat;
/**
@var boolean
View
44 Formatter/WadlFormatter.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the NelmioApiDocBundle.
+ *
+ * (c) Nelmio <hello@nelm.io>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Nelmio\ApiDocBundle\Formatter;
+
+class WadlFormatter extends HtmlFormatter
+{
+ private $baseUrl;
+
+ public function setBaseUrl($baseUrl)
+ {
+ $this->baseUrl = $baseUrl;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function renderOne(array $data)
+ {
+ return $this->engine->render('NelmioApiDocBundle::resource.wadl.twig', array(
+ 'data' => $data,
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function render(array $collection)
+ {
+ return $this->engine->render('NelmioApiDocBundle::resources.wadl.twig', array(
+ 'resources' => $collection,
+ 'apiName' => $this->apiName,
+ 'baseUrl' => $this->baseUrl,
+ ));
+ }
+}
View
20 README.md
@@ -220,6 +220,26 @@ input is used, so you can configure their priorities via container tags. Here's
tags:
- {name: nelmio_api_doc.extractor.parser, priority: 2}
+
+## Configuration Reference ##
+
+ nelmio_api_doc:
+ name: API documentation
+ base_url: http://example.com/
+ request_listener:
+ enabled: true
+ parameter: _doc
+ sandbox:
+ enabled: true
+ endpoint: /app_dev.php
+ request_format:
+ method: format_param
+ default_format: json
+ authentication:
+ name: ~ # Required
+ delivery: ~ # Required
+
+
## Credits ##
The design is heavily inspired by the [swagger-ui](https://github.com/wordnik/swagger-ui) project.
View
14 Resources/config/formatters.xml
@@ -9,6 +9,7 @@
<parameter key="nelmio_api_doc.formatter.markdown_formatter.class">Nelmio\ApiDocBundle\Formatter\MarkdownFormatter</parameter>
<parameter key="nelmio_api_doc.formatter.simple_formatter.class">Nelmio\ApiDocBundle\Formatter\SimpleFormatter</parameter>
<parameter key="nelmio_api_doc.formatter.html_formatter.class">Nelmio\ApiDocBundle\Formatter\HtmlFormatter</parameter>
+ <parameter key="nelmio_api_doc.formatter.wadl_formatter.class">Nelmio\ApiDocBundle\Formatter\WadlFormatter</parameter>
<parameter key="nelmio_api_doc.sandbox.authentication">null</parameter>
</parameters>
@@ -47,6 +48,17 @@
<argument>%nelmio_api_doc.sandbox.authentication%</argument>
</call>
</service>
+ <service id="nelmio_api_doc.formatter.wadl_formatter" class="%nelmio_api_doc.formatter.wadl_formatter.class%"
+ parent="nelmio_api_doc.formatter.abstract_formatter">
+ <call method="setTemplatingEngine">
+ <argument type="service" id="templating" />
+ </call>
+ <call method="setApiName">
+ <argument>%nelmio_api_doc.api_name%</argument>
+ </call>
+ <call method="setBaseUrl">
+ <argument>%nelmio_api_doc.base_url%</argument>
+ </call>
+ </service>
</services>
-
</container>
View
4 Resources/config/routing.yml
@@ -1,5 +1,5 @@
nelmio_api_doc_index:
- pattern: /
- defaults: { _controller: NelmioApiDocBundle:ApiDoc:index }
+ pattern: /{_format}
+ defaults: { _controller: NelmioApiDocBundle:ApiDoc:index, _format: html }
requirements:
_method: GET
View
8 Resources/views/layout.wadl.twig
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://wadl.dev.java.net/2009/02 wadl.xsd"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://wadl.dev.java.net/2009/02">
+ <doc xml:lang="en" title="{{ apiName }}" />
+ {% block content %}{% endblock %}
+</application>
View
29 Resources/views/method.wadl.twig
@@ -0,0 +1,29 @@
+<method name="{{ data.method|upper }}">
+{% if data.description is defined %}
+ <doc xml:lang="en" title="{{ data.description }}" />
+{% endif %}
+{% if (data.filters is defined and data.filters is not empty) -%}
+ <request>
+ {% for name, infos in data.filters %}
+ <param name="{{ name }}" style="query" required="false"
+ {%- if infos.dataType is defined %} type="xsd:{{ infos.dataType }}" {% endif -%}
+ {%- if infos.default is defined %} default="{{ infos.default }}" {% endif -%}
+ {%- if infos.description is defined -%}>
+ <doc xml:lang="en" title="{{ infos.description }}" />
+ </param>
+ {%- else -%}
+ />
+ {%- endif -%}
+ {% endfor %}
+ </request>
+{%- endif -%}
+{% if data.statusCodes is defined and data.statusCodes is not empty -%}
+ {% for statusCode, description in data.statusCodes %}
+ <response status="{{ statusCode }}">
+ {% if description is not empty %}
+ <doc xml:lang="en" title="{{ description }}" />
+ {% endif %}
+ </response>
+ {% endfor %}
+{%- endif -%}
+</method>
View
43 Resources/views/resources.wadl.twig
@@ -0,0 +1,43 @@
+{% extends "NelmioApiDocBundle::layout.wadl.twig" %}
+
+{% block content %}
+ <resources base="{{ baseUrl }}">
+ {% for resource, methods in resources %}
+ {%- set resourcePath = resource -%}
+ {%- set nested = 0 -%}
+ <resource path="{{ resource }}">
+ {% for data in methods %}
+ {% if resourcePath != data.uri %}
+ {% if nested > 0 %}
+ </resource>
+ {% set nested = nested - 1 %}
+ {% endif %}
+ <resource path="{{ data.uri }}">
+ {% if data.requirements is defined and data.requirements is not empty %}
+ {% for name, infos in data.requirements %}
+ <param name="{{ name }}" style="template"{% if infos.dataType %} type="xsd:{{ infos.dataType }}"{% endif %} />
+ {% endfor %}
+ {% endif %}
+
+ {%- set resourcePath = data.uri -%}
+ {%- set nested = nested + 1 -%}
+ {% endif %}
+
+ {%- include 'NelmioApiDocBundle::method.wadl.twig' -%}
+
+ {% if resourcePath != data.uri %}
+ {% for i in 0..nested %}
+ </resource>
+ {% set nested = nested - 1 %}
+ {% endfor %}
+ {% endif %}
+ {% endfor %}
+ {% if resourcePath != resource %}
+ {% for i in 0..nested %}
+ </resource>
+ {% set nested = nested - 1 %}
+ {% endfor %}
+ {% endif %}
+ {% endfor %}
+ </resources>
+{% endblock content %}
Something went wrong with that request. Please try again.