backbone.jsdrupal-7drupal-services

Drupal services module JSON response fetched: Backbone.js model attributes turn into string


I've set up web services using Drupal's services module. It outputs JSON for me which I am requesting through a Backbone.js front-end application.

I'm having issues with this set-up. If I request data through Backbone.js' fetch method of a model, the model's attributes are all typed as string after fetching, while there are some attributes that should be e.g. integer.

For example:

...which results in the following response (slimmed down version from the real response):

    {"uid":"8","name":"itsme","mail":"me@mydomain.nl"}

I assume the above leads to my model ending up with a uid attribute of not integer, but string. It also happens with all other web service resources I have created, using my own entities.

I need correct typing of attributes in my model due to sorting issues using Backbone's collection sorting. I.e. sorting a collection of models using a field of type 'integer' leads to different sorting results when sorting the field with the same values although stored as a string.

I'm not sure exactly where to look:

Thanks for any help.


Solution

  • So I finally managed to crack this issue and I found my solution here: How to get numeric types from MySQL using PDO?. I thought I'd document the solution.

    Drupal 7 uses PDO. Results fetched using PDO, using Drupal's default PDO settings result in stringified values.

    In Drupal's includes/database.inc file you will find this around lines 40-50:

    $connection_options['pdo'] += array(
      // So we don't have to mess around with cursors and unbuffered queries by default.
      PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => TRUE,
      // Because MySQL's prepared statements skip the query cache, because it's dumb.
      PDO::ATTR_EMULATE_PREPARES => TRUE,
    );
    

    The statement here that MySQL's prepared statements skip the query cache is not entirely true, as can be found here: http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html. It states MySQL > 5.1.17 prepared statements use the query cache under certain conditions.

    I used the info from the other stack overflow question/answers to override the PDO settings for the database connection in Drupal's sites/default/settings.php (please note I only did this for the database I was querying, which is different than Drupal's own database):

    'database_name' =>
      array (
        'default' => 
        array (
          'database' => 'database_name',
          'username' => 'user_name',
          'password' => 'user_pass',
          'host' => 'localhost',
          'port' => '',
          'driver' => 'mysql',
          'prefix' => '',
          'pdo' => array(
            PDO::ATTR_STRINGIFY_FETCHES => FALSE,
            PDO::ATTR_EMULATE_PREPARES => FALSE
          ),
        ),
      ),
    

    This resulted in integers being integers. Floats/decimals are incorrectly returned by PDO still, but this is different issue. At least my problems are solved now.