1
votes

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)"} []

2
Please update your question with config, it's quite hard to read through the lines :) Also, could you share your code?Samundra
@Samundra Done, it's not my code (can't post it here) but it's a dummy example based on it, so it yells the same stuff.Astaroth

2 Answers

1
votes

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 !!

0
votes

first, explicity separate routing resources with prefix property

# app/config/routing.yml
_besimple_soap:
  resource: "@BeSimpleSoapBundle/Resources/config/routing/webservicecontroller.xml"
  prefix:   "%contexto_ws%"

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

For now it looks like that your REST controlller processes the WS route as it overlaps by configuraiton. Separating route namespaces with prefixes can help.

Second, verify the request host, as your configuration already splits the rouiting based on request host variable

Third, check the routing configuration with

bin/console debug:router
bin/console router:match