С тех пор как я начал свой путь в программировании, я заметил интересную закономерность: большинство приложений шаблонны. Да это чистый факт! Просто остановитесь прямо здесь, в начале этой статьи, и начните думать обо всех проектах, которые вы разработали.
Что они имеют общего? Если вы присмотритесь, вы увидите, что многие основные функции повторно используются в разных проектах. Эти основные функции часто включают аутентификацию пользователей, обработку платежей, управление пользователями и многое другое.
В этой статье я хотел бы подчеркнуть, что все эти шаблоны уже были созданы программистами прошлого. Действительно, почти все, что мы сейчас используем, уже реализовано. Мы просто модифицируем некоторый функционал исходя из конкретного проекта.
Я познакомлю вас с примерами серверной разработки на Python, но это можно применить к любому языку программирования или любой области разработки программного обеспечения.
Итак, что общего у всех серверных приложений? Давайте взглянем!
Примечание . Если вы знакомы с ООП (объектно-ориентированным программированием), считайте свои шаблонные модули высшим уровнем абстракции, но на уровне приложения , поэтому их следует писать в соответствии с этим принципом.
Я хотел бы разбить каждый следующий раздел на базовые компоненты, которые можно применить практически к любому серверному приложению.
Основные компоненты
2.1 Модель пользователя
Мы определяем наиболее общий класс User
с атрибутами, которые можно применить к любому конкретному пользователю.
from werkzeug.security import generate_password_hash, check_password_hash class User: def __init__(self, username, password, email): self.username = username self.password_hash = generate_password_hash(password) self.email = email self.roles = [] def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password)
2.2 Управление токенами
Использование JWT для аутентификации на основе токенов — хороший выбор с точки зрения кибербезопасности и лучших практик серверной разработки.
def generate_token(user): payload = { 'username': user.username, 'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1) } return jwt.encode(payload, SECRET_KEY, algorithm='HS256') def verify_token(token): try: payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256']) return payload['username'] except jwt.ExpiredSignatureError: return None except jwt.InvalidTokenError: return None
2.3 Декораторы
from functools import wraps from flask import request, jsonify, session def is_authenticated(func): @wraps(func) def decorated_function(*args, **kwargs): if 'user' not in session: return jsonify({"error": "User not authenticated"}), 401 return func(*args, **kwargs) return decorated_function
def roles_required(*roles): def decorator(func): @wraps(func) def decorated_function(*args, **kwargs): user_roles = session.get('roles', []) if not any(role in user_roles for role in roles): return jsonify({"error": "User does not have the required role"}), 403 return func(*args, **kwargs) return decorated_function return decorator
И, в принципе, вот и все! Вы можете использовать эту предопределенную функцию для аутентификации во всех проектах!
Практически любое приложение обрабатывает финансовые транзакции. Будь то местная мясная лавка или крупный гигант, вам потребуется использовать эффективную систему сбора платежей.
Основные компоненты
Stripe
или PayPal
3.1 Интеграция платежного шлюза
Это можно использовать в качестве основы для интеграции различных платежных шлюзов с конкретной реализацией Stripe. В целом я лично предпочитаю использовать StripeAPI
для платежей, поскольку он уже давно присутствует на рынке и действительно легко интегрируется в любой проект.
class PaymentGateway(ABC): @abstractmethod def create_payment_intent(self, amount, currency='gbp'): pass @abstractmethod def confirm_payment(self, payment_id): pass @abstractmethod def handle_webhook(self, payload, sig_header): pass
Это наиболее общий пример платежного шлюза, и вы можете сосредоточиться на конкретной реализации в соответствии с вашими потребностями.
3.2 Модели оплаты
Определите модели для хранения платежной информации. Этот пример можно адаптировать для использования с ORM. При необходимости вы можете создать более сложную иерархию классов, но для этого примера следующего фрагмента будет вполне достаточно.
class Payment: def __init__(self, user_id, amount, currency): self.id = uuid.uuid4() self.user_id = user_id self.amount = amount self.currency = currency self.status = status payments = []
Сохраните все платежи в базу данных и настройте задачу Celery
для обработки транзакций, для раздела 3.3. Записи базы данных должны выглядеть следующим образом:
id | user_id | amount | currency | status --------------------------------------+-----------------------------------+--------+----------+---------- e532d653-7c8b-453a-8cd4-3ab956863d72 | 1ff9efb3-d5e8-4e53-854f-4246ba9ff638 | 100.00 | USD | Failed 35985d41-5d54-4021-bed6-82d7233cc353 | a0984002-bace-478e-b6f9-6e4459e1b5ba | 250.50 | EUR | Pending 1ff9efb3-d5e8-4e53-854f-4246ba9ff638 | 9f896874-dc43-4592-8289-d0f7f8b8583a | 99.99 | GBP | Completed
Теперь мы создали сложную систему, которую можно интегрировать в любой проект. Вы все еще следуете шаблону? Это можно использовать ВЕЗДЕ!
Ведь вы можете определить другое приложение для визуализации этих данных. Вы поняли суть шаблонов! 😉
Электронная почта и уведомления позволяют пользователям быть в курсе событий и участвовать в жизни вашего приложения. Будь то проверка учетной записи, сброс пароля или маркетинговые коммуникации, надежная служба электронной почты необходима для любого типа проекта.
SendGrid
или Amazon SES
.
4.1 Интеграция службы электронной почты
Определите основную логику SendGrid
для отправки электронных писем внутри класса EmailService
.
import sendgrid from sendgrid.helpers.mail import Mail class EmailService: def __init__(self, api_key): self.sg = sendgrid.SendGridAPIClient(api_key) def send_email(self, from_email, to_email, subject, html_content): email = Mail( from_email=from_email, to_emails=to_email, subject=subject, html_content=html_content ) try: response = self.sg.send(email) return response.status_code except Exception as e: return str(e)
Как и в случае с платежным шлюзом, вам не нужно сосредотачиваться на каких-либо конкретных утилитах или продуктах на рынке. Это всего лишь пример того, как это можно обобщить и шаблонизировать для любого проекта.
4.2 Шаблоны электронных писем
Мой любимый шаблон для подобных систем — шаблон обработчиков; вы просто добавляете в словарь все больше и больше ключей как типа письма, так и пути к файлу с содержимым.
email_templates = { 'welcome': “welcome.html”, 'reset_password': "<h1>Reset Your Password</h1><p>Click <a href='{link}'>here</a> to reset your password.</p>" }
В противном случае было бы неплохо определить Enum
для тех же целей.
4.3 Отправка электронных писем
Нам нужна функция, чтобы творить волшебство! Напишем следующее:
def send_email(email_service, from_email, to_email, subject, template_name, **template_vars): """ Send an email using the specified email service. """ html_content = get_email_template(template_name, **template_vars) return email_service.send_email(from_email, to_email, subject, html_content)
Еще одним важным моментом будет добавление нескольких файлов во все серверные проекты, таких как README
.env
config.py
, pyproject.toml,
.pre-commit.yml
, и создание базовой структуры файлов внутри проекта.
Хотя предложенная структура немного ограничена реализацией Python, как я уже упоминал ранее, вы можете сделать то же самое для любого другого языка или области.
Также важно отметить, что создание шаблонов на самом высоком уровне абстракции и поддержание хорошей структуры приложения могут быть эффективными.
повторно использоваться для других проектов в качестве пакета или дополнения к архитектуре микросервиса.
ВСЕ МОЖНО СДЕЛАТЬ ПО ШАБЛОНУ!
Приведенные здесь примеры — это только начало: эти шаблоны можно расширять и уточнять, чтобы охватить более сложные сценарии по мере развития ваших проектов. Вы можете добавить caching
установить k8s
, docker
, инфраструктуру Devops
, CI/CD
и конвейеры.
Запомните одно простое утверждение: как только вы выполнили свою работу должным образом, вы можете использовать ту же работу при выполнении другой.
Цель состоит в том, чтобы сделать проект, инфраструктуру, компоненты и сервисы повторно используемыми в различных приложениях!
Заварите себе чашку чая и подумайте, какие части ваших приложений можно повторно использовать в других приложениях. Попробуйте создать подобные сервисы и автоматизировать свою работу, корректируя лишь некоторые участки кода!
Спасибо за прочтение и удачного создания шаблонов!