[PYTHON] Django REST Framework + Considération de conception d'architecture propre

Django REST Framework + conception d'une architecture propre

introduction

Avec l'essor récent de l'IA, je pense que le choix de construire avec Python pour le développement de nouveaux systèmes a augmenté. Quand il s'agit d'écrire de nouveaux services Web en Python, je pense que les principaux choix sont de fournir une API REST avec un framework tel que React ou Vue.js pour le front-end et Django ou Flask pour le back-end. Avec une configuration simple, le Django REST Framework facilite et simplifie la création d'un serveur API, mais quand cela devient un peu compliqué, cela devient rapidement chaotique si vous ne pensez pas correctement à l'architecture. ~~ Dans le cas où je suis entré, c'est déjà le chaos et le chaos. .. .. ~~ D'après mes recherches, il n'y a pas d'article sur la combinaison de Django REST Framework + Clean Architecture, donc je vais l'examiner dans cet article ainsi que dans ma propre étude et résumé de mes réflexions. ~~ C'est plutôt douloureux, alors j'aimerais vous le présenter avec le contenu résumé ici. ~~ Veuillez commenter si vous avez un bon design.

Cette fois, nous envisageons d'exclure le projet et l'application (décrit plus loin). De plus, le routage, ViewSet, ModelManager, etc. ne sont pas pris en compte.

