Backend
3.95K subscribers
35 photos
707 links
Комьюнити Backend программистов.
Python, Java, Golang, PHP, C#, C/C++, DevOps

Сайт easyoffer.ru
Реклама @easyoffer_adv
ВП @easyoffer_vp
Download Telegram
Пример использования gRPC:

Рассмотрим простой пример использования gRPC для создания клиент-серверного приложения на Python.

1. Определение сервиса и сообщений в файле example.proto с использованием синтаксиса Protocol Buffers:

syntax = "proto3";

message HelloRequest {
string name = 1;
}

message HelloResponse {
string message = 1;
}

service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse);
}


2. Генерация кода на основе файла example.proto с помощью компилятора Protocol Buffers:

protoc -I=. --python_out=. --grpc_python_out=. example.proto


3. Создание сервера на Python с использованием gRPC:

import grpc
import example_pb2
import example_pb2_grpc

class GreeterServicer(example_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return example_pb2.HelloResponse(message=f"Hello, {request.name}!")

def serve():
server = grpc.server(grpc.insecure_server())
example_pb2_grpc.add_GreeterServicer_to_server(GreeterServicer(), server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()

if name == 'main':
serve()


4. Создание клиента на Python с использованием gRPC:

import grpc
import example_pb2
import example_pb2_grpc

def run():
channel = grpc.insecure_channel('localhost:50051')
stub = example_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(example_pb2.HelloRequest(name='world'))
print
Использование JWT и OAuth для аутентификации и авторизации в веб-приложениях

JWT (JSON Web Token) и OAuth - это два распространенных стандарта для реализации аутентификации и авторизации в веб-приложениях.


JWT - это компактный и самодостаточный способ представления информации об аутентификации в форме JSON, которая может быть передана между двумя сторонами как часть HTTP запроса или в теле. Он состоит из трех частей: заголовка (header), полезной нагрузки (payload) и подписи (signature). Заголовок содержит информацию о типе токена и используемом алгоритме шифрования. Полезная нагрузка содержит информацию об аутентифицированном пользователе или другие данные. Подпись обеспечивает проверку целостности данных.

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

Пример использования JWT и OAuth в веб-приложении:


Пользователь входит в систему, предоставляя учетные данные (например, имя пользователя и пароль).

Сервер аутентификации проверяет учетные данные пользователя и создает JWT токен с информацией об аутентифицированном пользователе (например, идентификатор пользователя, роль и срок действия токена).

Сервер возвращает JWT токен клиентскому приложению.

При последующих запросах клиентское приложение включает JWT токен в заголовок Authorization.

Сервер проверяет подлинность токена и авторизует запрос на основе информации в токене.

Следующим постом рассмотрим пример кода на Python с использованием библиотеки Flask для реализации аутентификации с помощью JWT ⬇️
👍5
Пример кода на Python с использованием библиотеки Flask для реализации аутентификации с помощью JWT:

from flask import Flask, jsonify, request
import jwt
from functools import wraps

app = Flask(name)
app.config['SECRET_KEY'] = 'secret'

def token_required(f):
@wraps(f)
def decorated(*args, **kwargs):
token = request.headers.get('Authorization')
if not token:
return jsonify({'message': 'Token is missing!'}), 401
try:
data = jwt.decode(token, app.config['SECRET_KEY'])
except:
return jsonify({'message': 'Token is invalid!'}), 401
return f(*args, **kwargs)
return decorated

@app.route('/login', methods=['POST'])
def login():
auth = request.authorization
if auth and auth.password == 'password':
token = jwt.encode({'username': auth.username}, app.config['SECRET_KEY'])
return jsonify({'token': token.decode('UTF-8')})
return jsonify({'message': 'Could not verify!'}), 401

@app.route('/protected', methods=['GET'])
@token_required
def protected():
return jsonify({'message': 'This is protected route!'})

if name == 'main':
app.run(debug=True)


В этом примере, при запросе на /login пользователь предоставляет учетные данные и, если они верны, сервер создает JWT токен, который включает в себя имя пользователя. После этого, для доступа к защищенному маршруту /protected, клиент должен предоставить этот токен в заголовке Authorization. Функция token_required обеспечивает аутентификацию пользователя на основе JWT токена.
👍8
⚙️ Обработка NULL с DISTINCT

with new_table as (
select patient_id from patients
UNION
select null
)

select
count()
, count(distinct patient_id)
, count(patient_id)

from new_table


Результатом запроса будет значение 4531 для столбца COUNT() и 4530 для двух оставшихся столбцов. Когда вы указываете столбец, ключевое слово COUNT исключает нулевые значения.Однако, при использовании звездочки в подсчет включаются значения NULL.

Это может сбивать с толку при проверке, является ли столбец первичным ключом, поэтому я посчитал нужным упомянуть об этом.
1
Что такое ACID максимально содержательно и с примерами

ACID (Atomicity, Consistency, Isolation, Durability) - это набор основных принципов транзакционной обработки в базах данных, обеспечивающих надежность и целостность данных.

Вот более подробное объяснение каждого из принципов:

Atomicity (Атомарность):

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

Пример: Представьте, что пользователь хочет выполнить банковский перевод со счета A на счет B. Если перевод прошел успешно, то деньги будут вычтены со счета A и добавлены на счет B. Если произошла ошибка в середине процесса (например, проблемы с сетью), ни один из счетов не будет изменен.

Consistency (Согласованность):

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

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

Isolation (Изоляция):

Этот принцип гарантирует, что выполнение одной транзакции не зависит от выполнения других транзакций, которые происходят параллельно. Изоляция предотвращает влияние одной транзакции на другие транзакции.

Пример: Если две транзакции пытаются изменить одни и те же данные одновременно, изоляция гарантирует, что результат выполнения одной транзакции не повлияет на результат выполнения другой транзакции.

Durability (Долговечность):

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

Пример: После того, как транзакция перевода средств выполнена успешно и пользователь получил подтверждение, долговечность гарантирует, что эти изменения останутся в базе данных и не будут потеряны даже в случае сбоя системы.
👍12
Clean Architecture

Clean Architecture - это методология проектирования программного обеспечения, предложенная Робертом Мартином (также известным как Uncle Bob), которая призвана создать гибкую, легко поддерживаемую и расширяемую архитектуру приложения.

Основной принцип Clean Architecture заключается в разделении программы на независимые компоненты, каждый из которых отвечает за конкретный аспект бизнес-логики и имеет четкие границы и интерфейсы с внешним миром.

Основные компоненты Clean Architecture включают в себя:


Entities (Сущности): Это основные объекты, которые представляют бизнес-логику приложения. Сущности содержат логику и данные, специфичные для предметной области.

Use Cases (Случаи использования):
Это компоненты, которые описывают то, что система должна делать. Они содержат логику, которая координирует взаимодействие между сущностями и другими компонентами.

Interfaces (Интерфейсы):
Это абстракции, которые определяют способ взаимодействия между компонентами системы. Интерфейсы разделяют код на уровни и определяют контракты между компонентами.

Frameworks and Drivers (Фреймворки и драйверы):
Это внешние компоненты, такие как фреймворки, библиотеки и инструменты, которые используются для реализации конкретных функций или подключения системы к внешним ресурсам.

Пример применения Clean Architecture:


Представьте, что у вас есть веб-приложение для управления задачами. Вы можете реализовать Clean Architecture, разделив приложение на следующие компоненты:

Entities: Сущности могут включать в себя объекты, такие как Task (Задача) с полями, такими как название, описание, статус и т. д.

Use Cases: Случаи использования могут включать в себя логику для создания, чтения, обновления и удаления задач, а также выполнение других операций, связанных с управлением задачами.

Interfaces:
Интерфейсы могут определять, как компоненты приложения будут взаимодействовать между собой, например, через REST API для взаимодействия с веб-интерфейсом пользователя или через сервисы для доступа к базе данных.

Frameworks and Drivers:
Фреймворки и драйверы могут включать в себя фреймворки для разработки веб-приложений, библиотеки для работы с базами данных и инструменты для автоматизации тестирования.

Clean Architecture способствует созданию гибких, модульных и легко поддерживаемых приложений, которые легко масштабировать и изменять.
👍4🔥2🤔1
Как и просили, делаю пример применения Clean Architecture в коде

Рассмотрим пример применения Clean Architecture на простом веб-приложении для управления задачами. Мы разделим приложение на несколько слоев: представление (View), бизнес-логику (Use Cases) и данные (Repositories). Для простоты мы будем использовать Python и фреймворк Flask для реализации веб-интерфейса.

# entities.py
class Task:
def init(self, title, description, status):
self.title = title
self.description = description
self.status = status

# repositories.py
class TaskRepository:
def get_task_by_id(self, task_id):
# код для получения задачи из базы данных
pass

def save_task(self, task):
# код для сохранения задачи в базу данных
pass

# use_cases.py
class TaskManager:
def init(self, task_repository):
self.task_repository = task_repository

def create_task(self, title, description):
task = Task(title=title, description=description, status='todo')
self.task_repository.save_task(task)

def get_task(self, task_id):
return self.task_repository.get_task_by_id(task_id)

# app.py (Flask приложение)
from flask import Flask, request, jsonify
from entities import Task
from repositories import TaskRepository
from use_cases import TaskManager

app = Flask(name)
task_repository = TaskRepository()
task_manager = TaskManager(task_repository)

@app.route('/tasks', methods=['POST'])
def create_task():
data = request.json
title = data.get('title')
description = data.get('description')
task_manager.create_task(title, description)
return jsonify({'message': 'Task created successfully'})

@app.route('/tasks/<task_id>', methods=['GET'])
def get_task(task_id):
task = task_manager.get_task(task_id)
return jsonify({'title': task.title, 'description': task.description, 'status': task.status})

if name == 'main':
app.run(debug=True)


В этом примере:

entities.py содержит базовую сущность задачи.
repositories.py содержит репозиторий для доступа к данным задачи.
• use_cases.py содержит бизнес-логику приложения (создание и получение задачи).
app.py - это веб-приложение Flask, которое обрабатывает HTTP-запросы и использует компоненты бизнес-логики для создания и получения задач.

Этот пример демонстрирует, как Clean Architecture разделяет приложение на независимые слои, что делает его более гибким, легко поддерживаемым и тестируемым. Каждый компонент отвечает только за свою часть функциональности, что делает его более независимым и переносимым.
3👍2🔥2
​​10 причин, по которым стоит выбрать Django вместо FastAPI

FastAPI предлагает производительное, асинхронное, компактное и современное решение для разработки бэкенда и API на Python по сравнению с более зрелым, но несколько более громоздким Django. И все же многие опытные бэкендеры предпочитают Django.

Проверенная надежность вместо модных фишек

Стабильность – превыше всего, а Django – образец стабильности, с минимальным количеством серьезных изменений и регрессий на протяжении многих лет. Каждое обновление тщательно тестируется, а сам фреймворк имеет минимум внешних зависимостей, что помогает избежать значительных проблем.

Обилие справочных ресурсов

За 18 лет существования Django в интернете накопилось огромное количество ресурсов, многие из которых до сих пор актуальны. Ответы на Stack Overflow остаются действительными годами, а ChatGPT предоставляет корректные ответы, основанные на огромном объеме полезного и релевантного контента.

Гибкость

Django одинаково хорошо подходит и для бэкенда, и для фулстек-разработки.

Более удобная ORM

При работе с FastAPI можно использовать несколько ORM, но выбор менее распространенного инструмента несет свои проблемы, включая меньшее количество документации и поддержки.

Ограниченная полезность асинхронных возможностей

Одним из преимуществ FastAPI считается встроенная поддержка ASGI-сервер, но на практике такая функциональность требуется не так уж часто. Для действительно асинхронных задач достаточно инструментов вроде Celery, а для вебсокетов можно использовать решения типа Soketi или Pusher.

Вводящие в заблуждение утверждения о «меньшем количестве шаблонного кода»

Легкость запуска проекта уровня hello world не равнозначна простоте управления и масштабирования со временем.

Ценность конвенций

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

Производительность – не самое главное

Хотя Django – не самый производительный фреймворк, особенно в сравнении с FastAPI, на самом деле навыки разработчика влияют на проблемы с производительностью гораздо больше, чем внутренние возможности используемой технологии. Кроме того, не каждый проект требует экстремальной производительности, а для тех, что требуют, Python – не лучший выбор.

Потенциальные проблемы с поддержкой проекта

В отличие от FastAPI, разработкой и поддержкой Django занимается большая команда.

Иногда лучше выбрать TypeScript-фреймворк

Для проектов с относительно простым бэкендом оптимальным выбором может быть не Django и не FastAPI, а фреймворк типа AdonisJS, в сочетании с ORM вроде Prisma: это упрощает управление проектом за счет единого языка для фронтенда и бэкенда.
👍3😁3🤔2
​​Протоколы TLS/SSL максимально содержательно и с примерами

Протоколы TLS (Transport Layer Security) и SSL (Secure Sockets Layer) - это криптографические протоколы, которые обеспечивают защищенную передачу данных в сети Интернет. Они используются для обеспечения конфиденциальности, целостности и подлинности данных, передаваемых между клиентом и сервером.

Протокол SSL был разработан компанией Netscape и стал широко использоваться для защищенной передачи данных в Интернете. Однако из-за уязвимостей и проблем безопасности SSL, протокол был заменен более современным и безопасным протоколом TLS.

Протоколы TLS и SSL работают на разных уровнях сетевой модели OSI


SSL/TLS Handshake Protocol: Этот протокол используется для установления защищенного соединения между клиентом и сервером. В процессе рукопожатия происходит обмен криптографическими ключами, установка параметров шифрования и аутентификация сторон.

SSL/TLS Record Protocol: Этот протокол используется для защищенной передачи данных между клиентом и сервером. Он обеспечивает конфиденциальность, целостность и аутентификацию сообщений путем шифрования и аутентификации данных.

Когда вы заходите на защищенный сайт (например, сайт банка или интернет-магазина), ваш браузер и сервер взаимодействуют по следующему сценарию:

1. Браузер отправляет запрос на сервер.
2. Сервер отвечает с помощью сертификата SSL/TLS, который содержит открытый ключ сервера.
3. Браузер проверяет сертификат, чтобы убедиться, что он действителен и принадлежит запрашиваемому серверу.
4. Если сертификат действителен, браузер и сервер выполняют SSL/TLS Handshake Protocol для установления защищенного соединения.
5. После успешного рукопожатия данные между браузером и сервером передаются с использованием SSL/TLS Record Protocol, обеспечивая конфиденциальность и целостность данных.

Протоколы TLS и SSL играют ключевую роль в обеспечении безопасности передачи данных в Интернете и используются в различных сферах, включая веб-браузеры, электронную почту, мессенджеры и другие приложения.
👍5
​​Задача: Сделать кастомную waitGroup на семафоре

Семафор можно легко получить из канала. Чтоб не аллоцировать лишние данные, будем складывать туда пустые структуры.


В нашем случае мы хотим сделать семафор, который будет ждать выполнения пяти горутин. Для этого просто добавим вместо обычного канала буфферизированный. И внутри каждой горутины положим в него значение. А в конце будем дожидаться, что все ок — мы вычитаем все значения из канала.

Решение ⬇️

package main

import (
"fmt"
)

type sema chan struct{}

func New(n int) sema {
return make(sema, n)
}

func (s sema) Inc(k int) {
for i := 0; i < k; i++ {
s <- struct{}{}
}
}

func (s sema) Dec(k int) {
for i := 0; i < k; i++ {
<-s
}
}

func main() {
numbers := []int{1, 2, 3, 4, 5}
n := len(numbers)

sem := New(n)

for _, num := range numbers {
go func(n int) {
fmt.Println(n)
sem.Inc(1)
}(num)
}

sem.Dec(n)

}
​​Архитектурный паттерн CQRS максимально содержательно и с примерами

CQRS (Command Query Responsibility Segregation) - это архитектурный паттерн, который предлагает разделять операции записи (команды) и операции чтения (запросы) в приложении. Этот подход позволяет разработчикам создавать более гибкие и масштабируемые системы, а также улучшить производительность и обеспечить согласованность данных.

Основные принципы CQRS:


1. Разделение операций записи и операций чтения: Команды (операции записи) и запросы (операции чтения) обрабатываются отдельно. Это позволяет оптимизировать обработку каждого типа операций и использовать различные модели данных для команд и запросов.

2. Моделирование данных: Для команд и запросов могут использоваться различные модели данных, оптимизированные для конкретных потребностей. Например, для операций записи может использоваться нормализованная модель данных, а для операций чтения - денормализованная модель данных или материализованные представления.

3. Асинхронная обработка: Обработка команд может быть асинхронной и происходить в фоновом режиме, что позволяет улучшить производительность и масштабируемость системы.

Следующим постом рассмотрим пример использования CQRS ⬇️
👍5
Пример использования CQRS:

// Пример реализации CQRS в TypeScript

// Команда для создания нового пользователя
class CreateUserCommand {
constructor(public username: string, public email: string) {}
}

// Обработчик команды создания пользователя
class CreateUserCommandHandler {
handle(command: CreateUserCommand) {
// Логика создания нового пользователя
console.log(Creating user: ${command.username});
}
}

// Запрос для получения информации о пользователе
class GetUserQuery {
constructor(public userId: string) {}
}

// Обработчик запроса информации о пользователе
class GetUserQueryHandler {
handle(query: GetUserQuery) {
// Логика получения информации о пользователе
console.log(Getting user info for user with ID: ${query.userId});
return { userId: query.userId, username: 'John Doe', email: '[email protected]' };
}
}

// Использование команд и запросов
const createUserCommand = new CreateUserCommand('johndoe', '[email protected]');
const createUserHandler = new CreateUserCommandHandler();
createUserHandler.handle(createUserCommand);

const getUserQuery = new GetUserQuery('123');
const getUserHandler = new GetUserQueryHandler();
const userInfo = getUserHandler.handle(getUserQuery);
console.log(userInfo);


В этом примере команды (CreateUserCommand) и запросы (GetUserQuery) обрабатываются отдельно с помощью соответствующих обработчиков (CreateUserCommandHandler и GetUserQueryHandler). Это позволяет эффективно управлять операциями записи и операциями чтения в приложении, а также использовать различные модели данных и подходы к их обработке.
👍31🔥1
Принципы работы и применение очередей сообщений: RabbitMQ, ActiveMQ, Kafka и их сравнение

RabbitMQ:


RabbitMQ - это брокер сообщений, реализующий протокол AMQP (Advanced Message Queuing Protocol). Он предоставляет гибкую и надежную систему для отправки, получения и обработки сообщений между различными компонентами приложения.

Применение: RabbitMQ часто используется для обеспечения асинхронной коммуникации между различными компонентами распределенных систем, таких как микросервисы. Он также может быть использован для реализации очередей задач, обработки событий и многое другое.

ActiveMQ:


ActiveMQ - это еще один брокер сообщений, реализующий протоколы OpenWire и AMQP, а также поддерживающий ряд других протоколов. Он обеспечивает расширяемую и надежную платформу для обмена сообщениями.

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

Kafka:


Apache Kafka - это распределенная система для потоковой обработки и хранения сообщений. Он предоставляет высокопроизводительную платформу для обработки потоков данных в реальном времени.

Применение: Kafka часто используется для обработки данных в реальном времени, стриминговой аналитики, журналирования и анализа логов, обмена данными между микросервисами и т. д.

Сравнение


Протоколы: RabbitMQ и ActiveMQ поддерживают протоколы AMQP, OpenWire и другие. Kafka использует собственный протокол.

Управление сообщениями: RabbitMQ и ActiveMQ обеспечивают надежную доставку сообщений с использованием очередей. Kafka хранит сообщения в журнале, позволяя им быть доступными для обработки потоковыми приложениями.

Производительность: Kafka обеспечивает высокую производительность и масштабируемость благодаря своей архитектуре. RabbitMQ и ActiveMQ также могут быть масштабированы, но обычно имеют меньшую производительность по сравнению с Kafka.

Применение: RabbitMQ и ActiveMQ часто используются для обеспечения асинхронной коммуникации в приложениях и микросервисах. Kafka широко применяется для обработки данных в реальном времени, стриминговой аналитики и журналирования.
👍42
​​Использование архитектурного стиля Serverless в разработке приложений

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

Основные компоненты Serverless-архитектуры:


Функции как сервис (Functions as a Service, FaaS): Основная концепция Serverless заключается в том, что код выполняется в виде отдельных функций, которые могут быть вызваны по требованию. Например, AWS Lambda и Azure Functions предоставляют инфраструктуру для запуска и масштабирования функций в облаке.

Событийное управление: Функции в Serverless-архитектуре запускаются в ответ на определенные события, такие как HTTP-запросы, загрузка файлов в хранилище, изменение данных в базе данных и т. д. Это позволяет создавать реактивные приложения, которые реагируют на изменения в окружении.

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

Следующим постом разберем примеры использования gRPC 👇
2👍1
Пример использования архитектурного стиля Serverless на платформе AWS Lambda

// Пример функции AWS Lambda для обработки HTTP-запросов
exports.handler = async (event) => {
console.log('Received event:', JSON.stringify(event, null, 2));
const responseBody = {
message: 'Hello from AWS Lambda!',
input: event,
};
const response = {
statusCode: 200,
body: JSON.stringify(responseBody),
};
return response;
};


Этот пример демонстрирует функцию AWS Lambda, которая обрабатывает HTTP-запросы. Функция принимает входные данные в формате события, выполняет необходимую логику и возвращает ответ в виде HTTP-ответа.

Преимущества Serverless-архитектуры


Масштабируемость: Платформы Serverless автоматически масштабируют ресурсы в зависимости от нагрузки, обеспечивая высокую производительность приложений.

Экономичность: Плата за использование функций взимается только за фактически использованные ресурсы, что позволяет снизить затраты на инфраструктуру.

Гибкость: Разработчики могут сосредоточиться на написании кода, не тратя время на управление серверами и инфраструктурой.

Недостатки Serverless-архитектуры


Ограничения платформы: Платформы Serverless могут иметь ограничения по количеству ресурсов, времени выполнения функций и другим параметрам, что может ограничивать их применение для некоторых типов приложений.

Сложность отладки: Отладка и тестирование функций в Serverless-архитектуре может быть сложнее из-за их распределенной и асинхронной природы.

В целом, использование архитектурного стиля Serverless в разработке приложений предоставляет ряд преимуществ, таких как гибкость, масштабируемость и экономичность, что делает его привлекательным выбором для создания современных облачных приложений.
1
Стартуем с REST: Создание вашего первого RESTful API

Приветствую всех, кто стремится освоить искусство создания RESTful API! Сегодня мы начинаем нашу серию мастер-классов по REST API, и первый шаг — это создание простого API с нуля. Чтобы понять основы, мы сначала обсудим, что такое REST API и приведем пример "Hello, World!" на Node.js с использованием Express framework.

Что такое REST API?

REST (Representational State Transfer) — это архитектурный стиль взаимодействия компонентов распределенного приложения в сети. RESTful API позволяет разным приложениям или устройствам общаться между собой через HTTP.

Создание "Hello, World!" API

Для создания API нам понадобится:
- Node.js установленный на вашем компьютере
- Text editor для написания кода (например, Visual Studio Code)


Шаг 1: Инициализация проекта Node.js

Создайте папку для вашего проекта и инициализируйте Node.js проект.
mkdir myfirstapi
cd myfirstapi
npm init -y


Шаг 2: Установка Express

Express — это быстрый, гибкий и минималистичный веб-фреймворк для Node.js.
npm install express --save


Шаг 3: Написание "Hello, World!" сервера

Создайте файл index.js и добавьте следующий код:
const express = require('express');
const app = express();

app.get('/', (req, res) => {
res.send('Hello, World!');
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(Server is running on port ${PORT});
});

В этом коде мы импортировали express, создали экземпляр приложения и определили обработчик для корневого маршрута (GET запрос на '/'). Когда обращение идет к этому маршруту, сервер отправляет ответ 'Hello, World!'.


Шаг 4: Запуск сервера

Теперь запустим сервер:
node index.js

Откройте браузер и перейдите по адресу https://localhost:3000/. Вы должны увидеть сообщение 'Hello, World!'.


Вывод

Поздравляю! Вы только что создали свой первый RESTful API с самым базовым маршрутом. В следующих постах мы расширим наши знания, исследуя методы HTTP, статус-коды и другие фундаментальные аспекты REST API. Следите за обновлениями!
👍4🤯1
Основы HTTP: Понимание методов и их использование в REST API

Протокол HTTP (HyperText Transfer Protocol) является основной основой передачи данных в интернете. Основные методы HTTP определяют действия, которые клиент хочет предпринять, обращаясь к определенному ресурсу на сервере. Эти методы часто используются в архитектуре REST API (Representational State Transfer Application Programming Interface), где они позволяют взаимодействовать с ресурсами на сервере, такими как записи в базе данных или файлы.

Основные методы HTTP в REST API:

1. GET: Запрос на чтение данных. GET используется для запроса содержимого определенного ресурса. Запросы GET должны быть идемпотентны, то есть несколько идентичных запросов GET должны приводить к одному и тому же результату и не вызывать изменений на сервере (они не имеют "побочных эффектов").

Пример: GET /users может вернуть список пользователей.

2. POST: Используется для создания нового ресурса. POST-запросы не идемпотентны, что означает, что многократное выполнение одних и тех же POST-запросов обычно приведет к созданию нескольких новых ресурсов.

Пример: POST /users с данными о новом пользователе в теле запроса будет создавать новую учетную запись пользователя.

3. PUT: Применяется для обновления существующего ресурса или создания ресурса, если он ещё не существует. PUT должен быть идемпотентен, так как он заменяет текущее представление ресурса данными, предоставляемыми в запросе.

Пример: PUT /users/1 с обновленной информацией о пользователе в теле запроса будет обновлять данные пользователя с ID 1.

4. DELETE: Удаляет указанный ресурс. Запросы DELETE также должны быть идемпотентны, поскольку повторное удаление того же ресурса будет иметь тот же эффект, что и первое (ресурс останется удаленным).

Пример: DELETE /users/1 удалит учетную запись пользователя с ID 1.

5. PATCH: Используется для частичного обновления существующего ресурса. Подобно PUT, метод PATCH обновляет ресурс, но только указанные поля, в отличие от PUT, который заменяет весь ресурс.

Пример: PATCH /users/1 с частичным обновлением, например только изменением имени пользователя, не трогая другие поля.

Понимание и правильное использование этих методов критически важно при проектировании RESTful API, потому что они позволяют клиенту выполнять стандартизированные действия с ресурсами в сети, таким образом обеспечивается ясность и предсказуемость взаимодействия между клиентом и сервером. Это также позволяет разработчикам API легче следовать принципам REST, включая statelessness (отсутствие состояния) и унифицированный интерфейс.
👍6
REST API от А до Я: Изучаем статус-коды и их значимость

EST API – это один из подходов к организации взаимодействия разных программ через интернет. API (Application Programming Interface) – это набор правил, по которым одна программа может обращаться к функциям другой. Когда этот набор правил следует принципам REST (Representational State Transfer), то и API называется RESTful.

Важной частью REST API являются статус-коды HTTP-ответов, которые сервер отправляет в ответ на запросы клиента. Вот некоторые из них:


Статус-коды 2xx (успешное выполнение запроса):
- 200 OK – стандартный ответ на успешный запрос. Например, вы запрашиваете список контактов через API, и сервер отправляет этот список в ответ.
- 201 Created – говорит о том, что в результате выполнения запроса на сервере был создан новый ресурс. Пример: после отправки данных нового пользователя сервер создал эту запись и подтвердил её создание.

Статус-коды 3xx (перенаправление):
- 301 Moved Permanently – ресурс окончательно перемещён на другой URL. Это как если бы вы переехали и оставили знакомым сообщение где искать вас теперь.
- 302 Found – ресурс временно перемещён, и для доступа к нему следует использовать предоставленный URL.

Статус-коды 4xx (ошибка со стороны клиента):
- 400 Bad Request – сервер не понимает запрос из-за неверного синтаксиса. То есть ваше API-вызов был сформулирован неправильно.
- 401 Unauthorized – для доступа к запрашиваемому ресурсу нужна аутентификация.
- 403 Forbidden – у клиента нет прав на доступ к содержимому, даже если он предоставит аутентификацию.
- 404 Not Found – запрашиваемый ресурс не найден. Это как если бы вы попытались посмотреть страницу по ссылке, которой не существует.

Статус-коды 5xx (ошибка на стороне сервера):
- 500 Internal Server Error – общая ошибка сервера, когда сервер столкнулся с ситуацией, которую он не умеет обработать.
- 503 Service Unavailable – сервер недоступен, например, из-за технического обслуживания или перегрузки.

Статус-коды помогают разработчикам понимать, что произошло при выполнении запроса: всё ли прошло хорошо, нужно ли что-то исправить в запросе или проблема на стороне сервера. Эти коды – универсальный язык общения клиент-серверных интерфейсов, который позволяет быстро диагностировать и исправлять проблемы.
👍7
👾 Ребят, напоминаю, у нас есть приватные группы где мы делимся реальными собеседованиями и тестовыми заданиями. Чтобы попасть в эти в группы воспользуйтесь ботами:
🤖 Доступ к базе собесов
🤖 Доступ к базе тестовых заданий
👍1
Что такое Роутинг в REST и как эффективно организовать пути в API

Роутинг в контексте REST API относится к процессу направления клиентских запросов к соответствующим серверным обработчикам. REST (Representational State Transfer) - это архитектурный стиль для разработки сетевых приложений. REST использует стандартные HTTP-методы и определяет набор принципов для создания веб-сервисов, которые являются удобными, легко масштабируемыми и поддерживаемыми.

Обычно, роутинг в REST API осуществляется через URL-адреса, куда включены определенные паттерны, которые соотносятся с ресурсами и действиями над ними. Здесь важна четкая и последовательная организация путей (endpoints), чтобы их было легко понять и использовать.

Основные принципы роутинга в REST API:

1. Используйте существительные для обозначения ресурсов. Например, если у вас есть сервис, который управляет пользователями, то ресурс будет называться /users.

2. Используйте HTTP-методы для описания действий над ресурсами.
- GET для получения данных.
- POST для создания нового ресурса.
- PUT или PATCH для обновления существующего ресурса.
- DELETE для удаления ресурса.

3. Структурируйте URL-пути согласно иерархии ресурсов. Если есть ресурс вложен в другой ресурс, структурируйте пути соответствующим образом. Например, /users/123/posts представляет все посты пользователя с ID 123.

4. Понятно оформляйте пути для действий, не покрываемых стандартными методами. Для действий типа поиска или фильтрации используйте query-параметры. Например, /users?age=21 для фильтрации пользователей по возрасту.

5. Избегайте глубокой вложенности. Слишком сложная иерархия может усложнить понимание и использование API. По возможности, ограничивайтесь одним или двумя уровнями вложенности.

6. Используйте множественное число для названий ресурсов. Это предпочтительный подход, так как такие пути лучше отражают суть ресурсов как коллекций.

Примеры организации путей в REST API:

1. Получение списка всех пользователей:
GET /users

2. Создание нового пользователя:
POST /users

3. Получение пользователя по идентификатору (ID):
GET /users/123

4. Обновление данных конкретного пользователя:
PUT /users/123

5. Удаление пользователя:
DELETE /users/123

6. Получение постов конкретного пользователя:
GET /users/123/posts

7. Добавление нового поста пользователем:
POST /users/123/posts

8. Поиск пользователей старше 21 года:
GET /users?age_gt=21

Всегда полезно составлять понятную и однозначную документацию на ваш API, чтобы разработчики могли легко понять, как работать с вашими эндпоинтами.
👍13