В первой части этого урока мы достигли следующего:

  • Настройка проекта
  • Создание базовой функциональности отправки запросов и получения ответов для конечных точек GET и POST REST API.
  • Прикрепите тело пользовательского запроса к запросам POST

Если вы еще не читали Часть 1, настоятельно рекомендуем сделать это, прежде чем продолжить.



Во второй и последней части руководства мы создадим наше приложение и добавим еще две функции:

  • Прикрепляйте пользовательские заголовки к запросам API
  • Сохранение и загрузка прошлых запросов, чтобы их можно было использовать повторно

Прикрепляйте пользовательские заголовки к запросам API

Много раз, а на самом деле чаще, необходимо прикреплять заголовки к запросам API для таких целей, как аутентификация, например, «x-api-key». Хорошей новостью является то, что внешний вид и функциональность настраиваемых заголовков очень похожи на тело настраиваемого запроса для запросов POST. Для начала давайте добавим пользовательский интерфейс для этой функции, и хорошим местом для этого будет вкладка рядом с вкладкой Body. Итак, обновляем раздел следующим образом:

Как видите, мы начинаем с перемещения *ngIf в разделе на вкладку, соответствующую 'Body', поскольку заголовки запроса могут потребоваться в запросах GET или POST, в отличие от тела запроса. Кроме того, пользовательский интерфейс значительно похож и фактически проще, чем у вкладки Body — здесь нам не нужно поле типа данных — это всегда пара строковых значений ключ-значение. У нас также есть положения для добавления и удаления элементов. Но здесь мы добавляем обязательный неизменяемый заголовок для Content-Type — это поле нельзя ни редактировать, ни удалять.

Отбросив пользовательский интерфейс, давайте теперь посмотрим на логическую часть. Для начала нам нужно добавить заголовки к функциям-оболочкам, которые мы определили в сервисе. Нам нужно добавить дополнительный параметр к обеим функциям и создать заголовок, используя класс HttpHeader, предоставленный Angular. Заполненный файл main.service.ts теперь будет выглядеть следующим образом:

Теперь, когда служба убрана, пришло время добавить логику компонента. Еще раз хорошая новость заключается в том, что мы можем повторно использовать функции, которые мы создали для пользовательского тела, добавляя параметр контекста к доступным функциям и возвращая результаты или выполняя действия соответственно. Для этого мы обновляем api-params.component.ts следующим образом:

И точно так же у нас теперь есть функциональность пользовательского заголовка запроса.

Сохранение и загрузка прошлых запросов

Теперь наше приложение отвечает более чем достаточным требованиям для работы в качестве базового инструмента опроса API. Однако полезной функцией будет возможность повторного использования прошлых запросов. Это включает в себя две части — сохранение запросов, которые мы делаем, и возможность загрузить их, чтобы тот же запрос можно было сделать снова. Эта функция является фундаментальным требованием к системе хранения. Поскольку для этой версии приложения мы сохраняем его как чистое браузерное приложение, логично выбрать одно из нескольких решений для хранения, предоставляемых браузером. Наиболее очевидным выбором будет использование localStorage. Однако localStorage — это хранилище на основе строк. В идеале нам нужно хранилище объектов JSON. Из-за этого лучшим и более правильным выбором будет использование IndexedDB.



Для начала нам понадобится компонент для отображения прошлых запросов и их загрузки. Мы создаем его с помощью CLI.

ng g c past-requests

Давайте теперь разместим оба компонента на базовом компоненте, компоненте приложения. После этого это будет выглядеть примерно так:

На данный момент мы должны понять, что, хотя большинство современных браузеров поддерживают, все еще существуют более ранние версии браузеров, которые не поддерживают API IndexedDB. И поскольку нет смысла иметь компонент past-requests, если браузер не поддерживает IndexedDB. Таким образом, как видно, макет страницы, а также отрисовка компонента past-requests управляются переменной hasIndexedDB, которую мы будет установлено значение true или false в зависимости от доступности API в браузере. Это один из аспектов прогрессивных веб-приложений, когда мы настраиваем отображаемое приложение в соответствии с положениями браузера, в котором оно работает.

