Как подключить rest api к сайту js
Перейти к содержимому

Как подключить rest api к сайту js

  • автор:

Запросы к Rest API из JavaScript компактно и красиво

Делал я тут небольшой проект на чистом JS и в ходе оного потребовалось работать с Rest API. Ну не ручками ведь XMLHttpRequest дёргать, решил я, наверняка есть бесчисленное количество готовых решений для такой простой задачи.

Как можно догадаться по КДПВ, я несколько ошибался; впрочем, обо всём по порядку. Но если вкратце — получился вот такой симпатичный велосипедик, с которым запросы к Rest API получаются, как и обещано в заголовке, компактными и красивыми.

image

Кандидаты

Итак, мне был нужен джаваскриптовский клиент для Rest API. Гугл выдал чуток библиотек — restful.js, rest, amygdala. На самом деле, была ещё вот такая библиотечка, но это плагин к jQuery. jQuery в проекте не используется и тащить его как-то не хотелось; но, отчасти, предлагаемый библиотекой синтаксис мне понравился и это ещё всплывёт впоследствии.

Amygdala отпала сразу — нет Promise, а значит нет и async/await. Ещё и границы функциональности у неё странные, amygdala скорее претендует на что-то вроде недо-data-layer; про отсутствие сбилженной версии и лишние зависимости я тактично умолчу.
Осталось два кандидата — restful.js и rest.

rest предлагает некое минимальное ядро и даёт широкие возможности по его кастомизации с помощью так называемых «перехватчиков» — interceptors в оригинале. Не знаю насколько это круто — перспектива строить полные урлы и указывать метод руками при каждом запросе меня вовсе не прельщала, перехватчиков для модификации этого поведения не наблюдалось, да и документация восторга не вызывала. Я перешёл к последнему варианту — restful.js.

A pure JS client for interacting with server-side RESTful resources. Think Restangular without Angular.

Вообще-то я предпочитаю Ember, но какая разница? Главное-то что б использовать удобно было!

const articleCollection = api.all('articles'); // http://api.example.com/articles // http://api.example.com/articles/1 api.one('articles', 1).get().then((response) => < const articleEntity = response.body(); // if the server response was < id: 1, title: 'test', body: 'hello' >const article = articleEntity.data(); article.title; // returns `test` article.body; // returns `hello` // You can also edit it article.title = 'test2'; // Finally you can easily update it or delete it articleEntity.save(); // will perform a PUT request articleEntity.delete(); // will perform a DELETE request >, (response) => < // The reponse code is not >= 200 and < 400 throw new Error('Invalid response'); >);

Это пример из документации. Выглядит неплохо в сравнении с конкурентами, да и документация достаточно внятная… Вариантов-то всё равно больше не наблюдается. Берём? Берём.

Небольшое лирическое отступление

Есть такая концепция «разумного умолчания», которая предполагает, если пересказывать своими словами, что решение некоей проблемы заточено, условно, под 90% юзкейсов, а в остальных 10% нужно явно сказать что имеются особенные обстоятельства.

Тривиальный пример этой концепции — параметры по умолчанию в большинстве языков программирования.

Куда менее тривиальный пример (являющийся, тем не менее, просто обобщением предыдущего) — оптимизация любого интерфейса исходя из ожидаемого поведения пользователя, будь то интерфейс командный, графический, программный или вообще физический: рубильники там, кнопочки и прочие хардварные крутилки-вертелки.

Общая стратегия этих оптимизаций одинакова — 90% пользователей для достижения своих целей должны производить так мало действий, как это вообще возможно. Не будет большим преувеличением сказать что это общая формула прогресса — изобретение всё более и более простых, с точки зрения количества необходимых телодвижений, интерфейсов для решения всё тех же задач.
И, в общем-то, эти самые разумные умолчания — один из главных способов упрощения.

Зачем я играю в Капитана Очевидность, растекаясь мысью по древу? Потому что очередной велосипед — это просто очередной велосипед, а вот велосипед с подведённой под него философской базой уже не просто очередной велосипед, а даже может издали и на мотоцикл смахивать!
Конец небольшого лирического отступления.

restful.js

