Backend Ready | IT
8.34K subscribers
1.25K photos
93 videos
6 files
1K links
По всем вопросам: @AdilNow
Download Telegram
Похоже, компании реально переосмысляют весь SDLC вокруг агентов и пытаются прийти к миру, где инженеры, возможно, вообще не будут писать ни одной строчки кода руками.

Я тут общался с одним инженерным лидом, и по ощущениям многие уже готовятся к полностью agentic SDLC. В репозиториях начинают появляться файлы под Claude и прочие agent-штуки, под внутренние инструменты пилят MCP, и в целом многое меняется. Код-ревью тоже автоматизируют, и это только один из пунктов.

Вот такие времена :)

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое SOLID?

Это акроним, представляющий пять основных принципов объектно-ориентированного программирования и дизайна, которые помогают разработчикам создавать более понятный, гибкий и поддерживаемый код. Эти принципы были предложены Робертом Мартином (известным также как Uncle Bob) и являются основополагающими в области программной инженерии.

🟠Single Responsibility Principle (Принцип единственной ответственности)
Этот принцип гласит, что у каждого класса должна быть только одна причина для изменения, то есть класс должен иметь только одну ответственность или задачу. Это помогает уменьшить сложность и повысить читаемость кода, делая его более управляемым и легким для поддержки. Когда класс выполняет лишь одну задачу, его легче тестировать и изменять без влияния на другие части системы.

🟠Open/Closed Principle (Принцип открытости/закрытости)
Программные сущности (классы, модули, функции и т.д.) должны быть открыты для расширения, но закрыты для модификации. Это означает, что поведение классов должно быть расширяемым без изменения их исходного кода. Для реализации этого принципа часто используются абстракции и интерфейсы, которые позволяют добавлять новые функции через наследование и полиморфизм, не нарушая существующий код.

🟠Liskov Substitution Principle (Принцип подстановки Барбары Лисков)
Объекты подклассов должны быть заменяемы объектами суперклассов без нарушения правильности программы. Это означает, что если у нас есть базовый класс и его подкласс, то мы должны иметь возможность заменить экземпляры базового класса экземплярами подкласса без изменения желаемого поведения программы. Этот принцип поддерживает полиморфизм и гарантирует, что производные классы могут корректно взаимодействовать с остальным кодом.

🟠Interface Segregation Principle (Принцип разделения интерфейсов)
Клиенты не должны зависеть от интерфейсов, которые они не используют. Этот принцип направлен на создание узкоспециализированных интерфейсов, которые являются специфичными для отдельных клиентов. Таким образом, классы, реализующие эти интерфейсы, не будут обязаны реализовывать методы, которые им не нужны. Это уменьшает сложность и улучшает управляемость кода, а также способствует гибкости и повторному использованию интерфейсов.

🟠Dependency Inversion Principle (Принцип инверсии зависимостей)
Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба типа модулей должны зависеть от абстракций. Этот принцип направлен на уменьшение зависимости высокоуровневого кода от низкоуровневых деталей, что позволяет легче изменять и тестировать систему. Реализация этого принципа часто включает использование инверсии управления (IoC) и внедрения зависимостей (DI), что способствует созданию более гибких и модульных архитектур.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍1
This media is not supported in your browser
VIEW IN TELEGRAM
Ограничение скорости за 40 секунд

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1😁1
🤔 Что в твоем понимании значит правильный код?

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

🚩Характеристики

🟠Читаемость
Переменные, функции, классы и другие сущности должны иметь понятные и описательные имена, которые отражают их назначение. Следование стандартам кодирования и стиля, включая правильное форматирование, отступы и использование комментариев. Использование комментариев для объяснения сложных или неочевидных частей кода, но не для очевидных вещей, которые можно понять из названий переменных и функций.