Первый шаг — проверить, поддерживает ли браузер API IndexedDB, и хорошим местом для запуска проверки и установки переменной hasIndexedDB будет метод OnInit компонента приложения.

Как показано, мы вызываем функцию openIndexedDB из ngOnInit. В функции openIndexedDB мы сначала проверяем, является ли область действия браузера; т. е. объект window содержит IndexedDB. Если эта проверка проходит успешно, мы пытаемся открыть экземпляр IndexedDB. Если это удается, срабатывает обработчик onsuccess, и именно здесь мы инициируем экземпляр indexedDB и устанавливаем для переменной hasIndexedDB значение true.

Предполагая, что IndexedDB успешно открыт, нам нужно открыть хранилище объектов. Мы можем использовать метод createObjectStore для экземпляра indexedDB для открытия хранилища следующим образом:

Метод создает новое хранилище объектов с именем «pastRequests» или открывает его, если оно уже существует из предыдущих экземпляров запуска приложения. Мы передали методу два атрибута в качестве опций. keyPath определяет уникальный индекс, по которому мы идентифицируем каждую запись в магазине, который мы создаем/открываем, а autoIncrement: true автоматически добавляет новый _id к каждой записи в магазине, и нам не нужно устанавливать ее вручную.

Следующим шагом является сохранение сделанных запросов. Для этого вернемся к компоненту api-params.

Мы создали функцию, которая создает requestObject на основе типа запроса. Этот объект содержит элементы запроса, которые мы хотим сохранить. Как только объект готов, мы инициируем новую транзакцию, в которой мы открываем созданное хранилище объектов, ‘pastRequests’ в режиме readwrite, так как нам нужно записать новые данные. Наконец, мы добавляем созданный requestObject в хранилище pastRequests. Осталось только вызвать функцию saveRequest в методе sendRequest.

Следующая часть — получение сохраненных запросов для отображения в нашем компоненте past-requests. Для этого вернемся к компоненту app.

Здесь мы используем метод getAll для получения всех сохраненных запросов. Остальная часть процесса аналогична добавлению нового элемента в хранилище объектов. Затем мы вызываем эту функцию в обработчике onsucess открытия IndexedDB.

Теперь нам нужно добавить пользовательский интерфейс и логику в компонент past-requests для предоставления полученных запросов. Шаблон для этого будет выглядеть примерно так:

Что касается логической части компонента, все, что нам нужно сделать, это определить Input для получения массива pastRequests от компонента app.

На этом этапе мы сможем увидеть все запросы, которые мы делаем в этом компоненте.

Последнее, что нам нужно сделать, это добавить функциональность для загрузки прошлого запроса. Для этого мы определяем событие click для любого из перечисленных запросов, которое отправляет событие компоненту app.

Теперь нам нужно определить функцию в компоненте api-params для загрузки запроса. Нам также понадобится функция для деконструкции заголовков и объектов тела в массивы, чтобы они могли отображаться правильно.

Поскольку функция на месте, все, что нам нужно сделать, это вызвать ее при нажатии на прошлый запрос. Мы можем сделать это в функции-обработчике события, сгенерированного компонентом past-requests. Поскольку компонент api-params является дочерним по отношению к компоненту приложения, мы можем использовать декоратор @ViewChild, чтобы получить к нему доступ и запустить функцию. Завершенный компонент приложения теперь будет выглядеть следующим образом:

Мы завершили наше приложение со всеми запланированными функциями. Вы можете увидеть полный код проекта в следующем репозитории Github.



Вы можете просмотреть приложение вживую по следующей ссылке



Спасибо за чтение.

Хотите пообщаться со мной один на один по поводу этой истории или Angular, Typescript и Javascript в целом? Переходите в раздел Нанять автора и давайте подключаться!

Подпишитесь на нас в Twitter🐦и Facebook👥и Instagram📷 и присоединяйтесь к нашим Facebook и Linkedin Группы💬.

Чтобы присоединиться к командному чату Slack нашего сообщества🗣️ прочитайте наши еженедельные темы Faun🗞️,и свяжитесь с сообществом📣нажмите здесь⬇

Если этот пост был полезен, пожалуйста, нажмите кнопку аплодисментов 👏 несколько раз, чтобы выразить свою поддержку автору! ⬇