Работа с открытыми источниками данных с помощью API
Чтобы было интереснее изучать эту тему решил сразу сделать pet-проект. Это игра, которая предлагает угадать страну по флагу. И показывает карту из Яндекс-карт, а также статью об этой стране из википедии. Решил сразу сделать и английскую и русскую версии))).
В итоге вот что получилось:
Но обо всём по порядку.
Содержание:
1. Подключение внешней открытой БД с информацией о странах (в том числе там есть флаги) https://restcountries.com/v3.1/all
2. Подключение Яндекс-карт
2.1. Получение ключа
2.2. Работа с библиотекой react-yandex-maps
2.3. Как спрятать ключ. Использование apikey: process.env.REACT_APP_
3. Подключение википедии (самое интересное)
4. Инетересные приёмы:
4.1. Получение содержимого объекта, если ключ заранее неизвестен.
4.2. Как сделать большие числа красивыми.
4.3. Как снизить трафик. Использование localStorage и создание пользовательского хука useLocalStorage.
1. Для начала нашел открытую базу данных со всеми странами и флагами. Вот сайт с описанием работы этой БД https://restcountries.com
Вот сама БД https://restcountries.com/v3.1/all
Нам нужны сразу все страны. Структура данных выгладит вот так
[
{
"name": {
"common": "Haiti",
"official": "Republic of Haiti",
"nativeName": {
"fra": {
"official": "République d'Haïti",
"common": "Haïti"
},
"hat": {
"official": "Repiblik Ayiti",
"common": "Ayiti"
}
}
},
"tld": [
".ht"
],
"cca2": "HT",
"ccn3": "332",
"cca3": "HTI",
"cioc": "HAI",
"independent": true,
"status": "officially-assigned",
"unMember": true,
"currencies": {
"HTG": {
"name": "Haitian gourde",
"symbol": "G"
}
},
"idd": {
"root": "+5",
"suffixes": [
"09"
]
},
"capital": [
"Port-au-Prince"
],
"altSpellings": [
"HT",
"Republic of Haiti",
"République d'Haïti",
"Repiblik Ayiti"
],
"region": "Americas",
"subregion": "Caribbean",
"languages": {
"fra": "French",
"hat": "Haitian Creole"
},
"translations": {
"ara": {
"official": "جمهورية هايتي",
"common": "هايتي"
},
// здесь идет название почти на всех языках мира
// нам нужен только русский
"rus": {
"official": "Республика Гаити",
"common": "Гаити"
},
},
"latlng": [
19.0,
-72.41666666
],
"landlocked": false,
"borders": [
"DOM"
],
"area": 27750.0,
"demonyms": {
"eng": {
"f": "Haitian",
"m": "Haitian"
},
"fra": {
"f": "Haïtienne",
"m": "Haïtien"
}
},
"flag": "🇭🇹",
"maps": {
"googleMaps": "https://goo.gl/maps/9o13xtjuUdqFnHbn9",
"openStreetMaps": "https://www.openstreetmap.org/relation/307829"
},
"population": 11402533,
"gini": {
"2012": 41.1
},
"fifa": "HAI",
"car": {
"signs": [
"RH"
],
"side": "right"
},
"timezones": [
"UTC-05:00"
],
"continents": [
"North America"
],
"flags": {
"png": "https://flagcdn.com/w320/ht.png",
"svg": "https://flagcdn.com/ht.svg",
"alt": "The flag of Haiti is composed of two equal horizontal bands of blue
and red. A white square bearing the national coat of arms is superimposed
at the center of the field."
},
"coatOfArms": {
"png": "https://mainfacts.com/media/images/coats_of_arms/ht.png",
"svg": "https://mainfacts.com/media/images/coats_of_arms/ht.svg"
},
"startOfWeek": "monday",
"capitalInfo": {
"latlng": [
18.53,
-72.33
]
},
"postalCode": {
"format": "HT####",
"regex": "^(?:HT)*(\\d{4})$"
}
},
]
Создадим функцию для получения данных
fetch("https://restcountries.com/v3.1/all", {
method: 'GET',
headers: {
'"Accept": "application/json",
"Content-Type": "application/json"
}
})
.then((response) => {
if (response.ok) {
return response.json();
}
return Promise.reject(response.json())
})
.then ((data) => {
setCountries(data);
})
.catch ((error) => {
console.log(error);
})
2. Подключим к нашему приложению Яндекс-карты.
2.1. Для подключения Яндекс-карт нужно получить ключ.
Заходим в https://yandex.ru/dev/maps/jsapi/doc/2.1/quick-start/index.html
Всего 4 шага:
Шаг 1. Получите API-ключ
Зайдите на страницу Кабинета Разработчика и нажмите кнопку Получить ключ.
Во всплывающем окне выберите сервис «JavaScript API и HTTP Геокодер».После заполнения формы появится надпись «Сервис успешно подключен». Созданный ключ будет доступен в разделе «Ключи». Его необходимо использовать в дальнейшем при подключении API.
Чтобы посмотреть ключ - он здесь 👇https://developer.tech.yandex.ru/services/3
Шаг 2. Подключите API
Добавьте в заголовок head HTML-страницы строку следующего вида:
<head>
<script src="https://api-maps.yandex.ru/2.1/?apikey=ваш API-ключ&lang=ru_RU" type="text/javascript">
</script>
</head>
Шаг 3. Создайте контейнер для карты
Создайте видимый контейнер ненулевого размера, в котором будет размещена карта. В качестве контейнера может использоваться любой HTML-элемент блочного типа (например, элемент div). Карта заполнит этот элемент полностью.
<body>
<div id="map" style="width: 600px; height: 400px"></div>
</body>
Шаг 4. Создайте карту
В JavaScript-коде создайте экземпляр карты. Конструктору нужно передать:
- идентификатор HTML-контейнера;
- центр карты;
- коэффициент масштабирования.
<script type="text/javascript">
ymaps.ready(init);
function init(){
var myMap = new ymaps.Map("map", {
center: [55.76, 37.64],
zoom: 7
});
}
</script>
2.2. Но все-таки хочется React. Ищем и находим библиотеку react-yandex-maps
https://www.npmjs.com/package/react-yandex-maps/v/2.1.3?activeTab=readme
Устанавливаем:
npm i react-yandex-maps@2.1.3
или
yarn add react-yandex-maps@2.1.3
Импортируем библиотеку в приложение
import { YMaps } from '@pbe/react-yandex-maps';
Находим нужный в перечне и прописываем свой ключ.
<YMaps query={{ apikey: здесь Ваш ключ, lang: lang }}>
// здесь код программы
</YMaps>
Создадим компонент карты:
На понадобится компонент Map из установленной библиотеки и координаты столицы, которые можем взять из https://restcountries.com/v3.1/all (см. выше)
"capitalInfo": { "latlng": [ 18.53, -72.33 ]}
Информацию о стране тоже возьмем оттуда)))
2.3. Спрячем полученный ключ в переменные окружения. Но ведь фронтенд не использует переменные окружения? Нельзя установить Dotenv - это только для бэка. Что же делать?
Разработчики REACT уже позаботились об этом. В случае использования CRA, ничего настраивать не требуется. Под капотом уже установлены необходимые пакеты и настроен webpack для обработки таких файлов. Обязательным условием является только префикс REACT_APP_ для переменных окружения. Например, REACT_APP_API_KEY=secret-api-key. Другие имена переменных будут игнорироваться, чтобы избежать случайного раскрытия секретного ключа, который может иметь то же имя.
apikey: process.env.REACT_APP_APIKEY_YANDEX_MAPS,
Но !!! Во время сборки (build), в коде приложения, переменные вида process.env.REACT_APP_API_URL заменяются их значениями.
Поэтому мы только лишь обезопасили себя, спрятав ключ при размещении кода программы на гитхабе.
3. Подключим википедию.
Смотрим документацию: https://www.mediawiki.org/wiki/API:Properties#revisions_.2F_rv
А это вот ссылка на все знания мира 😀 (адрес открытой БД) https://en.wikipedia.org/w/api.php
А если хотим читать на русском? Вот пожалуйста:
https://ru.wikipedia.org/w/api.php
А вот еще ссылка (здесь кратко собрано всё самое интересное и нужное - спасибо автору)
https://github.com/mudroljub/wikipedia-api-docs
Только нужно с ключами писать...
Вот если, например, хочу получить статью о кефире... Пожалуйста
https://ru.wikipedia.org/w/api.php?action=query&titles=кефир&prop=extracts|pageimages|info&pithumbsize=400&inprop=url&redirects=&format=json&origin=*
В итоге вот что получилось:
Ссылка на гитхаб https://github.com/SeverInvest/flag-quiz
4. Из интересного:
4.1. В википедии id статьи - это ключ.
query: {pages: {id: {extract: выдержка статьи(первые 10 предложений)}}
Как достать содержимое, ведь компьютер не знает ключ id?
Вот так (переменная identificator получает название ключа):
4.2. И небольшая функция, чтобы красиво выводить большие числа (делит по три символа и ставит между ними пробел)
125836021 чел. преобразует в 125 836 021 чел.
4.3. Чтобы не грузить большую БД со всеми странами сделаем сохранение ее в localStorage браузера
А вот сам хук