Depuis que j'ai commencé mon parcours dans la programmation, j'ai remarqué un modèle intéressant : la majorité des applications sont basées sur des modèles. Oui, c'est un pur fait ! Arrêtez-vous ici, au début de cet article, et commencez à penser à tous les projets que vous avez développés.
Qu'est-ce qu'ils ont en commun? Si vous regardez attentivement, vous verrez que de nombreuses fonctionnalités essentielles sont réutilisées dans différents projets. Ces fonctionnalités de base incluent souvent l'authentification des utilisateurs, le traitement des paiements, la gestion des utilisateurs, etc.
Dans cet article, je voudrais souligner que tous ces modèles ont déjà été créés par des programmeurs du passé. En réalité, presque tout ce que nous utilisons actuellement a déjà été mis en œuvre. Nous modifions simplement certaines fonctionnalités en fonction du projet spécifique.
Je vais vous présenter des exemples du point de vue du développement backend en Python, mais cela peut être appliqué à n'importe quel langage de programmation ou à n'importe quel domaine du domaine du génie logiciel.
Alors, qu’ont en commun toutes les applications backend ? Nous allons jeter un coup d'oeil!
Remarque : Si vous êtes familier avec la POO (Programmation Orientée Objet), considérez vos modules modélisés comme le plus haut niveau d'abstraction mais au niveau applicatif afin que celui-ci soit écrit selon ce principe.
Je voudrais décomposer chaque section supplémentaire en composants de base, qui peuvent être appliqués à presque n'importe quelle application backend.
Composants de base
2.1 Modèle utilisateur
Nous définissons la classe la plus générique de l' User
avec des attributs pouvant être appliqués à n'importe quel utilisateur spécifique.
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 Gestion des jetons
L'utilisation de JWT pour l'authentification basée sur des jetons est un bon choix en termes de cybersécurité et de bonnes pratiques en matière de développement backend.
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 Décorateurs
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
Et en gros, c'est tout ! Vous pouvez utiliser cette fonctionnalité prédéfinie pour l'authentification sur tous les projets !
Presque toutes les applications gèrent les transactions financières. Qu'il s'agisse d'une boucherie locale ou d'une grande entreprise géante, vous devrez utiliser un système efficace pour encaisser les paiements.
Composants de base
Stripe
ou PayPal
3.1 Intégration de la passerelle de paiement
Celui-ci peut servir de base à l’intégration de différentes passerelles de paiement, avec une implémentation concrète pour Stripe. En général, ma préférence personnelle est d'utiliser StripeAPI
pour les paiements, car il existe depuis longtemps sur le marché et est vraiment facile à intégrer dans n'importe quel projet.
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
Il s’agit de l’exemple le plus générique de passerelle de paiement, et vous pouvez vous concentrer sur une mise en œuvre spécifique en fonction de vos besoins.
3.2 Modèles de paiement
Définissez des modèles pour stocker les informations de paiement. Cet exemple peut être adapté pour être utilisé avec ORM. Vous pouvez créer une hiérarchie de classes plus complexe si nécessaire, mais pour cet exemple, l'extrait suivant devrait suffire.
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 = []
Enregistrez tous les paiements dans la base de données et configurez une tâche Celery
pour le traitement des transactions, pour la section 3.3. Les enregistrements de la base de données devraient ressembler à ce qui suit :
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
Aujourd'hui, nous avons créé un système complexe qui peut être intégré à n'importe quel projet. Suivez-vous toujours le modèle ? Cela peut être utilisé PARTOUT !
Après tout, vous pouvez définir une autre application pour visualiser ces données. Vous avez compris le point sur les modèles ! 😉
Les e-mails et les notifications tiennent les utilisateurs informés et engagés dans la vie de votre application. Qu'il s'agisse de vérification de compte, de réinitialisation de mot de passe ou de communications marketing, un service de messagerie fiable est essentiel pour tout type de projet.
SendGrid
ou Amazon SES
.
4.1 Intégration du service de messagerie
Définissez la logique principale de SendGrid
pour l'envoi d'e-mails dans la classe 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)
Comme pour la passerelle de paiement, vous n'avez pas besoin de vous concentrer sur des utilitaires ou des produits spécifiques sur le marché. Ceci n'est qu'un exemple de la façon dont cela peut être généralisé et modélisé pour n'importe quel projet.
4.2 Modèles d'e-mails
Mon modèle préféré pour des systèmes comme celui-ci est le modèle des gestionnaires ; vous ajoutez simplement de plus en plus de clés au dictionnaire sous forme de type d'e-mail et le chemin d'accès au fichier avec un contenu.
email_templates = { 'welcome': “welcome.html”, 'reset_password': "<h1>Reset Your Password</h1><p>Click <a href='{link}'>here</a> to reset your password.</p>" }
Sinon, il pourrait être sympa de définir un Enum
dans le même but.
4.3 Envoi d'e-mails
Nous avons besoin d’une fonction pour que la magie opère ! Écrivons ce qui suit :
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)
Un autre point important serait d'ajouter plusieurs fichiers à tous les projets backend, tels que README
.env
config.py
, pyproject.toml,
.pre-commit.yml
et de proposer la structure de base des fichiers à l'intérieur du projet.
Bien que la structure suggérée soit un peu plus stricte que celle de l'implémentation Python, comme je l'ai déjà mentionné, vous pouvez faire de même pour n'importe quel autre langage ou domaine.
Il est également important de noter qu'il est possible de créer des modèles au plus haut niveau d'abstraction et de maintenir une bonne structure de l'application.
réutilisé pour d'autres projets en tant que package ou ajout à l'architecture du microservice.
TOUT PEUT ÊTRE MODÈLE !
Les exemples fournis ici ne sont qu'un début : ces modèles peuvent être étendus et affinés pour couvrir des scénarios plus complexes à mesure que vos projets évoluent. Vous pouvez ajouter caching
pour établir k8s
, docker
, l'infrastructure Devops
, CI/CD
et les pipelines.
Rappelez-vous une déclaration simple : une fois que vous avez fait votre travail correctement, vous pouvez utiliser le même travail tout en en accomplissant un autre.
L'objectif est de rendre le projet, l'infrastructure, les composants et les services réutilisables dans différentes applications !
Préparez-vous une tasse de thé et réfléchissez aux parties de vos applications qui peuvent être réutilisées dans différentes applications. Essayez de créer des services similaires et d'automatiser votre travail, en ajustant seulement quelques morceaux de code !
Merci d'avoir lu et bon modèle !