Скучная теория:
В RestAPI интеграциях есть основные принципы, один из них — это stateless rest api принцип. В скучной теории, определение этого принципа гласит, что stateless в клиент-серверной архитектуре — это когда сервер не хранит информацию о состоянии клиента. Но что это значит в техническом плане? Как препарировать это простое определение?
В своих объяснениях, я пытаюсь объяснить stateless в сравнении с stateful. Stateful vs stateless. Однако stateful не является принципом RestApi.
Объяснение 1 — видео
Я записал небольшое видео, делая акцент на объяснении принципа из офлайна. На примере заказа пиццы: VK и Youtube?
Объяснение 2 — код
Stateful и stateless отличия
В нашем примере Stateful состояния, мы (клиенты) будем передавать на ручку /stateful (сервера) запрос. По определению — stateful — хранит состояние клиента, то есть сервер должен хранить наше состояние. В качестве нашего состояния, мы будем хранить кол-во наших вызовов на эту ручку.
Посмотрите на код ниже:
// Stateful endpoint@Get('stateful')getStateful(@Req() req: Request): string { // Получаем IP-адрес клиента (упрощённо для демонстрации) const clientIP = req.ip;
// Инициализируем счётчик клиента, если он не существует if (!this.clientCounts[clientIP]) { this.clientCounts[clientIP] = 0; }
// Увеличиваем счётчик для этого клиента this.clientCounts[clientIP] += 1;
// Возвращаем текущий счётчик клиента return `Stateful: Вы выполнили ${this.clientCounts[clientIP]} запросов.`;}- Строка 5 — сохраняет ваш IP в переменной памяти (мы ведь stateful)
- Строка 13 — прибавляет к каждому вызову +1
- Строка 16 — выводит результат
То есть, в этом коде демонстрируется stateful состояние: поскольку кол-во запросов с вашего IP хранится в памяти сервера (сервер хранит состояние).
Если я перезагружу сервер, то память обнулится и кол-во запросов снова будет начинать с 0.
Stateless
В отличии от stateful, здесь сервер не сохраняет состояние (каждый запрос изолирован). То есть для сервера ваш клиентский запрос в ручку /stateless будет всегда, как новый. Поскольку он не использует память, как ячейку для хранения состояния. Это и есть один из основных принципов RestApi.
Посмотрим на код ниже:
// Stateless endpoint@Get('stateless')getStateless(@Query('count') count: string): string { // Парсим значение count из параметра запроса (по умолчанию 0, если не указано) const currentCount = parseInt(count) || 0; const newCount = currentCount + 1;
// Возвращаем обновлённое значение счётчика return `Stateless: Вы выполнили ${newCount} запросов. Отправьте ?count=${newCount} в следующем запросе.`;}- Строка 3 — получает переменную из query параметра: count (/stateless?count=1)
- Строка 6 прибавляет +1 к счётчику (по аналогии строки 13 в stateful)
- Строка 9 — выводит результат
Возможно, вы не понимаете, а какая разница по коду?
И там и там есть переменные, которые хранятся в памяти. Почему тогда это тоже stateless, если мы так же храним состояние в памяти?
Мы храним это состояние только в рамках текущего вызова (хранением бы я это не назвал).
То есть когда вы сделаете повторный запрос, счётчик обнулится. Он не сохраняется в памяти, в отличии от stateful. В этом и есть разница между stateful и stateless.