Итак, restful.js. Использовал я его крайне недолго — и пары дней не прошло, как я понял что:

    Каждый раз явно вызывать all() — не круто.

let games = api.all('games'); //
let games = (await api.games.get()).body().data(); //

В общем, классический пример неудобного интерфейса. Я не знаю, влияние ли это ангуляра, который вроде славится своей академичностью, или ориентация скорее на бытиё фреймворком, нежели библиотекой, но предлагаемый restful.js интерфейс мне сильно не понравился. На самом деле, по итогу он понравился мне, наверно, даже меньше чем интерфейс конкурентов — видимо, эффект зловещей долины сказывается: близко к идеалу, но не дотянуло, а от любви до ненависти всего один велосипед.

Что же я сделал?

Выкинул restful.js и накидал два класса, которые за 150 строк кода делали в принципе то же, что и restful.js за 6000 (шесть тысяч, это не опечатка).
Потом подумал, выложил на github, порефакторил, освоил webpack (замечательная штука!), mocha+chai, sinon и travis, выложил на npm и bower, написал документацию, запилил пример и в итоге написал эту статью, чтобы облегчить жизнь тем, кто столкнётся с такой же проблемой.

На данный момент (июнь 2016) там маловато тестов, нет методов HEAD и OPTIONS, сложно получить сырой ответ и слишком мало бейджей в README (всего один, что за позор. ).
Впрочем, это всё легко исправить. Главное что another-rest-client предоставляет понятный и простой интерфейс, с которым мне нравится работать; надеюсь что и не только мне.

Немного кода

Использование github API:

