Свой API на Python. Flask, чтобы быстро писать API
Что такое API и как оно работает: объяснение с нуля, шаг за шагом
Серверная часть
API - это
код на сервере
, который участвует почти во всех ключевых функциях бэкенда сайта:CRUD-операции
с базой данных: чтение, добавление, обновление, удаление данныхАвторизация
на сайтеВалидация
данных, которые приходят с полей сайта (формы, инпуты и т.д)- Поиск, изменение, добавление страниц на сайте. И многое другое, конечно же
Пример простого кода API на Python, используя Flask:
@app.route('/users', methods=['GET']) # хотим получить информацию о "/users"
def get_users():
# формируем объект-как-json с ответом:
response = {
"user_name": "Damir",
"id": 0
}
return jsonify(response) # возвращаем json с информацией о человеке
2
3
4
5
6
7
8
- Точка входа в API называется
эндпоинт
:
@app.route('/users', methods=['GET']) # когда переходим на эндпоинт "/users"
def get_users():
...
@app.route('/question', methods=['GET', 'POST']) # эндпоинт "/question"
def get_questions():
...
2
3
4
5
6
7
- У эндпоинта могут быть
параметры
, которые позволяет доставать данные выборочно, например, только об одном пользователе:
@app.route('/users', methods=['GET'])
def get_users():
...
@app.route('/users/<id>', methods=['GET']) # эндпоинт с параметром "id"
def get_user(id):
...
2
3
4
5
6
7
Клиентская часть
Чтобы получить данные с API, мы посылаем запрос из
клиента
. Клиентом может быть сайт, телефон... Даже твоя VS Code (плагин Thunder Client)В веб-разработке мы обычно используем
fetch-запросы
, которые отправляем из нашего JavaScript:
async function fetchData() {
/* посылаем запрос на сервер (1) и принимаем ответ из сервера в формате json (2) */
const response = await fetch("https://jsonplaceholder.typicode.com/todos/1"); // 1)
const data = await response.json(); // 2)
/* выводим json (3) в формате строки (4) на сайте */
let placeForData = document.querySelector(".output"); // 3)
placeForData.innerText = JSON.stringify(data); // 4)
}
fetchData();
2
3
4
5
6
7
8
9
10
11
Смотри живой пример этого кода ниже:
Живой пример на странице
Эти данные вытянуты из API. Код взят из примера выше. Можешь проверить своими руками, это полезно
Правило тут такое: клиент живёт отдельно, сервер - отдельно. Мы связываем их через (fetch-запросы)[/web/lessons/js/fetch/]. Так и создаётся связь клиент-сервер, как показано на картинке ниже:
Принцип
разделения
клиента и сервера - один из основных принципов работы REST API. Смотри первую иконку ниже:
CORS-механизм в браузере
Когда мы посылаем запрос из клиента на сервер, в браузере срабатывает
CORS-механизм
. Cross Origin Resource Sharing, он же CORS - это вшитая в браузер технология защиты от несанкционированного доступа одного ресурса к другому. Грубо говоря, чтобы сайт А не спёр данные с сайта Б.CORS-механизм браузера даёт добро или, наоборот, блокирует запросы на
сервер
из нашего клиента:
- CORS-механизм основан на
preflight-запросе
: перед отправкой твоего запроса срабатывает ещё один, невидимый, запрос, который проверяет, настроен ли сервер на приём входящих запросов и отправку данных:
- Если сервер не настроен корректно или
не хочет
отдавать данные, ты увидишь в консоли браузера CORS-ошибку (я её называю именно так):
- Эту ошибку выдаёт тот самый preflight-запрос. Чтобы исправить её, достаточно добавить на свой сервер поддержку CORS-механизма. Вот пример с Flask:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
# включаем поддержку CORS, дабы сервер мог свободно делиться данными
CORS(app)
@app.route('/')
def home():
return 'Hello, CORS is enabled!'
2
3
4
5
6
7
8
9
10
Если же у тебя нет доступа к серверу, значит, тут 2 причины:
- Он не настроен корректно
- ИЛИ ты неправильно отправляешь запрос.
Убедись, что А) эндпоинт сервера
действительно
настроен на отправку данных и Б) что твойзапрос
написан 100% правильно
Итоговый код для создания и работы с API: клиент и сервер
Клиент на JavaScript
Отправляет fetch-запрос на сервер:
async function fetchData() {
const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
const data = await response.json();
let placeForData = document.querySelector(".output");
placeForData.innerText = JSON.stringify(data);
}
fetchData();
2
3
4
5
6
7
8
9
Сервер на Python + Flask
Ловит fetch-запрос и отвечает объектом Response с данными в формате JSON:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route('/')
def home():
return 'Hello, CORS is enabled!'
@app.route('/users', methods=['GET'])
def get_users():
...
@app.route('/users/<id>', methods=['GET']) # эндпоинт с параметром "id"
def get_user(id):
...
if __name__ == '__main__':
app.run()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20