🟠Сопровождаемость
Код должен быть разбит на модули, функции или классы с чётко определёнными задачами. Это упрощает его понимание, тестирование и изменение. Избегание дублирования кода через применение принципа DRY (Don't Repeat Yourself). Код должен быть легко тестируемым. Написание автоматических тестов для проверки корректности работы помогает предотвратить ошибки.

🟠Эффективность
Код должен быть оптимизирован для выполнения задач с минимальными затратами ресурсов, таких как время выполнения и использование памяти. Использование эффективных алгоритмов и структур данных для обеспечения хорошей производительности, особенно на больших объемах данных.

🟠Надежность
Код должен корректно обрабатывать ошибки и исключительные ситуации, предотвращая неожиданные сбои. Проверка входных данных для предотвращения некорректного поведения программы.

🟠Документированность
Написание документации, описывающей основные компоненты системы, их взаимодействие и использование. Хорошо документированный код облегчает его понимание для других разработчиков.

🟠Применение принципов и паттернов проектирования
Применение принципов SOLID для создания устойчивого, гибкого и масштабируемого кода. Использование проверенных решений для общих задач проектирования.

🚩Примеры

Читаемость и сопровождаемость
def calculate_area(radius):
"""Calculate the area of a circle given its radius."""
import math
if radius < 0:
raise ValueError("Radius cannot be negative")
return math.pi * radius ** 2


Тестируемость
def add(a, b):
"""Add two numbers and return the result."""
return a + b

# Unit test for the add function
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0

test_add()


Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
Видел интересное видео от CTO Zerodha про то, как они масштабировали Postgres с 7+ млн таблиц.
Технология просто выносит мозг, а если копнуть глубже, становится еще веселее:

- синхронщина? не масштабируется, значит выкидываем.
- все в async. тяжелую генерацию отчетов ставим в очередь.
- независимый middleware, которому все равно на базу и на приложение.
- собрали “DungBeetle” на Go: обобщенные, независимые от СУБД HTTP API, чтобы тянуть отчеты из любой базы.
- результаты сливаем в отдельную Results DB, а приложение читает уже оттуда.

Вот так выглядит настоящий масштаб.

Смотреть видео

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
📈 Python 3.14 стал быстрее до 30% благодаря новому интерпретатору. В чем магия?

Python 3.14 стал до 30 % быстрее благодаря новому интерпретатору с tail call — ускорение без изменений в коде, просто обновите версию.


Команда CPython продолжает ускорять Python. Так, релиз 3.14 уже включает одну из самых заметных внутренних реформ — новый байт-кодовый интерпретатор.

❗️ Благодаря этому улучшению в некоторых случаях производительность увеличивается до 30%, при этом средний прирост оценивается в 3–5%.

Читать статью

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥41👍1
🤔 Как можно заблокировать конкретные поля в Postgres?

В PostgreSQL можно использовать различные методы для блокировки конкретных полей или строк таблицы, чтобы предотвратить их изменение или обеспечить управление конкурентным доступом к данным. Наиболее распространенные способы включают использование транзакционных блокировок и политик доступа.

🟠Использование блокировок уровня строки (Row-Level Locks)
PostgreSQL поддерживает блокировки уровня строки с помощью команд SELECT FOR UPDATE и SELECT FOR SHARE. Эти команды позволяют заблокировать конкретные строки для изменения другими транзакциями, пока текущая транзакция не завершится.SELECT FOR UPDATE:
BEGIN;  -- Начало транзакции

-- Выбираем и блокируем строки для обновления
SELECT * FROM my_table WHERE id = 1 FOR UPDATE;

-- Выполняем необходимые операции
UPDATE my_table SET field = 'new_value' WHERE id = 1;

COMMIT; -- Завершение транзакции


SELECT FOR SHARE:
BEGIN;  -- Начало транзакции

-- Выбираем и блокируем строки для чтения
SELECT * FROM my_table WHERE id = 1 FOR SHARE;

-- Выполняем необходимые операции
-- Изменение данных будет заблокировано для других транзакций
-- Однако, можно выполнять SELECT
COMMIT; -- Завершение транзакции


🟠Использование политик доступа (Row-Level Security Policies)
Политики безопасности на уровне строк позволяют определить, кто и при каких условиях может видеть или изменять данные в таблице. Это обеспечивается с помощью функций и политик безопасности.
-- Включаем безопасность на уровне строк для таблицы
ALTER TABLE my_table ENABLE ROW LEVEL SECURITY;

-- Создаем роль, которая будет иметь доступ
CREATE ROLE limited_role;

-- Создаем политику, которая позволяет только чтение данных
CREATE POLICY read_only_policy ON my_table
FOR SELECT
USING (true); -- Условие для выполнения SELECT

-- Применяем политику для роли limited_role
GRANT SELECT ON my_table TO limited_role;


🟠Использование триггеров (Triggers)
Триггеры позволяют автоматически выполнять определенные действия перед или после операции INSERT, UPDATE, DELETE. Можно создать триггер, который будет блокировать изменение конкретных полей.
CREATE OR REPLACE FUNCTION prevent_update()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.field IS DISTINCT FROM OLD.field THEN
RAISE EXCEPTION 'Field "field" cannot be updated';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Применяем триггер к таблице
CREATE TRIGGER prevent_update_trigger
BEFORE UPDATE ON my_table
FOR EACH ROW
EXECUTE FUNCTION prevent_update();


🟠Ограничения на уровне столбца (Column-Level Constraints)
Ограничения на уровне столбца могут использоваться для ограничения возможных значений или для создания выражений, которые должны быть выполнены для выполнения изменения.
ALTER TABLE my_table
ADD CONSTRAINT field_check CHECK (field IS NOT NULL);


Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31🔥1😁1
Axios против Fetch: выбираем инструмент для запросов в 2026 году 📡

Несмотря на то что в Node.js давно завезли нативный fetch, библиотека Axios всё еще остается стандартом в индустрии. Почему разработчики не спешат переходить на «встроенное» решение?

Разница в подходе: 🛠️

Fetch: Это низкоуровневый API. Чтобы получить JSON, тебе нужно сделать два шага: сначала дождаться ответа, а потом вызвать .json().
Axios: Это обертка, которая делает всю грязную работу за тебя. Он автоматически парсит JSON и возвращает готовый объект в response.data.

Почему Axios всё еще круче? 🚀

Интерцепторы (Interceptors): Можно создать функцию, которая будет автоматически добавлять токен авторизации к каждому запросу или логировать время ответа. С fetch тебе придется писать обертку руками. 🔍
Таймауты: В Axios таймаут задается одной строкой в конфиге. В fetch для этого нужно создавать AbortController (как мы учили в прошлых постах). ⏱️
Обработка ошибок: Axios считает ошибкой любой статус, кроме 2xx. fetch же не выдаст ошибку, даже если сервер вернул 404 или 500 — тебе нужно вручную проверять свойство res.ok.



Пример интерцептора в Axios:
const axios = require('axios');

const api = axios.create({ baseURL: 'https://api.example.com' });

api.interceptors.request.use(config => {
config.headers.Authorization = 'Bearer SECRET_TOKEN';
return config;
});

const data = await api.get('/users'); // Токен подставится сам!


Когда использовать Fetch? 🏗️

— Если ты пишешь легкую библиотеку и не хочешь лишних зависимостей.
— Если ты работаешь в Edge-окружениях (например, Vercel Edge Functions), где важен размер бандла.
— Если тебе просто нужно сделать один запрос и ты не хочешь тянуть NPM-пакет.

Методы и фишки: 📝

axios.all([]) — удобный аналог Promise.all для параллельных запросов.
Base URL — возможность задать корень API один раз и дальше писать только пути. 🧩
XSRF Protection — встроенная защита от подделки межсайтовых запросов.

> Итог: fetch — это база, которую нужно знать. Но если ты строишь серьезное приложение с кучей запросов, сложной авторизацией и логированием — Axios сэкономит тебе часы времени и сотни строчек кода.

---

### **Пакет nodemon — забываем про ручной перезапуск сервера 🔄**

Разработка на Node.js без этого пакета — это страдание. Отредактировал файл -> Перешел в консоль -> Ctrl+C -> Вверх -> Enter. И так 500 раз в день. Nodemon делает это за тебя: он следит за файлами в папке и перезапускает процесс мгновенно после сохранения.

Шаг 1 — установка и запуск:
Обычно его ставят как devDependency, чтобы он не улетал на боевой сервер.

npm install --save-dev nodemon


// package.json
"scripts": {
"dev": "nodemon index.js"
}


npm run dev


Зачем это нужно? 🚀

Скорость разработки: Ты видишь результат своих правок через секунду. 🏎️
Гибкость: Можно настроить, какие файлы игнорировать (например, тесты или логи), чтобы сервер не перезагружался зря.
Поддержка любого языка: Через nodemon можно запускать даже Python или Ruby скрипты, если тебе нужен авто-рестарт.



Крутые фишки: 📝

nodemon.json — файл настроек, где можно прописать расширения (.js, .json, .graphql) и папки для слежки. ⚙️
Ручной рестарт: Если что-то зависло, просто введи rs в терминале, и nodemon перезапустит сервер без выхода из программы.
Запуск команд: Можно настроить выполнение линтера или тестов перед каждым перезапуском.

> Важный нюанс: В Node.js 18+ появился встроенный флаг --watch. Можно запускать так: node --watch index.js. Это работает быстрее и не требует установки пакетов. Но nodemon всё еще популярен из-за более гибких настроек и удобного лога в консоли.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1🔥1
👩‍💻 Хватит учить только синтаксис, начинай делать реальные проекты!

Python Ready — авторский канал, где Python перестаёт быть только теорией и становится рабочим инструментом. Мини-проекты, боты, советы, разборы задач, гайды и шпаргалки для каждого программиста.

🔥 Советую подписаться: @python_ready
Please open Telegram to view this post
VIEW IN TELEGRAM
2
Хочешь посмотреть, как Java эволюционировала, фича за фичей?

brunoborges сделал офигенный сайт, где изменения языка Java показаны рядом, в формате side-by-side. Идеально для студентов и для тех, кто модернизирует легаси-приложения.

Зацени:
https://javaevolved.github.io

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
3
Один умный человек, написал эссе про алгоритм BM25, который лежит в основе Elasticsearch, Apache Solr и Apache Lucene.

Зачем? Просто потому что ему было нечем заняться, он нырнул в кроличью нору информационного поиска: пытался понять, почему и где TF-IDF в итоге упирается в свои пределы, как на самом деле устроен BM25 под капотом, и почему системы вроде Elasticsearch, Solr и Lucene сделали его своей дефолтной функцией ранжирования.

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

Этот текст должен дать тебе нормальную ментальную модель, чтобы понимать BM25 и также IDF из популярного TF-IDF. Зацени.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
Fastify — когда Express становится слишком медленным 🏎️

Express — это классика, но он был создан в те времена, когда Node.js только зарождался. Fastify — это современный фреймворк, созданный с фокусом на максимальную производительность и минимальные накладные расходы. Он буквально «летает» за счет оптимизации JSON-схем и встроенной системы плагинов.

Шаг 1 — создаем первый роут:
Синтаксис похож на Express, но сразу предлагает использовать async/await.

npm install fastify


const fastify = require('fastify')({ logger: true });

fastify.get('/ping', async (request, reply) => {
return { status: 'pong' }; // JSON парсится автоматически
});

fastify.listen({ port: 3000 }, (err) => {
if (err) throw err;
console.log('Fastify запущен!');
});


Зачем это нужно? 🚀

Сверхскорость: Fastify считается одним из самых быстрых фреймворков для Node.js. Он тратит меньше ресурсов процессора на каждый запрос.
Валидация «из коробки»: Fastify использует JSON Schema для проверки входных данных. Это не только делает API безопасным, но и ускоряет сериализацию ответов в 2 раза. 🛡️
Экосистема плагинов: Вместо хаотичного мидлвара, как в Express, здесь строгая и понятная иерархия плагинов.



Крутые фишки: 📝

Hooks: Ты можешь вклиниться в любой момент жизненного цикла запроса (onRequest, preHandler и т.д.).
Типизация: Отличная поддержка TypeScript прямо из коробки. 🧩
Декораторы: Позволяют легко добавлять новые методы в объекты request и reply без костылей.
Логирование: Встроенный сверхбыстрый логгер Pino (о котором мы писали раньше).

Пример с валидацией:
const schema = {
params: {
type: 'object',
properties: { id: { type: 'number' } }
}
};

fastify.get('/user/:id', { schema }, async (req, res) => {
return { userId: req.params.id };
});


> Важный нюанс: Если ты начинаешь новый проект в 2026 году — выбирай Fastify. Express всё еще жив, но Fastify предлагает более современную архитектуру и лучшую производительность для микросервисов.

---

### **Пакет cron — планируем задачи по расписанию **

В любом серьезном бэкенде есть задачи, которые должны выполняться сами по себе: рассылка писем по утрам, чистка старых логов или бэкап базы данных в полночь. Пакет cron позволяет настроить выполнение функций по расписанию с помощью стандартного синтаксиса crontab.

Шаг 1 — настраиваем «будильник»:

npm install cron


const { CronJob } = require('cron');

const job = new CronJob(
'0 0 * * *', // Каждый день в полночь
function() {
console.log('Время делать бэкап базы данных! 💾');
},
null, // Коллбэк при остановке
true, // Запустить сразу
'Europe/Moscow' // Часовой пояс
);


Зачем это нужно? 🚀

Автоматизация: Тебе не нужно помнить о рутинных задачах — сервер сделает всё сам.
Гибкость: Можно настроить запуск раз в секунду, раз в месяц или только по рабочим дням в 9 утра. 📅
Надежность: Задачи работают в фоне и не мешают пользователям пользоваться сайтом.



Как читать синтаксис (5 звезд): 📝

* * * * * * (секунды, минуты, часы, день месяца, месяц, день недели).
0 */2 * * * — каждые два часа.
0 9 * * 1-5 — в 9:00 с понедельника по пятницу. 👔
30 18 * * * — каждый день в 18:30.

Крутые фишки: 📝

Поддержка часовых поясов: Твой сервер может стоять в США, но выполнять задачи по времени твоего города.
Управление: Задачи можно динамически создавать, останавливать (job.stop()) и запускать заново в коде. ⚙️
async/await: Внутри задачи можно спокойно использовать асинхронный код для запросов к БД или API.

> Важный нюанс: Если у тебя один сервер — cron идеален. Если же у тебя кластер из 10 серверов, обычный cron запустится на каждом из них одновременно. В таких случаях лучше использовать распределенные очереди задач, например BullMQ или Agenda.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
BullMQ — мощные очереди задач для тех, кто вырос из обычного Cron 🐂

Когда твой проект растет, простых задач «по расписанию» становится мало. Что, если нужно отправить 10 000 писем, но API почтового сервиса тормозит? Или нужно обработать тяжелое видео, не заставляя пользователя ждать ответа? Здесь на сцену выходит BullMQ — стандарт для очередей задач в Node.js, работающий на базе Redis.

Шаг 1 — создаем очередь и воркер:
Одна часть приложения (продюсер) кидает задачу в очередь, а другая (воркер) — выполняет её, когда освободится.

npm install bullmq ioredis


const { Queue, Worker } = require('bullmq');

// 1. Создаем очередь
const videoQueue = new Queue('video-processing');

// 2. Добавляем задачу (например, из контроллера)
await videoQueue.add('compress', { videoId: 42, format: 'mp4' });

// 3. Воркер в отдельном процессе подхватывает задачу
const worker = new Worker('video-processing', async job => {
console.log(`Обработка видео ${job.data.videoId}...`);
// Тут логика сжатия
return 'Done';
});


Зачем это нужно? 🚀

Фоновая обработка: Пользователь нажимает «Загрузить», и мы сразу говорим ему «Ок, скоро всё будет», а само видео обрабатывается в фоне. 🎬
Устойчивость к сбоям: Если воркер упадет или сервер перезагрузится, задача не пропадет. Она останется в Redis и будет выполнена позже.
Rate Limiting: Можно ограничить выполнение задач (например, не больше 5 запросов в секунду к стороннему API), чтобы не получить бан. 🛡️
Повторы (Retries): Если задача упала с ошибкой (например, сеть мигнула), BullMQ может автоматически попробовать еще раз через 5, 10 или 60 минут.



Крутые фишки: 📝

Priorities: Можно сделать так, чтобы задачи от Premium-пользователей всегда шли в начало очереди.
Delayed Jobs: Выполни задачу не сейчас, а ровно через 2 часа.
Parent/Child Jobs: Создавай сложные цепочки — выполни задачу А, и только если она успешна, запускай задачи Б и В.
Панель управления: Есть готовые админки (например, BullBoard), где можно в реальном времени смотреть, сколько задач в очереди, сколько упало и почему. 📊

Почему Redis? 🤔
Redis работает в оперативной памяти, поэтому обмен задачами происходит мгновенно. Это намного быстрее, чем хранить очередь в обычной реляционной базе вроде PostgreSQL.

> Важный нюанс: BullMQ — это профессиональный инструмент. Если тебе просто нужно раз в день чистить логи, обычного node-cron хватит. Но если от выполнения задачи зависят деньги или лояльность юзера — используй очереди.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
🔌 Модуль dns — работаем с доменными именами напрямую

Когда мы делаем HTTP-запрос, Node.js сам разрешает домены, но иногда приложению нужно делать это вручную: проверить существование домена, получить его IP или узнать MX-записи почтового сервера.

dns — резолвинг и проверка сети**

dns.resolve()
dns.lookup()
dns.reverse()
dns.getServers()

dns.resolve() — отправляет реальный запрос к DNS-серверам в сети. Позволяет узнать IP-адреса, привязанные к домену.

const dns = require('dns');

dns.resolve('google.com', (err, addresses) => {
console.log('IP адреса:', addresses);
});
// Результат: IP адреса: ['142.250.185.142', ...]




dns.lookup() — использует настройки операционной системы (например, файл hosts). Это быстрее, но не всегда дает актуальные данные из интернета.

dns.lookup('localhost', (err, address) => {
console.log('Адрес:', address);
});
// Результат: Адрес: 127.0.0.1


dns.reverse() — выполняет обратное преобразование: вы передаете IP-адрес, а модуль пытается найти имя хоста, которое ему соответствует.
dns.resolveMx() — возвращает записи почтового обмена. Идеально для проверки, существует ли почтовый сервер у домена перед отправкой письма.

dns.resolveMx('github.com', (err, addresses) => {
console.log(addresses);
});


dns.getServers() — показывает список IP-адресов DNS-серверов, которые в данный момент использует твоя система для резолвинга.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
🧩 Модуль url — безопасный парсинг и сборка ссылок**

Работа со строками через split или регулярные выражения — прямой путь к ошибкам и уязвимостям. В Node.js есть встроенный класс URL, который соответствует международным стандартам и автоматически обрабатывает спецсимволы.

url — разбор и валидация адресов

new URL()
url.searchParams
url.pathname
url.origin
url.format()

new URL() — создает объект, который разбивает строку на части: протокол, хост, порт, путь и параметры.

const myUrl = new URL('https://api.test.ru:8080/v1/user?id=10#hash');

console.log(myUrl.host); // api.test.ru:8080
console.log(myUrl.protocol); // https:
console.log(myUrl.hash); // #hash




searchParams — мощный инструмент для работы с GET-запросами. Позволяет легко добавлять, удалять или изменять параметры без ручного склеивания строк.

const link = new URL('https://shop.ru/search');
link.searchParams.append('sort', 'desc');
link.searchParams.set('page', '1');

console.log(link.href);
// https://shop.ru/search?sort=desc&page=1


pathname — возвращает только путь к ресурсу. Полезно для роутинга, чтобы отсечь домен и параметры поиска.
origin — возвращает комбинацию протокола и хоста. Идеально для настройки CORS или проверки источника запроса.

const site = new URL('https://blog.js.org/posts/123');
console.log(site.origin); // https://blog.js.org


Безопасность — если передать в конструктор URL некорректную строку, он выдаст ошибку. Это отличный способ проверить, является ли строка валидной ссылкой, прежде чем сохранять её в базу.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
2
🔐 Права доступа в Linux — разбираемся с chmod и chown!

В Linux всё есть файл, и безопасность системы строится на том, кто может эти файлы читать, изменять или запускать. Если вы хоть раз видели ошибку Permission denied, значит, пришло время разобраться, как работают права доступа и как ими управлять.

В этом посте:
— Разбираем магические цифры 777, 644 и 755.
— Учимся менять владельца файлов через chown.
— Настраиваем права на чтение, запись и запуск.
— Узнаем, как рекурсивно исправить доступ во всей папке.

---

Каждый файл в Linux имеет три группы прав: для Владельца (User), для Группы (Group) и для Всех остальных (Others). Для каждой группы можно разрешить или запретить три действия: r (read — чтение), w (write — запись) и x (execute — запуск).

Как читать цифровой код:
4 — чтение (read)
2 — запись (write)
1 — запуск (execute)
0 — нет прав

Складывая эти цифры, мы получаем нужный уровень доступа. Например, 4+2+1 = 7 (полные права), а 4+2 = 6 (чтение и запись).

Популярные комбинации:
chmod 777 — «гуляй, кто хочешь». Все могут делать всё. Худший вариант для безопасности.
chmod 644 — стандарт для файлов. Владелец пишет и читает, остальные только читают.
chmod 755 — стандарт для папок и скриптов. Все могут зайти в папку или запустить файл, но менять его может только владелец.

Иногда проблема не в правах, а в том, что файл принадлежит не тому пользователю (например, root вместо вашего юзера). Чтобы сменить «хозяина», используется команда chown. Если нужно сменить и владельца, и группу сразу, пишем через двоеточие: sudo chown user:group filename.



Часто права нужно поправить не в одном файле, а во всей папке с вложенными проектами. Для этого используйте флаг -R (recursive). Но будьте осторожны: sudo chmod -R 777 / превратит вашу систему в решето за одну секунду.

Использование правильных прав — это не просто «чтобы работало», а защита вашего сервера от взлома. Скрипты должны иметь флаг +x только если вы собираетесь их запускать, а конфиги с паролями (вроде .env) должны быть закрыты от всех, кроме владельца.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🛰️ Модуль querystring — работаем с параметрами запросов**

Хотя класс URL умеет парсить параметры, модуль querystring остается незаменимым, когда нужно быстро превратить объект в строку для тела запроса или разобрать сырые данные, которые приходят в POST-запросе от старых HTML-форм.

querystring — парсинг и сборка запросов

parse()
stringify()
escape()
unescape()

parse() — превращает строку параметров (то, что идет после знака ?) в обычный объект JavaScript.

const qs = require('querystring');

const query = 'user=admin&role=editor&active=true';
const parsed = qs.parse(query);

console.log(parsed.user); // admin




stringify() — делает обратную операцию: берет объект и собирает из него корректную строку параметров, которую можно подставить в URL.

const params = { search: 'node js', page: 5 };
const string = qs.stringify(params);

console.log(string); // search=node%20js&page=5


escape() / unescape() — низкоуровневые методы для работы со спецсимволами. Они заменяют пробелы, кавычки и кириллицу на безопасные коды (например, %20), чтобы сервер мог их прочитать.

Отличие от URLSearchParamsquerystring работает быстрее и поддерживает кастомные разделители. Если вместо & и = тебе нужно использовать ; и :, этот модуль справится в одну строку.

const custom = qs.parse('name:tom;age:20', ';', ':');
console.log(custom.name); // tom

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
1