Search code examples
phpsymfonyfosrestbundle

How can I separate POST requests by content-type?


I want to execute different actions depending on the client-provided content-type. I've configured 2 controller actions for this:

/**
 * @Post("", requirements={"_format": "json"})
 */
public function postJsonAction(Request $request)
{
    // 
}

/**
 * @Post("", requirements={"_format": "csv"})
 */
public function postCsvAction(Request $request)
{
    //
}

However, this is not working for me, first action is always executed. What am I doing wrong here? Here is my fos_rest configuration in the config.yml:

fos_rest:
    param_fetcher_listener: true
    allowed_methods_listener: true
    routing_loader:
        default_format: json
        include_format: false
    view:
        mime_types: { 'csv': ['text/csv'], 'xlsx': ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'] }
        formats:
            json: true
            csv: true
            xlsx: true
    format_listener:
        rules:
            - { path: '^/api', priorities: ['json', 'csv', 'xlsx'], fallback_format: ~, exception_fallback_format: json, prefer_extension: false }
    service:
        view_handler: app.view_handler

Solution

  • You can configure this in your route. For example, if you are using a yml route configuration.

    csv:
        path:      /article/format/csv/
        defaults:  { _controller: AppBundle:Article:postCsv }
    
    json:
        path:      /article/format/json/
        defaults:  { _controller: AppBundle:Article:postJson }
    

    Then, using JS to change your form action.

    if ("csv" === $("#format").val()) {
       $('#your_form').attr('action', '/article/format/csv/');
    }
    else {
       $('#your_form').attr('action', '/article/format/json/');
    }