var api = new RestClient('https://api.github.com'); api.res(); api.repos('Amareis/another-rest-client').releases('latest').get().then(function(release)< console.log(release); document.write('Latest release of another-rest-client:
'); document.write('Published at: ' + release.published_at + '
'); document.write('Tag: ' + release.tag_name + '
'); >);

Вложенные ресурсы? Запросто:

var api = new RestClient('http://example.com/api/v1'); api.res(< //or it gets object and returns object where resource is available by name dogs: [ 'toys', 'friends'], cats: 0, humans: 'posts' >); /* last string is equal to: api.res('dogs').res(['toys', 'friends']); api.res('cats'); api.res('humans').res('posts'); */ api.dogs(1337).toys.get(); //GET http://example.com/api/v1/dogs/1337/toys api.dogs(1337).friends(2).delete(); //DELETE http://example.com/api/v1/dogs/1337/friends/2 //POST http://example.com/api/v1/humans/me/posts, body="" api.humans('me').posts.post();

С async/await код получается куда веселей:

var me = api.humans('me'); var i = await me.get(); console.log(i); //just object, i.e. var post = await me.posts.post() console.log(post); //object

Случайные занимательные факты

  1. Почему такое название? Ну, изначально он был просто rest-client. Но это название (а также ещё несколько похожих) занято в npm, да и уникальность так себе, так что я добавил чутка самоиронии и он стал another-rest-client.
  2. В самом начале своего существования restful.js была очень похожа на первые версии another-rest-client. Потом, видимо, скатилась в энтерпрайзщину.
  3. В коде another-rest-client всего два комментария (и я возмущён тем, что их слишком много) и оба они содержат проклятья в сторону Javascript, который не позволяет сделать код полностью красивым.
  4. Я так и не понял чем WTFPL отличается от MIT лицензии.

Руководство по использованию JS API

JS API предоставляет возможность разрабатывать приложения в Моем Мире и подключать внешние сайты с использованием JavaScript.

Библиотека позволяет осуществлять вызовы API прямо из браузера пользователя, минуя ваш сервер, помогая вам экономить трафик и вычислительные ресурсы. Кроме того, она дает доступ к некоторым возможностям, которые не доступны для вызова с сервера.

Подключение JS API

В IFrame-приложении или на внешнем сайте

Для использования JS API вам нужно:

  1. На домен вашего приложения или сайта загрузить файл receiver.html
  2. На вкладке Настройки IFrame управления приложением или в интерфейсе редактирования сайта указать адрес загруженного файла receiver.html
  3. Подключить загрузчик библиотеки, добавив следующий код в элемент всех страниц, где вы хотите использовать JS API:

  • для приложений: вызвав функцию mailru.app.init(private_key)
  • для сайтов: вызвав функцию mailru.connect.init(app_id, private_key)

Важно! Для корректной работы JS API на многостраничных приложениях необходимо передавать на внутренние страницы все GET-параметры, которые приложение получает на главной странице. Это не относится к сайтам.

Файл receiver.html

Файл receiver.html нужен для кроссдоменной передачи данных через JavaScript в старых браузерах. Он статический и мы не планируем его менять. Загрузите его на ваш сервер и он подойдет для всех приложений и сайтов, которые работают на одном домене.

Мы проверяем содержимое файла receiver.html на побитовое совпадение с оригиналом, поэтому размещать на сервере нужно исходный файл с нашего сервера, без обработки его текстовыми редакторами (они могут вставлять BOM или делать другие преобразования, которые приведут к ошибке при проверке ресивера).

Если вы разрабатываете приложение или сайт и ваше тестовое окружение не доступно из интернета, то мы не сможем проверить правильность файла receiver.html на ваших внутренних серверах и сообщим вам об этом в интерфейсе управления. Однако, адрес должен сохраниться в настройках и будет использоваться в работе JS API. Просто при выкладывании вашего проекта в публичный доступ проверьте, что receiver.html загружен и указан в настройках правильно.

Пример кода приложения
   
Пример кода сайта
   

Во Flash-приложении

Вы можете использовать все функции JS API внутри Flash части вашего приложения. Для этого мы создали Flash API — ActionScript прослойку для вызова функций JS API. Подробнее о подключении и применении читайте на странице документации по Flash API.

Использование библиотеки

Функции JS API разделены на те, которые можно вызывать с сайтов, из приложений и общие функции (доступный и с сайтов, и из приложений). Функции для приложений сгруппированы в объекте mailru.app, для сайтов — mailru.connect, общие — в mailru.common.

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

mailru.session

Объект, в котором хранятся данные о сессии. Становится доступным после вызова mailru.app.init или mailru.connect.init

, настоятельно // рекомендуем ее проверять на сервере при // использовании данных для авторизации ss: "d41d8cd98f00b204e9800998ecf8427e", // не используется state: "", // не используется vid: "1324730981306483817" // id текущего пользователя, который вы можете // использовать для авторизации >

Про различие между vid и oid читайте в руководстве по социальным приложениям. Для внешних сайтов oid всегда равен vid.

Работа с событиями

Некоторые действия пользователь может сделать самостоятельно с помощью кнопок на канве вашего приложения, а так же с помощью диалогов, которые ваше приложение может поднимать. Например, пользователь может установить ваше приложение сам, а может в вызванном вами диалоге. Для таких случаев предусмотрен механизм событий. Когда пользователь производит действие, не важно из диалога, поднятого ваши с помощью JavaScript библиотеки, или из интерфейса Моего Мира, вызывается ваша функция-обработчик, которая реагирует на это событие как вам нужно.

Для работы с событиями используйте функции events.listen js и events.remove js . В документации функций, которые могут генерировать события, указано какие именно события генерируются.

Тестовое приложение

  • тестовое приложение
  • код тестового приложения

Функции JS API

  • mailru.app.events.like
  • mailru.app.friends.invite
  • mailru.app.friends.request
  • mailru.app.payments.showDialog
  • mailru.app.users.isAppUser
  • mailru.app.users.requireInstallation
  • mailru.app.utils.hash.read
  • mailru.app.utils.hash.write
  • mailru.app.utils.scrollTo
  • mailru.app.utils.setHeight
  • mailru.app.utils.setTitle
  • mailru.app.widget.set
  • mailru.common.friends.add
  • mailru.common.friends.getAppUsers
  • mailru.common.friends.getExtended
  • mailru.common.friends.getInvitationsCount
  • mailru.common.guestbook.post
  • mailru.common.messages.send
  • mailru.common.photos.createAlbum
  • mailru.common.photos.get
  • mailru.common.photos.getAlbums
  • mailru.common.photos.upload
  • mailru.common.photos.uploadAvatar
  • mailru.common.stream.post
  • mailru.common.users.getBalance
  • mailru.common.users.getInfo
  • mailru.common.users.hasAppPermission
  • mailru.common.users.requirePermission
  • mailru.connect.getLoginStatus
  • mailru.connect.initButton
  • mailru.connect.login
  • mailru.connect.logout
  • mailru.events.listen
  • mailru.events.remove

Другие технологии

  • REST API
  • Flash-библиотека
  • сторонние библиотеки

Вызов REST API из JavaScript

Data exchange between JavaScript and a server.

В современном веб-разработке часто возникает потребность в использовании REST API — это способ, который позволяет веб-сайтам и веб-приложениям обмениваться данными с сервером. Например, возникает потребность отправить данные из формы на веб-странице на сервер или получить данные с сервера для отображения на веб-странице.

JavaScript предлагает несколько методов для взаимодействия с REST API, но самым популярным и широко используемым является метод fetch(). В данном контексте fetch() представляет собой функцию, которая позволяет осуществлять асинхронные HTTP-запросы к серверу и работать с REST API.

В базовом случае использования fetch() для отправки GET-запроса к REST API код будет выглядеть следующим образом:

fetch('https://api.example.com/items') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Ошибка:', error));

В этом коде вызывается fetch() с URL-адресом REST API, затем обрабатывается ответ от сервера и преобразуется в JSON, и затем выводится полученные данные.

Для отправки POST-запроса с данными код будет немного сложнее:

let data = ; fetch('https://api.example.com/items', < method: 'POST', headers: < 'Content-Type': 'application/json', >, body: JSON.stringify(data), >) .then(response => response.json()) .then(data => console.log(data)) .catch((error) => < console.error('Ошибка:', error); >);

В этот код добавлены дополнительные опции для метода fetch(), указывающие на использование HTTP-метода POST, добавление заголовка ‘Content-Type’ и отправку данных в формате JSON.

Описанные здесь примеры являются базовыми и могут быть дополнены и модифицированы в соответствии с требованиями конкретного REST API и задач, стоящих перед разработчиком.

Сторонние API

API, которые мы рассмотрели до сих пор, встроены в браузер, но не все API таковы. Многие крупные веб-сайты и сервисы, такие как Google Maps, Twitter, Facebook, PayPal и т. д., Предоставляют API-интерфейсы, позволяющие разработчикам использовать свои данные (например, показывать ваш твиттер-поток в вашем блоге) или сервисы (например, отображение пользовательских карт Google на вашем сайте, или использование логина Facebook для входа в систему ваших пользователей). В этой статье рассматривается различие между API-интерфейсами браузера и сторонними API и показано типичное использование последних.

Необходимые условия: Основы JavaScript (см. первые шаги, структурные элементы, объекты JavaScript), the основы клиентских API
Задача: Изучить, как работают сторонние API, и как использовать их для улучшения ваших сайтов.

Что такое сторонние API?

Сторонние API - это API, предоставляемые третьими лицами — как правило, такими компаниями, как Facebook, Twitter, or Google — чтобы вы могли получить доступ к их функциям с помощью JavaScript и использовать его на своём собственном сайте. Как мы показали в нашей вводной статье об API, одним из наиболее очевидных примеров является использование Google Maps APIs для отображения пользовательских карт на ваших страницах.

Давайте снова посмотрим на наш пример карты (см. исходный код на GitHub; см. это в действии), и используем его для иллюстрации того, как сторонние API отличаются от API-интерфейсов браузера.

Примечание: По умолчанию использование сторонних API на вашем сайте позволит им отслеживать файлы cookie своих доменов, устанавливать файлы cookie в исходное состояние, получать заголовки ссылок, определяющие посещаемые страницы, и разрешать им выполнять JavaScript на страницах, на которых они загружаются с теми же разрешениями (например, выполнить запросы AJAX на ваши серверы с теми же кукисами сеанса). Должны быть оценены вопросы регулирования, безопасности и конфиденциальности.

Примечание: Возможно, вы захотите сразу получить все наши примеры кода, в этом случае вы можете просто искать репо для файлов примеров, которые вам нужны в каждом разделе.

Они находятся на сторонних серверах

API браузера встроены в браузер - вы можете получить к ним доступ сразу из JavaScript. Например, API геолокации, доступный в нашем примере, осуществляется с использованием свойства геолокации объекта Navigator , которое возвращает объект Geolocation . Этот пример использует метод getCurrentPosition() этого объекта, для запроса текущего положения устройства:

.geolocation.getCurrentPosition(function(position)  . >); 

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

script type="text/javascript" src="https://maps.google.com/maps/api/js?key=AIzaSyDDuGt0E5IEGkcE6ZfrKfUtE9Ko_de66pA">/script> 

Затем вы можете начать использовать объекты, доступные в этой библиотеке. Например:

var latlng = new google.maps.LatLng( position.coords.latitude, position.coords.longitude, ); var myOptions =  zoom: 8, center: latlng, mapTypeId: google.maps.MapTypeId.TERRAIN, disableDefaultUI: true, >; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); 

Здесь мы создаём новый объект LatLng , используя конструктор google.maps.LatLng() , который содержит широту и долготу местоположения, которое мы хотим показать, полученные из API геолокации. Затем мы создаём объект опций ( myOptions ), содержащий эту и другую информацию, связанную с отображением карты. Наконец, мы фактически создаём карту, используя конструктор google.maps.Map() , который принимает в качестве параметров элемент, на котором мы хотим нарисовать карту, и объект опций.

Это вся информация, которую API Карт Google требует для построения простой карты. Сервер, к которому вы подключаетесь, обрабатывает все сложные вещи, такие как отображение правильных фрагментов карты для отображаемой области и т. д.

Примечание: Некоторые API обрабатывают доступ к их функциям несколько иначе, требуя от разработчика сделать HTTP-запрос (см. Получение данных с сервера) на определённый шаблон URL для получения определённых данных. Они называются RESTful API, и мы покажем пример этого позже в статье.

Разрешения обрабатываются по-разному

Безопасность API-интерфейсов браузеров, как правило, обрабатывается запросами разрешения, как описано в нашей первой статье. Целью этого является то, что пользователь знает, что происходит на сайтах, которые он посещает, и с меньшей вероятностью может стать жертвой того, кто использует API, злонамеренно.

Сторонние API имеют немного другую систему разрешений - они, как правило, используют ключевые коды, чтобы позволить разработчикам получить доступ к функциям API. Просмотрите URL-адрес библиотеки API Карт Google, с которой мы связались:

https://maps.google.com/maps/api/js?key=AIzaSyDDuGt0E5IEGkcE6ZfrKfUtE9Ko_de66pA

Параметр URL, указанный в конце URL-адреса, является ключом разработчика - разработчик приложения должен применять его для получения ключа, а затем включать его в свой код определённым образом, чтобы иметь доступ к функциям API. В случае с Картами Google (и другими API Google) вы подаёте заявку на получение ключа на Google Cloud Platform.

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

Требование к ключу заключается в том, что не каждый может использовать функциональность API без какой-либо подотчётности. Когда разработчик зарегистрировался для ключа, они затем известны поставщику API, и действие может быть предпринято, если они начинают делать что-то вредоносное с помощью API (например, отслеживать местоположение пользователей или пытаться спамить API с множеством запросов для остановки его работы, например). Самое простое действие - просто отменить их привилегии API.

Расширенный пример Карт Google

Теперь когда мы рассмотрели пример API Карт Google и посмотрели, как он работает, добавим ещё несколько функций, чтобы показать, как использовать некоторые другие функции API.

  1. Чтобы начать этот раздел, сделайте себе копию исходного файла Карт Google, в новой папке. Если вы уже клонировали репозиторий примеров, у вас уже есть копия этого файла, которую вы можете найти в папке the javascript/apis/third-party-apis/google-maps.
  2. Затем получите свой собственный ключ разработчика, выполнив следующие шаги:
    1. Перейдите в панель управления API-интерфейсом Google Cloud Platform.
    2. Создайте новый проект, если у вас его ещё нет.
    3. Нажмите кнопку Enable API.
    4. Выберите Google Maps JavaScript API.
    5. Нажмите кнопку Enable.
    6. Нажмите Create credentials, затем выберите API key.
    7. Скопируйте свой ключ API и замените существующий ключ в первом элементе примера вашим собственным (фрагмент между ?key= и меткой закрытия закрытия атрибута ( " ).)

    Примечание: Получение ключей API, связанных с Google, может быть немного затруднительным: в Менеджере API Google Cloud Platform много разных экранов, и рабочий процесс может немного отличаться в зависимости от того, как у вас уже установлена учётная запись. Если у вас возникнут проблемы с этим шагом, мы будем рады помочь — Свяжитесь с нами.

    Adding a custom marker

    Adding a marker (icon) at a certain point on the map is easy — you just need to create a new marker using the google.maps.Marker() constructor, passing it an options object containing the position to display the marker at (as a LatLng object), and the Map object to display it on.

      Add the following just below the var map . line:

    var marker = new google.maps.Marker( position: latlng, map: map, >); 
    var iconBase = "https://maps.google.com/mapfiles/kml/shapes/"; 
    var marker = new google.maps.Marker( position: latlng, icon: iconBase + "flag_maps.png", map: map, >); 

    Примечание: See Customizing a Google Map: Custom Markers for more information.

    Примечание: See Map marker or Icon names to find out what other icons are available, and see what their reference names are. Their file name will be the icon name they display when you click on them, with ".png" added on the end.

    Displaying a popup when the marker is clicked

    Another common use case for Google Maps is displaying more information about a place when its name or marker is clicked (popups are called info windows in the Google Maps API). This is also very simple to achieve, so let's have a look at it.

      First of all, you need to specify a JavaScript string containing HTML that will define the content of the popup. This will be injected into the popup by the API and can contain just about any content you want. Add the following line below the google.maps.Marker() constructor definition:

    var contentString = '

    Custom info window

    This is a cool custom info window.

    '
    ;
    var infowindow = new google.maps.InfoWindow( content: contentString, >); 
    .addListener("click", function ()  infowindow.open(map, marker); >); 

    Controlling what map controls are displayed

    Inside the original google.maps.Map() constructor, you'll see the property disableDefaultUI: true specified. This disables all the standard UI controls you usually get on Google Maps.

    1. Try setting its value to false (or just removing the line altogether) then reloading your example, and you'll see the map zoom buttons, scale indicator, etc.
    2. Now undo your last change.
    3. You can show or hide the controls in a more granular fashion by using other properties that specify single UI features. Try adding the following underneath the disableDefaultUI: true (remember to put a comma after disableDefaultUI: true , otherwise you'll get an error):

    zoomControl: true, mapTypeControl: true, scaleControl: true, 

    That's it for now — have a look around the Google Maps APIs documentation, and have some more fun playing!

    A RESTful API — NYTimes

    Now let's look at another API example — the New York Times API. This API allows you to retrieve New York Times news story information and display it on your site. This type of API is known as a RESTful API — instead of getting data using the features of a JavaScript library like we did with Google Maps, we get data by making HTTP requests to specific URLs, with data like search terms and other properties encoded in the URL (often as URL parameters). This is a common pattern you'll encounter with APIs.

    An approach for using third-party APIs

    Below we'll take you through an exercise to show you how to use the NYTimes API, which also provides a more general set of steps to follow that you can use as an approach for working with new APIs.

    Find the documentation

    When you want to use a third party API, it is essential to find out where the documentation is, so you can find out what features the API has, how you use them, etc. The New York Times API documentation is at https://developer.nytimes.com/.

    Get a developer key

    Most APIs require you to use some kind of developer key, for reasons of security and accountability. To sign up for an NYTimes API key, you need to go to https://developer.nytimes.com/signup.

    1. Let's request a key for the "Article Search API" — fill in the form, selecting this as the API you want to use.
    2. Next, wait a few minutes, then get the key from your email.
    3. Now, to start the example off, make copies of nytimes_start.html and nytimes.css in a new directory on your computer. If you've already cloned the examples repository, you'll already have a copy of these files, which you can find in the javascript/apis/third-party-apis/nytimes directory. Initially the element contains a number of variables needed for the setup of the example; below we'll fill in the required functionality.

    The app will end up allowing you to type in a search term and optional start and end dates, which it will then use to query the Article Search API and display the search results.

    Connect the API to your app

    First, you'll need to make a connection between the API, and your app. This is usually done either by connecting to the API's JavaScript (as we did in the Google Maps API), or by making requests to the correct URL(s).

    In the case of this API, you need to include the API key as a get parameter every time you request data from it.

      Find the following line:

    var key = "INSERT-YOUR-API-KEY-HERE"; 
    .addEventListener("submit", submitSearch); 
    function submitSearch(e)  pageNumber = 0; fetchResults(e); > function fetchResults(e)  // Use preventDefault() to stop the form submitting e.preventDefault(); // Assemble the full URL url = baseURL + "?api-key token operator">+ key + "&page token operator">+ pageNumber + "&q token operator">+ searchTerm.value + '&fq=document_type:("article")'; if (startDate.value !== "")  url += "&begin_date token operator">+ startDate.value; > if (endDate.value !== "")  url += "&end_date token operator">+ endDate.value; > > 

    submitSearch() sets the page number back to 0 to begin with, then calls fetchResults() . This first calls preventDefault() on the event object, to stop the form actually submitting (which would break the example). Next, we use some string manipulation to assemble the full URL that we will make the request to. We start off by assembling the parts we deem as mandatory for this demo:

    • The base URL (taken from the baseURL variable).
    • The API key, which has to be specified in the api-key URL parameter (the value is taken from the key variable).
    • The page number, which has to be specified in the page URL parameter (the value is taken from the pageNumber variable).
    • The search term, which has to be specified in the q URL parameter (the value is taken from the value of the searchTerm text ).
    • The document type to return results for, as specified in an expression passed in via the fq URL parameter. In this case, we just want to return articles.

    Next, we use a couple of if() statements to check whether the startDate and endDate s have had values filled in on them. If they do, we append their values to the URL, specified in begin_date and end_date URL parameters respectively.

    So, a complete URL would end up looking something like this:

    https://api.nytimes.com/svc/search/v2/articlesearch.json?api-key=4f3c267e125943d79b0a3e679f608a78&page=0&q=cats &fq=document_type:("article")&begin_date=20170301&end_date=20170312

    Примечание: You can find more details of what URL parameters can be included in the Article Search API reference.

    Примечание: The example has rudimentary form data validation — the search term field has to be filled in before the form can be submitted (achieved using the required attribute), and the date fields have pattern attributes specified, which means they won't submit unless their values consist of 8 numbers ( pattern="[0-9]" ). See Form data validation (en-US) for more details on how these work.

    Requesting data from the API

    Now we've constructed our URL, let's make a request to it. We'll do this using the Fetch API.

    Add the following code block inside the fetchResults() function, just above the closing curly brace:

    // Use fetch() to make the request to the API fetch(url) .then(function (result)  return result.json(); >) .then(function (json)  displayResults(json); >); 

    Here we run the request by passing our url variable to fetch() , convert the response body to JSON using the json() (en-US) function, then pass the resulting JSON to the displayResults() function so the data can be displayed in our UI.

    Displaying the data

    OK, let's look at how we'll display the data. Add the following function below your fetchResults() function.

    function displayResults(json)  while (section.firstChild)  section.removeChild(section.firstChild); > var articles = json.response.docs; if (articles.length === 10)  nav.style.display = "block"; > else  nav.style.display = "none"; > if (articles.length === 0)  var para = document.createElement("p"); para.textContent = "No results returned."; section.appendChild(para); > else  for (var i = 0; i  articles.length; i++)  var article = document.createElement("article"); var heading = document.createElement("h2"); var link = document.createElement("a"); var img = document.createElement("img"); var para1 = document.createElement("p"); var para2 = document.createElement("p"); var clearfix = document.createElement("div"); var current = articles[i]; console.log(current); link.href = current.web_url; link.textContent = current.headline.main; para1.textContent = current.snippet; para2.textContent = "Keywords: "; for (var j = 0; j  current.keywords.length; j++)  var span = document.createElement("span"); span.textContent += current.keywords[j].value + " "; para2.appendChild(span); > if (current.multimedia.length > 0)  img.src = "http://www.nytimes.com/" + current.multimedia[0].url; img.alt = current.headline.main; > clearfix.setAttribute("class", "clearfix"); article.appendChild(heading); heading.appendChild(link); article.appendChild(img); article.appendChild(para1); article.appendChild(para2); article.appendChild(clearfix); section.appendChild(article); > > > 

    There's a lot of code here; let's explain it step by step:

    • The while loop is a common pattern used to delete all of the contents of a DOM element, in this case, the element. We keep checking to see if the has a first child, and if it does, we remove the first child. The loop ends when no longer has any children.
    • Next, we set the articles variable to equal json.response.docs — this is the array holding all the objects that represent the articles returned by the search. This is done purely to make the following code a bit simpler.
    • The first if() block checks to see if 10 articles are returned (the API returns up to 10 articles at a time.) If so, we display the that contains the Previous 10/Next 10 pagination buttons. If less than 10 articles are returned, they will all fit on one page, so we don't need to show the pagination buttons. We will wire up the pagination functionality in the next section.
    • The next if() block checks to see if no articles are returned. If so, we don't try to display any — we just create a containing the text "No results returned." and insert it into the .
    • If some articles are returned, we, first of all, create all the elements that we want to use to display each news story, insert the right contents into each one, and then insert them into the DOM at the appropriate places. To work out which properties in the article objects contained the right data to show, we consulted the Article Search API reference. Most of these operations are fairly obvious, but a few are worth calling out:
      • We used a for loop ( for(var j = 0; j < current.keywords.length; j++) < . >) to loop through all the keywords associated with each article, and insert each one inside its own , inside a

        . This was done to make it easy to style each one.

      • We used an if() block ( if(current.multimedia.length > 0) < . >) to check whether each article actually has any images associated with it (some stories don't.) We display the first image only if it actually exists (otherwise an error would be thrown).
      • We gave our element a class of "clearfix", so we can easily apply clearing to it (this technique is needed at the time of writing to stop floated layouts from breaking.)

      If you try the example now, it should work, although the pagination buttons won't work yet.

      Wiring up the pagination buttons

      To make the pagination buttons work, we will increment (or decrement) the value of the pageNumber variable, and then re-rerun the fetch request with the new value included in the page URL parameter. This works because the NYTimes API only returns 10 results at a time — if more than 10 results are available, it will return the first 10 (0-9) if the page URL parameter is set to 0 (or not included at all — 0 is the default value), the next 10 (10-19) if it is set to 1, and so on.

      This allows us to easily write a simplistic pagination function.

        Below the existing addEventListener() call, add these two new ones, which cause the nextPage() and previousPage() functions to be invoked when the relevant buttons are clicked:

      .addEventListener("click", nextPage); previousBtn.addEventListener("click", previousPage); 
      function nextPage(e)  pageNumber++; fetchResults(e); > function previousPage(e)  if (pageNumber > 0)  pageNumber--; > else  return; > fetchResults(e); > 

      YouTube example

      We also built another example for you to study and learn from — see our YouTube video search example. This uses two related APIs:

      • The YouTube Data API to search for YouTube videos and return results.
      • The YouTube IFrame Player API to display the returned video examples inside IFrame video players so you can watch them.

      This example is interesting because it shows two related third-party APIs being used together to build an app. The first one is a RESTful API, while the second one works more like Google Maps (with constructors, etc.). It is worth noting however that both of the APIs require a JavaScript library to be applied to the page. The RESTful API has functions available to handle making the HTTP requests and returning the results, so you don't have to write them out yourself using say fetch or XHR.

      We are not going to say too much more about this example in the article — the source code has detailed comments inserted inside it to explain how it works.

      Summary

      This article has given you a useful introduction to using third party APIs to add functionality to your websites.

      In this module

      • Introduction to web APIs
      • Manipulating documents
      • Fetching data from the server
      • Third party APIs
      • Drawing graphics (en-US)
      • Video and audio APIs (en-US)
      • Client-side storage

      Found a content problem with this page?

      • Edit the page on GitHub.
      • Report the content issue.
      • View the source on GitHub.

      This page was last modified on 3 авг. 2023 г. by MDN contributors.

      Your blueprint for a better internet.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *