Настраиваем EmberJS для работы с REST-api

В этой статье постараюсь изложить действия, которые необходимо выполнить, чтобы заставить EmberJS работать с базовым REST-api. Для многих популярных реализаций REAST-api для Ember уже имеются готовые расширения (например, django-rest-adapter для Django и DRF), так что, если есть возможность выбора, то сначала сначала стоит посмотреть в сторону готовых решений.

Итак, имеем: сервер (предположим, Flask), который находится по адресу 0.0.0.0:5000 и возвращает данные о пользователях в формате

{
  "users": [
    {
      "id": 1,
      "username": "lily"
    },
    {
      "id": 2,
      "username": "john"
    }
  ]
}

Соответствующая модель на стороне ember-приложения сгенерирована командой

ember g model user username:string

Само ember-приложение запущено с ключом --proxy=http://0.0.0.0:5000, который позволяет перенаправлять все ajax-запросы на определенный адрес.

При попытке получить данные в случае отсутствия иных настроек ember в первую очередь обращается по адресу <api_url>/<model_name>, что в нашем случае будет выглядеть как 0.0.0.0:5000/users. Ниже будет написано, как это изменить, но пока будем считать, что данные о пользователях доступны именно по этому адресу. 

Для общения с сервером данных по REST-протоколу (точнее, для интерпретации полученных данных) Ember использует адаптеры. В базовой комплектации имеется 3 вида адаптеров:

  • DS.Adapter - базовый адаптер, не содержит в себе никакого функционала. В общем случае, это хорошая стартовая позиция для создания совего, кардинально отличающегося от остальных, адаптера;
  • DS.JSONAPIAdapter - адаптер по-умолчанию. Следует конвенциям JSON API для обмена данными с HTTP-сервером, передавая JSON по XHR;
  • DS.RESTAdapter позволяет обмениваться обычными JSON-данными с HTTP-сервером. До версии Ember Data 2.0 был адаптером по-умолчанию.

Как можно заметить из описания выше, по-умолчанию используется JSONAPIAdapter, который для обмена данными использует хитромудрый формат, в корне отличающийся от более простого формата, возвращаемого нашим сервером на Flask. Задача - объяснить Ember-у все это. В данном случае решение тривиальное - нужно вместо JSONAPIAdapter использовать RESTAdapter, который ожидает данные как раз в передаваемом формате. Чтобы заменить адаптер, используемый по-умолчанию, как советуют в документации, определим собственный adapter:application, который будет иметь более высокий приоритет относительно стандартного JSONAPIAdapter. Для этого создадим файл app/adapters/application.js со следующим содержанием:

import DS from 'ember-data';

export default DS.RESTAdapter.extend({
});

Этого достаточно, чтобы ember распознал и корректно интерпретировал получаемые от сервера данные. Если в дальнейшем у нас появятся модели со специфичными форматами данных, для них созданный нами адаптер можно переопределить. Для этого нужно создать файл вида app/adapters/<model-name>.js, можно используя командную строку: ember generate adapter post и в получившемся файле переопределить правила форматирования данных для конкретной модели.

Используя свойство адаптера namespace, можно указать специальный url-префикс, который будет использоваться для всех запросов:

export default DS.JSONAPIAdapter.extend({
  namespace: 'api/1'
});

Запросы к объектам users будут теперь иметь вид http://example.com/api/1/users/1.

По умолчанию, адаптер пытается выполнить запросы к текущему домену. Чтобы направить запросы к api по другому адресу, необходимо указать свойство адапретра host:

export default DS.JSONAPIAdapter.extend({
  host: 'https://api.example.com'
});

Ссылки для самостоятельного прочтения: