Работа с различными форматами данных

Backbone.js изначально проектировался как минималистичный MVC-фреймворк, ориентированный на работу с данными, получаемыми от сервера. В основе этой работы лежит строгая модель обмена данными между клиентом и сервером, где Backbone берет на себя синхронизацию, сериализацию и интерпретацию различных форматов данных. Ключевыми элементами здесь выступают Model, Collection и механизм sync.

Backbone по умолчанию ориентирован на формат JSON, однако архитектура фреймворка позволяет адаптировать его для работы с любыми другими форматами — XML, FormData, URL-encoded, бинарными структурами и даже нестандартными API.


JSON как основной формат обмена

Сериализация моделей

Каждая модель Backbone хранит данные во внутреннем объекте attributes. Метод toJSON() отвечает за преобразование этих данных в формат, пригодный для отправки на сервер.

var User = Backbone.Model.extend({
    defaults: {
        name: '',
        age: 0
    }
});

var user = new User({ name: 'Alex', age: 30 });
user.toJSON();
// { name: "Alex", age: 30 }

toJSON() используется автоматически при вызове save(), create() и других методов, связанных с синхронизацией. Переопределение этого метода позволяет управлять структурой данных, отправляемых на сервер.

toJSON: function () {
    var attrs = _.clone(this.attributes);
    delete attrs.internalFlag;
    return attrs;
}

Разбор входящих данных: метод parse

Метод parse используется для преобразования данных, полученных от сервера, в структуру, понятную модели или коллекции.

var User = Backbone.Model.extend({
    parse: function (response) {
        return response.data;
    }
});

Если сервер возвращает объект вида:

{
  "status": "ok",
  "data": {
    "id": 1,
    "name": "Alex"
  }
}

то parse позволяет изолировать полезную нагрузку. Этот механизм критически важен при работе с REST-API, где данные часто оборачиваются в дополнительные мета-поля.

Для коллекций parse должен возвращать массив моделей:

var Users = Backbone.Collection.extend({
    parse: function (response) {
        return response.items;
    }
});

Работа с нестандартными форматами ответа

XML

Backbone не имеет встроенной поддержки XML, но благодаря переопределению sync и parse можно адаптировать работу с таким форматом.

parse: function (xml) {
    return {
        id: $(xml).find('id').text(),
        name: $(xml).find('name').text()
    };
}

В этом случае сервер должен возвращать XML, а $.ajax — корректно его интерпретировать. Backbone не ограничивает формат данных, а лишь передает результат в parse.


Механизм sync и управление форматом запроса

Backbone.sync отвечает за отправку HTTP-запросов. По умолчанию он использует jQuery.ajax и отправляет данные в формате JSON.

Backbone.sync(method, model, options);

Переопределение sync на уровне модели или глобально позволяет полностью контролировать формат данных.

Backbone.sync = function (method, model, options) {
    options.contentType = 'application/x-www-form-urlencoded';
    options.data = $.param(model.toJSON());
    return Backbone.ajax(options);
};

Таким образом можно адаптировать Backbone под legacy-API, не поддерживающие JSON.


FormData и загрузка файлов

Для передачи бинарных данных используется объект FormData. Backbone напрямую его не поддерживает, но легко интегрируется.

var FileModel = Backbone.Model.extend({
    sync: function (method, model, options) {
        var formData = new FormData();
        formData.append('file', model.get('file'));

        options.data = formData;
        options.processData = false;
        options.contentType = false;

        return Backbone.ajax(options);
    }
});

Такой подход применяется при загрузке изображений, документов и других файлов без дополнительной сериализации.


Работа с коллекциями и вложенными структурами

Коллекции Backbone также оперируют JSON-данными, но часто сервер возвращает сложные вложенные структуры.

{
  "users": [
    { "id": 1, "name": "Alex" },
    { "id": 2, "name": "Maria" }
  ],
  "total": 2
}
var Users = Backbone.Collection.extend({
    parse: function (response) {
        this.total = response.total;
        return response.users;
    }
});

Хранение дополнительных данных (например, пагинации) непосредственно в коллекции — распространённая практика при работе с REST-API.


Преобразование данных перед сохранением

Иногда требуется отправлять данные в формате, отличном от внутреннего представления модели.

var Product = Backbone.Model.extend({
    toJSON: function () {
        return {
            product_name: this.get('name'),
            product_price: this.get('price')
        };
    }
});

Внутри приложения используются одни имена полей, а сервер получает другие. Это позволяет изолировать бизнес-логику клиента от API.


Переопределение ajax и работа без jQuery

Backbone допускает замену Backbone.ajax, что позволяет использовать альтернативные HTTP-клиенты или Fetch API.

Backbone.ajax = function (options) {
    return fetch(options.url, {
        method: options.type,
        body: options.data
    });
};

При этом ответственность за формат данных полностью переходит к разработчику, но сохраняется интерфейс Backbone.


Работа с нестандартными HTTP-методами и форматами

Backbone использует стандартные REST-методы:

  • GET
  • POST
  • PUT
  • DELETE

Некоторые серверы требуют альтернативных форматов, например, передачи метода через параметр.

options.data._method = 'PUT';
options.type = 'POST';

Такая адаптация часто применяется при интеграции с серверными фреймворками, не поддерживающими все HTTP-методы.


Валидация и формат данных

Метод validate работает с уже разобранными данными, но его логика часто зависит от формата входных значений.

validate: function (attrs) {
    if (!attrs.email) {
        return 'Email обязателен';
    }
}

Корректная работа parse и toJSON напрямую влияет на надежность валидации и целостность данных.


Итоговая архитектура работы с форматами

Backbone.js не навязывает конкретный формат данных, а предоставляет точки расширения:

  • toJSON — управление исходящими данными
  • parse — разбор входящих данных
  • sync — контроль транспорта и формата
  • ajax — замена HTTP-клиента

Такая архитектура позволяет использовать Backbone.js как универсальный слой синхронизации данных в приложениях с любыми требованиями к формату и протоколу обмена.