## 1. API API - это публичный интерфейс сервиса: то, чем потребитель сервиса может пользоваться. Примеры: - На ПлюсАгенте есть бэкенд (код на сервере) и фронтенд (код в браузере). Бэкенд предоставляет различные адреса, по которому фронтенд может сделать запрос и получить ответ (например, получение списка агентов). Это и называется API бэкенда ПлюсАгент. - Сервис GreenApi предоставляет различные адреса, по которому можно делать запросы для взаимодействия с WhatsApp (например, отправить сообщение). Это - API сервиса GreenApi. Если описаны инструкции по тому, какие именно запросы поддерживаются, то это - документация к API. ## 2. HTTP HTTP - это протокол взаимодействия по сети. Чаще всего API сервиса подразумевает взаимодействие по HTTP (из примеров выше: и бекенд ПлюсАгент, и GreenApi работают по HTTP). HTTP запрос состоит из следующих частей: - HTTP Метод: - GET запрос обычно делается для получения информации - POST запрос обычно делается для изменения информации - подробнее о методах в разделе про REST - Путь запроса - например `/api/agent`; похоже на путь к файлу в файловой системе - Заголовки запроса - в них передаётся различная служебная информация; нам они сейчас не обязательны - Тело запроса - здесь передаётся информация, которую нам надо записать (например, текст сообщения для WhatsApp); у GET-запросов нет тела, так как они ничего не записывают Пример: браузеры и сайты тоже общаются по HTTP; поэтому, когда мы что-то ищем в Гугле, то мы делаем вот такой запрос: - HTTP метод GET, так как мы получаем информацию - Путь запроса: https://www.google.com/search?q=Сургут (здесь `q=Сургут` - это параметр запроса) - Заголовки запроса: разная служебная информация, например, версия нашего браузера - Тело запроса: пустое, потому-что GET В результате отправки HTTP запроса мы получаем HTTP ответ (логично). У ответа есть "статус" - это числовой код, по которому можно понять, успешен ли запрос. Топ 3 статусов: - 200: всё хорошо - 404: ресурс не найден - 500: ошибка на сервере ## 3. REST REST - это стиль построения API, основанный на использовании HTTP с дополнительными ограничениями. Чтобы было понятнее, я сначала приведу пример REST и не-REST API. Пример: скажем, мы делаем бэкенд для ПлюсАгент и создаём возможность создать агента и получить информацию об агентах. REST подход: - Получение списка агентов: `GET /api/agent` - Получения данных агента с ID 123: `GET /api/agent/123` - Создание агента: `POST /api/agent` (в теле запроса - данные об агенте) - Обновление данных агента с ID 123: `PUT /api/agent/123` (в теле запроса - данные об агенте) - Удаление риелтора с ID 123: `DELETE /api/agent/123` Не-REST подход: - Получение списка агентов: `GET /api/get-agents` - Получения данных агента с ID 123: `GET /api/get-agent?id=123` - Создание агента: `POST /api/create-agent` (в теле запроса - данные об агенте) - Обновление данных агента с ID 123: `POST /api/update-agent?id=123` (в теле запроса - данные об агенте) - Удаление риелтора с ID 123: `POST /api/delete-agent?id=123` Правила REST: - Путь запроса - это путь к какому-то ресурсу (напрмер, `/api/agent`; обычно - это существительное) - Мы описываем то, что мы хотим сделаем с помощью HTTP метода (это глагол): - GET - получить данные о ресурсе - POST - создать ресурс - PUT - обновить ресурс - DELETE - удалить ресурс - Сервер не обязан хранить информацию о предыдущем запросе - каждый запрос должен содержать достаточно информации, чтобы его обработать (поэтому говорят, что "REST - это протокол без состояния") ## 4. SQL Основные запросы: - Создать таблицу агентов: `CREATE TABLE agents (id INT PRIMARY KEY, name VARCHAR(), createdAt TIMESTAMP())` - Получить всех агентов: `SELECT * FROM agents` - Получить одного агента: `SELECT * FROM agents WHERE id = 1` - Добавить агента: `INSERT INTO agents (id, name, createdAt) VALUES (1, "Александр", "2022-10-02 17:00:00")` - Обновить агента: `UPDATE agents SET name = "Алексей" WHERE id = 1` - Удалить агента: `DELETE FROM agents WHERE id = 1` ## 5. ООП ООП - это парадигма программирования (подход к программирования), в которой объединяются данные и поведение. Это реализуется с помощью классов. Класс - это описание какой-либо сущности в программе - то, какие в нём есть данные (в ОПП это называется "свойства"; ближайший аналог - переменная) и какое у него есть поведение (в ООП это называется "метод"; ближайший аналог - процедура). Пример: класс "круг"; у него объявлено: - Свойства "x" (число), "y" (число), "радиус" (число) - Метод "получить площадь" (возвращает число; это процедура, которая рассчитывает формулу π × r^2) В псевдо-коде это выглядит так: ``` класс Круг { x: число y: число радиус: число получитьПлощадь(): число { вернуть 3,1415 * радиус * радиус } } ``` Объект - это экземпляр класса. В объекте те свойства, что объявлены в классе могут получать конкретные данные; например: ``` мойКруг = новый Круг() мойКруг.x = 1 мойКруг.y = 1 ``` ООП имеет 3 свойства: 1. Инкапсуляция (от слова капсула) - это как раз и есть объединение данных и поведения в одном месте. Также, в некоторых ООП-языках поддерживается "сокрытие" - возможность объявить некоторые методы и свойства приватными. Приватные методы недоступны "снаружи" класса. Это делается для того, чтобы дать программисту создателю-класса возможность обозначить "внутренности" класса от его публичного интерфейса. Тогда другому програамисту для понимания того, что можно сделать к этим классом, достаточно посмотреть только на публичные методы и свойства. Пример: мы убрали операцию возведения в степень в отдельную функция. Однако программисту, который будет пользоваться классом "Круг" не обязательно знать, что у класса есть такой метод, так что сделаем его приватным: ``` класс Круг { x: число y: число радиус: число получитьПлощадь(): число { вернуть 3,1415 * вСтепень(радиус) } приватно вСтепень(a: число) { вернуть a * a } } ``` 2. Наследование - возможность наследовать классы от других классов; при наследовании классы автоматически получают свойства и методы от родительских классов; пример: ``` класс Фигура { x: число y: число } класс Круг расширяет Фигура { радиус: число } ``` В этом примере у класса Круг будут свойства `x` и `y`. 3. Полиморфизм - возможность использвать наследников вместо родительских классов. Пример - у в программе нас есть метод для определения координатной четверти центра фигуры: ``` получитьЧетверть(фигура: Фигура): число { если (x > 0 и y > 0) то вернуть 1 ... } ``` Мы легко можем отправить в этом метод наш Круг, если он наследуется от класса Фигура: ``` мойКруг = новый Круг() мойКруг.x = 1 мойКруг.y = 1 получитьЧетверть(мойКруг) <-- вернёт 1 четверть ```