To implement Web Service in symfony, ckWebServicePlugin can offer integration of symfony module as web service. The instruction detail can be found at http://www.symfony-project.org/plugins/ckWebServicePlugin/3_0_0?tab=plugin_readme.
But, to make the plugin installation work, you need additional files:
- ckWsdlGenerator
ckWsdlGenerator can be checked out from http://svn.symfony-project.com/plugins/ckWebServicePlugin/branches/ckWsdlGenerator and must be placed under [project]/plugins/ckWebServicePlugin/lib/vendor/. - Addendum
Addendum can be checked out from http://addendum.googlecode.com/svn/trunk and must be placed under [project]/plugins/ckWebServicePlugin/lib/vendor/ckWsdlGenerator/vendor/.
Then follow the instruction to configure the plugin. But, the readme is rather outdated. For example:
<?php // apps/frontend/modules/math/actions/actions.class.php class mathActions extends sfActions { /** * An action multiplying two numbers. * * @ws-enable * @ws-method SimpleMultiply * * @param double $a Factor A * @param double $b Factor B * * @return double The result */ public function executeMultiply($request) { // nothing changed here... } }
But, it should be:
<?php // apps/frontend/modules/math/actions/actions.class.php class mathActions extends sfActions { /** * An action multiplying two numbers. * * @WSMethod(name='SimpleMultiply', webservice='MathApi') * * @param float $a Factor A * @param float $b Factor B * * @return float The result */ public function executeMultiply($request) { // nothing changed here... } }
Notice the comment doc tag, it should @WSMethod(name='SimpleMultiply', webservice='MathApi') instead @ws-method and @ws-enable is removed. You can view the complete module at [project]/plugins/ckWebServicePlugin/test/fixtures/project/apps/tutorial/modules/math/actions/actions.class.php.
By default, the generated WSDL will be located under SF_WEB_DIR, so the wsdl location is at http://localhost/MathApi.wsdl, and the front controller will be http://localhost/MathApi.php. Notice that the front controller defined in the MathApi.wsdl using static address. So if you move your Web Service to production server, you need to alter the front controller manually.
Now the part to make the wsdl front controller dynamically changed. Generate a module named wsdl:
php symfony generate:module frontend wsdl
And change the content of index action to:
<?php // apps/frontend/modules/wsdl/actions/actions.class.php class wsdlActions extends sfActions { /** * Executes index action * * @param sfRequest $request A request object */ public function executeIndex(sfWebRequest $request) { $this->forward404Unless($service = $request->getParameter('service')); $wsdl = sprintf('%s/wsdl/%s.wsdl', sfConfig::get('sf_data_dir'), $service); if (!file_exists($wsdl)) { $this->forward404('WSDL "'.$wsdl.'" is not found.'); } // generate the wsdl controller based on current request $wsdlController = $request->getUriPrefix().$request->getRelativeUrlRoot().'/'.$service.'.php'; $dom = new DOMDocument(); if ($dom->load($wsdl)) { // query the soap:address node to change location $xpath = new DOMXPath($dom); $nodes = $xpath->query('/wsdl:definitions/wsdl:service/wsdl:port/soap:address'); foreach ($nodes as $node) { if ($node->hasAttribute('location')) { $node->setAttribute('location', $wsdlController); } } // output $this->response->setContentType($request->getMimeType('xml')); return $this->renderText($dom->saveXML()); } throw new sfException('"'.$wsdl.'" is not a valid xml document.'); } }
Add a route to your [project]/apps/frontend/config/routing.yml:
wsdl: url: /:service.wsdl param: { module: wsdl, action: index }
Move your wsdl from [project]/web/MathApi.wsdl to [project]/data/wsdl/MathApi.wsdl, and last modify your [project]/frontend/config/app.yml, from:
soap: ck_web_service_plugin: wsdl: %SF_WEB_DIR%/MathApi.wsdl
to:
soap: ck_web_service_plugin: wsdl: %SF_DATA_DIR%/wsdl/MathApi.wsdl
If you want to enabled debugging on wsdl front controller, edit your [project]/web/MathApi.php to:
<?php require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php'); $configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'soap', true); sfContext::createInstance($configuration)->dispatch();
Thanks that is very help full form me
Pingback:Web Services and Symfony | SymfonyLab
Thanks for the article!
I’ve implemented that feature in the development branch:
http://trac.symfony-project.org/changeset/29916
I’ve also mentioned this article in the comments of the implementation.