Search code examples
phpsymfonysoapfosrestbundle

Conflict between BeSimple Soap bundle and FOSRest Bundle


I'm doing some Rest and some SOAP services, for the REST ones I'm using FOSRestBundle and for the SOAP type I'm using BeSimple Soap Bundle (this really is not that relevant as the problem is with a FOSRest listener IMO, but I say it just in case).

The thing is that the FOSRest offers a listener to handle the responses and serialize/render them like this:

<?php
/**
 * @Rest\View
 */
public function getAction()
{
  return $item;
}

And it handles the response serializing it into JSON/XML or whatever. The conflict comes when I try to call my SOAP services and the listener yells at me saying that it does not support SOAP as a format (it supports JSON, XML, etc).

This happens when I put view_response_listener: 'force' into my FOSRest yml config file. If I change it to view_response_listener: 'enabled' the SOAP services do work but I seem to lose the so convenient FOSRest ability of autohandling my responses.

How could I achive that the FOSRest view_response_listener just handles the right responses letting the SOAP Bundle handle the soap type responses.

Edit:

fos_rest:
    param_fetcher_listener: true
    body_listener: true
    format_listener: true
    view:
        view_response_listener: 'force' #This is the parameter that is driving me crazy. Value to 'force' Rest controllers work just fine SOAP don't, value to 'enabled' the other way around
        formats:
            xml: true
            json : true
        templating_formats:
            html: true
        force_redirects:
            html: true
        failed_validation: HTTP_BAD_REQUEST
        default_engine: twig
    routing_loader:
        default_format: json

That is the FOSRestBundle configuration.

Here's my routing.yml for both the Rest endpoints and the SOAP ones:

#config/routing.yml
rest_api:
  resource:    "@RESTBundle/Resources/config/api_routes.yml"
  host:        "%host_front%" #api.myproject.local
  type:        rest

#api_routes.yml detail
accounts:
    resource:    'RESTBundle\Controller\AccountsController'
    type:        rest
    name_prefix: api_

#config/routing.yml
soap_api:
  resource: "@SOAPBundle/Resources/config/soap_routing.yml"
  host:     "%host_ws%"
  prefix:   "%contexto_ws%"

#soap_routing.yml detail
_besimple_soap:
  resource: "@BeSimpleSoapBundle/Resources/config/routing/webservicecontroller.xml"
soap_ws:
  resource: "@SOAPBundle/Controller/"
  type: annotation

RestController example:

<?php

namespace RESTBundle\Controller\API;

use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\FOSRestController;
use Nelmio\ApiDocBundle\Annotation\ApiDoc as ApiDoc;
use Symfony\Component\HttpFoundation\Request;

/**
 * @Rest\RouteResource("accounts", pluralize=false)
 */
class AccountsController extends FOSRestController
{
    /**
     * @Rest\View
     */
    public function getAction($userId)
    {
        return [
          ['name' => 'Example', 'pass'=> 'example'],
          ['name' => 'Example2', 'pass'=> 'example2']
        ];
    }
}

SOAP Controller:

/**
 * @Soap\Header("user", phpType="string")
 * @Soap\Header("token", phpType="string")
 */
class AccountsController implements ContainerAwareInterface
{
    use ContainerAwareTrait;

    /**
     * @Soap\Method("getAccounts")
     * @Soap\Param("account", phpType="SOAPBundle\DataType\AccountFilter" )
     *
     * @Soap\Result(phpType="SOAPBundle\DataType\Account[]"")
     */
    public function getAccountsAction(Request $request, AccountFilter $filter)
    {
       return [(new Account())->setName('Example')->setPass('example')] //This is just an example
    }
}

Edit with the error:

request.ERROR: Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException: "Format 'soap' not supported, handler must be implemented" at /home/teampro/Sites/corinto/vendor/friendsofsymfony/rest-bundle/View/ViewHandler.php line 292 {"exception":"[object] (Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException(code: 0): Format 'soap' not supported, handler must be implemented at /.../vendor/friendsofsymfony/rest-bundle/View/ViewHandler.php:292)"} []


Solution

  • You can define how make rules to listen like this in the fos_rest config :

    format_listener:
          rules:
            - { path: ^/, priorities: [ html, json, xml ], fallback_format: ~, prefer_extension: true } # default routes
            - { path: '/soap', priorities: [xml], fallback_format: xml, prefer_extension: true } # your soap route
            - { path: '^/rest', priorities: [xml, json], fallback_format: xml, prefer_extension: true } # your rest route
    

    Hope this help !!