En En

Настройка адаптеров


В Ember Data адаптер определяет, как сохраняются данные в хранилище backend'а, например, формат URL и заголовки для REST API. (Сам формат данных определяет сериализатор). По умолчанию адаптер в Ember Data имеет некоторые встроенные положения о том, как должен выглядеть REST API. Если соглашения backend'а отличаются от этих положений, Ember Data позволяет без проблем изменить свою функциональность с помощью замены или расширения исходного адаптера.

Причины для индивидуальной настройки адаптера включают: использование underscores_case в URL-адресах, использование другого стиля, отличного от REST, для взаимодействия с API backend'а или даже использование локального хранилища backend'а.

Расширение адаптеров — естественный процесс в Ember Data. Ember занимает следующую позицию: вам нужно расширять адаптер, чтобы добавлять другую функциональность. В результате код легче тестировать, он становится проще для понимания, и людям не приходится раздувать код, чтобы разделить ваш адаптер на подклассы.

Если у backend'а есть некоторые устойчивые правила, вы можете определить adapter:application. adapter:application получит приоритет перед исходным адаптером, но его по-прежнему будут замещать адаптеры со специфической моделью.

app/adapters/application.js

import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({
  // Application specific overrides go here
});

Если у вас есть одна модель, у которой в отличие от других есть исключительные правила для взаимодействия с backend'ом, вы можете создать адаптер со специфической моделью с помощью команды ember generate adapter adapter-name. Например, запуск ember generate adapter post создаст следующий файл:

app/adapters/post.js

import DS from 'ember-data';

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

По умолчанию в Ember Data есть несколько встроенных адаптеров. Свободно используйте их в качестве отправной точки для создания собственного адаптера.

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

Настройка JSONAPIadapter

DS.JSONAPIAdapter имеет небольшое количество hook'ов, которые обычно используются, чтобы расширить его для работы с нестандартными backend'ами.

Соглашения URL

JSONAPIAdapter достаточно разумный, чтобы на основе имени модели определять URL-адреса, с которыми он взаимодействует. Например, если вы запросите Post по идентификатору:

store.findRecord('post', 1).then(function(post) {
});

адаптер JSON API автоматически отправит запрос GET по адресу /posts/1.

В адаптере JSON API вы можете применить следующие действия к записи, которые соответствуют URL-адресам:

Действие Команда HTTP URL
Find GET /posts/123
Find All GET /posts
Update PATCH /posts/123
Create POST /posts
Delete DELETE /posts/123

Настройка образования множественного числа

Чтобы способствовать образованию множественного числа имен модели при генерации URL-адресов маршрута, в Ember Data используется Ember Inflector. Это совместимая библиотека ActiveSupport::Inflector, которая предназначена для преобразования слов во множественную и единственную формы. Неправильные или неисчисляемые формы множественного числа можно указать через Ember.Inflector.inflector. Обычно это делается таким образом:

app/app.js

// sets up Ember.Inflector
import './models/custom-inflector-rules';

app/models/custom-inflector-rules.js

import Inflector from 'ember-inflector';

const inflector = Inflector.inflector;

inflector.irregular('formula', 'formulae');
inflector.uncountable('advice');

// Meet Ember Inspector's expectation of an export
export default {};

Так вы сообщите адаптеру JSON API, что запросы для formula должны следовать по адресу /formulae/1 вместо /formulas/1, а запросы для advice — по адресу /advice/1 вместо /advices/1.

При определении неправильных форм для сложных слов следует указывать только конечное слово или фразу. Например, чтобы установить множественное число для redCow как redKine, или red-cow как red-kine, следует указывать только конечные сегменты cow и kine:

inflector.irregular('cow', 'kine');

Настройка пути к конечной точке

Свойство namespace можно использовать, чтобы ставить в начале запросов специфический заполнитель URL.

app/adapters/application.js

import DS from 'ember-data';

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

Запросы для person теперь будут направляться по адресу http://emberjs.com/api/1/people/1.

Настройка хоста

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

app/adapters/application.js

import DS from 'ember-data';

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

Запросы для person теперь будут направляться по адресу https://api.example.com/people/1.

Настройка пути

По умолчанию JSONAPIAdapter попытается образовать множественное число для имени модели и вставить в него тире, чтобы сгенерировать имя пути. Если это соглашение не соответствует backend'у, вы можете переопределить метод pathForType.

Например, если вы не хотите образовывать множественное число для имени модели, и вам нужно использовать underscore_case вместо camelCase, то можно переопределить метод pathForType таким образом:

app/adapters/application.js

import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({
  pathForType: function(type) {
    return Ember.String.underscore(type);
  }
});

Запросы для person теперь будут направлены по адресу /person/1. Запросы для user-profile — по /user_profile/1.

Настройка заголовков

Некоторым API требуются заголовки HTTP, например, чтобы предоставить ключ API. В объекте headers в JSONAPIAdapter можно установить произвольные заголовки в виде пар ключ/значение. Ember Data будет отправлять их вместе с каждым запросом ajax.

app/adapters/application.js

import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({
  headers: {
    'API_KEY': 'secret key',
    'ANOTHER_HEADER': 'Some header value'
  }
});

headers также можно использовать как вычисляемое свойство для поддержки динамических заголовков. В примере ниже заголовки генерирует вычисляемое свойство, которое зависит от службы session.

app/adapters/application.js

import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({
  session: Ember.inject.service('session'),
  headers: Ember.computed('session.authToken', function() {
    return {
      'API_KEY': this.get('session.authToken'),
      'ANOTHER_HEADER': 'Some header value'
    };
  })
});

В некоторых случаях для динамических заголовков требуются данные из объектов вне системы наблюдения Ember (например, document.cookie). Вы можете использовать функцию volatile, чтобы установить свойство в режим «без кэширования». В результате заголовки будут вычисляться по-новому при каждом запросе.

app/adapters/application.js

import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({
  headers: Ember.computed(function() {
    return {
      'API_KEY': Ember.get(document.cookie.match(/apiKey\=([^;]*)/), '1'),
      'ANOTHER_HEADER': 'Some header value'
    };
  }).volatile()
});

Авторские адаптеры

Свойство defaultSerializer можно применить, чтобы указать сериализатор, который этот адаптер будет использовать. Оно применяется только в тех случаях, когда не определен сериализатор со специфической моделью или serializer:application.

Часто в приложении проще указать serializer:application. Но если вы разработчик адаптера из сообщества, то важно не забыть установить это свойство. Это гарантирует, что Ember сделает все правильно, если пользователь вашего адаптера не укажет serializer:application.

app/adapters/my-custom-adapter.js

import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({
  defaultSerializer: '-default'
});

Адаптеры сообщества

Если ни один из встроенных адаптеров Ember Data не работает с вашим backend'ом, то посмотрите адаптеры, которые поддерживает сообщество Ember. Адаптеры можно найти в этих местах:


Комментарии (2)

  1. Алексей 01 июля 2016, 11:38 # 0
    Как сделать, чтобы при запуске из контроллера this.store.findRecord (или другая функция) использовали кастомный адаптер?
    1. Виталий 26 марта 2017, 21:39 # 0
      Привет. Как использовать два адаптера, например, для Firebase и JSONAPIAdapter. Я имею ввиду синтаксис файла adapters/application.js
      Выделите опечатку и нажмите Ctrl + Enter, чтобы отправить сообщение об ошибке.