Comme il ne s'agit que d'images et de phrases, j'ai essayé d'implémenter un échantillon. Un exemple de code peut être trouvé ici [https://github.com/ryoutoku/django_rest_clean_architecture). Sur la base du modèle de didacticiel Django, j'essaierai d'implémenter uniquement Question POST. (Cependant, comme je ne pouvais pas trop penser à la logique métier, c'est juste une implémentation qui rend le traitement POST inutilement redondant.)

Configuration et problèmes de Django REST Framework

Django lui-même est un framework basé sur l'idée qu'il y a plusieurs applications dans un projet et MVT (Model, View, Template). Dans le Framework Django REST, il n'y a pas de Template et plus Serializer.

Vous trouverez ci-dessous un diagramme de l'architecture et des rôles du Framework Django REST. Pour le traitement CRUD pour un modèle (1 table de base de données), fondamentalement vue -- sérialiseur -- model est 1 à 1 à 1, et il peut être fait simplement.

base architecture.png

Pour les services Web de niveau métier, lorsque l'API REST est exécutée, le traitement logique est effectué en fonction de certaines connaissances, règles et jugements métier, il est donc rare que seul le traitement CRUD d'une table soit effectué. Cependant, si vous démarrez l'implémentation sans considérer l'architecture en profondeur, l'architecture fournie par le Django REST Framework conduira au chaos. .. ..

Pour moi, les deux points suivants sont de gros problèmes qui ont tendance à être chaotiques. N'est-ce pas fondamentalement un cadre qui brise facilement le principe de la responsabilité unique? Je sens ça.

Problème 1. views a tendance à être compliqué (il a tendance à être Fat Contoller)

C'est un problème appelé Fat Controller, dans lequel la logique est écrite dans les vues. C'est un problème qui a tendance à se produire lorsqu'un débutant ou quelqu'un qui ne s'intéresse pas à l'architecture le fait.

Dans Django REST Framework, s'il est simple, il n'y a presque pas d'implémentation du traitement CRUD comme indiqué ci-dessous.

models.py


from django.db import models

class Question(models.Model):
    #Offrir ORM
    question_text = models.CharField(max_length=10)
    pub_date = models.DateTimeField('date published')

serialzers.py


from .models import Question
from rest_framework import serializers

class QuestionSerializer(serializers.ModelSerializer):
    # data <->Fournit une conversion de modèle
    class Meta:
        model = Question
        fields = '__all__'
        # data <->modèle Définit le modèle et le champ à convertir

views.py


from rest_framework import viewsets
from .models import Question
from .serializers import  QuestionSerializer

class QuestionViewSet(viewsets.ModelViewSet):
    #API REST I/Offre O
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

    #Parce que la source d'héritage ModelViewSet définit une fonction qui est une API pour le traitement CRUD.
    #Pas besoin de créer une méthode

Le traitement CRUD est fourni et masqué du côté de Django REST Framework. Par conséquent, par exemple, si vous devez incorporer une certaine logique lors de la sauvegarde des données (POST), vous pouvez facilement l'écrire dans views-> "Ajouter à vues (contrôleur) pour le moment ". N'est-ce pas souvent le cas que vous écrivez diverses choses en .py?

Si vous n'écrivez pas une nouvelle classe au lieu de l'écrire solidement, cela vous fera devenir un Fat Controller.

Problème 2. Les connaissances commerciales ont tendance à être dispersées dans les «sérialiseurs» et les «modèles»

Puisque Serializer fournit la validation, vous vous demanderez où mettre en œuvre la validation (pas au niveau des connaissances métier) comme les limites supérieure et inférieure des valeurs et le format des chaînes de caractères. Si vous mettez la logique de la manière dont elle est implémentée dans les sérialiseurs parce que la validation est fournie, cela placera seliarizers sur plusieurs responsabilités. Quelle est la validation des "sérialiseurs" lorsqu'ils sont implémentés dans "models"? Cela deviendra. De plus, si vous développez avec un grand nombre de personnes, la logique sera dispersée à moins que vous ne l'implémentiez avec une idée unifiée. .. ..

Si vous ne pensez pas à quoi mettre en œuvre et où, cela peut provoquer le chaos.

Causes des problèmes personnels

Je pense que la raison pour laquelle Serializer a tendance à être chaotique est qu'il fournit trop de fonctions (trop bonnes). Plus précisément, je me demande si la cause est la suivante.

-Serializer.save () enregistre l'enregistrement model correspondant (en fonction de la classe Serializer héritée)

Enquête préliminaire 1. Conception / mise en œuvre d'une autre personne

J'ai googlé "django rest framework logic" et il est sorti en premier cette page, Il est écrit que la logique est collectée dans les «sérialiseurs». Cependant, il y a un problème avec le test. Cette personne est écrite comme étant en «vues», mais je pense que la logique métier est susceptible d'être dispersée. .. .. ..

Enquête préliminaire 2. Support entre Django REST Framework et Clean Architecture

Ci-dessous, un schéma de la correspondance entre le Framework Django REST et Clean Architecture que j'interprète. La gauche est la composition originale, la droite est la [figure habituelle] de Clean Architecture (https://blog.cleancoder.com/uncle-bob/images/2012-08-13-the-clean-architecture/CleanArchitecture.jpg) J'ai essayé de le cartographier. La gauche est la référence et la droite est le mappage.

relation arch.png

En regardant cela, il n'y a pas de règle métier xxx correspondante. .. ..

Étude Django REST Framework + Clean Architecture Design

conception

Sur la base de ce qui précède, nous l'avons conçu comme suit. Ou plutôt, j'ai probablement fait référence à ici.

new architecture.png

En gros, je l'ai conçu avec la politique suivante. De toute évidence, la logique de domaine ne doit pas être écrite dans les vues, les sérialiseurs et les modèles. Inversement, pour ceux qui n'incluent pas la logique de domaine, il est supposé être utilisé selon le Framework Django REST.

comportement

Le comportement lors de la frappe de l'API REST est décrit ci-dessous (certains ne sont pas implémentés).

--Lors de l'exécution de la requête (GET)

--Utilisez les fonctions fournies par Django REST Framework telles quelles --Lors de l'extraction de données à partir de ressources autres que Django, définissez-les avec SerializerMethodField etc. du côté serializer.

--Dans validate () of serializer, validez la valeur en utilisant ʻAggregate et DomainObject`.

--Lors de l'exécution de la commande (POST / PUT / PATCH / DELETE): avec la logique métier ver

  1. views transmet dict des données du sérialiseur à ʻapplication_services` comme argument
  2. ʻapplication_service crée et traite ʻAggregate basé sur l'argument dict. --Utilisez ʻIXXXReader pour générer ʻAggregate à partir des données DB
  1. Retour en utilisant serializer pour la réponse basée sur dict obtenu à partir de ʻapplication_services`

Résumé et impressions

Voici un résumé de mes réflexions lors de la recherche et de la conception.

Concernant la mise en œuvre

Concernant le fonctionnement réel

Si vous souhaitez créer un serveur API (ou concevoir un URI), j'ai pensé qu'il serait préférable d'utiliser correctement les API GraphQL et REST avec la politique suivante.

--Fourni par GraphQL pour la requête

finalement

Je suis sûr sur le site actuel "C'est plus simple et plus facile à comprendre si vous insérez la logique dans des" vues "(1 méthode a plus de 200 lignes de logique implémentées)" "Si vous faites un cours en vain, la performance sera ... (Il semble que la performance ne soit pas mesurée)" Ah ... je ne sais pas ...

Les références

https://medium.com/@amarbasic4/django-rest-framework-where-to-put-business-logic-82e71c339022 https://isseisuzuki.com/it/django-rest-framework-concept/ https://qiita.com/MinoDriven/items/3c7db287e2c66f36589a https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html https://blog.tai2.net/the_clean_architecture.html

Recommended Posts

Django REST Framework + Considération de conception d'architecture propre
Bases du framework Django REST
Astuces Django Rest Framework
Bloc d'achoppement du framework Django REST
Framework Django REST avec Vue.js
Connectez-vous avec Django Rest Framework
[Django] Utiliser MessagePack avec le framework Django REST
Suppression logique dans Django, DRF (Django REST Framework)
Comprendre la commodité de Django Rest Framework
CRUD GET avec Nuxt & Django REST Framework ②
Notes diverses sur le framework Django REST
Framework Django REST Un peu utile à savoir.
Implémenter la fonctionnalité de connexion JWT dans le framework Django REST
Implémentation de la fonction d'authentification dans Django REST Framework à l'aide de djoser
Créer une application Todo avec Django REST Framework + Angular
Plus de nouvelles méthodes d'authentification des utilisateurs avec Django REST Framework
Essayez de créer une application Todo avec le framework Django REST
Créer une API autour de l'authentification des utilisateurs avec Django REST Framework
Lorsque vous souhaitez filtrer avec le framework Django REST
List, méthode pour les ressources imbriquées dans le framework Django REST
Implémentez l'API à une vitesse explosive en utilisant Django REST Framework
[Django Rest Framework] Personnalisez la fonction de filtre à l'aide de Django-Filter
Implémenter des URL hiérarchiques avec des routeurs imbriqués drf dans le framework Django REST
Framework Web Django Python
Comment écrire une validation personnalisée dans Django REST Framework
Comment réinitialiser le mot de passe via l'API à l'aide du framework Rest Django
Décorateurs du cadre de repos Django ʻaction decorator remplace list_route et detail_route`