IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bibliothèques & Frameworks Discussion :

[sequelize] Création d'un wrapper de library (conseils, et bonnes pratiques)


Sujet :

Bibliothèques & Frameworks

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2015
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2015
    Messages : 76
    Points : 58
    Points
    58
    Par défaut [sequelize] Création d'un wrapper de library (conseils, et bonnes pratiques)
    Bonjour à tous,

    Dans le cadre d'une mise en place d'un projet JS avec le framework Vue.js, j'aimerais travaillé avec une base local comme Sqlite.
    Pour cela j'utilise la librairie Sequelize.

    Néanmoins je ne souhaite pas utiliser directement cette librairie dans mes scripts de vue afin d'alléger le code et de centraliser la logique autour de cette librairie.
    Pour cela j'ai décidé de créer un "wrapper" (fichier js qui sera appelé dans mes scripts vue) qui utilise réellement lui de son coté la librairie Sequelize (et non les vues).

    Néanmoins je n'arrive pas à inscrire de données dans un table, ni même récupérer des données.
    Pourtant j'arrive à établir une connexion à cette base de données.

    Étant encore plutôt novice en JavaScript, je pense avoir des soucis dans la logique de création de mon wrapper et j'aurais apprécié de l'aide avec un coup d’œil rapide sur mon code et des conseils.
    Mon wrapper est un objet qui contiendra l'ensemble de l'utilisation de Sequelize.

    Dois-je, a chaque fonction, retourné l'instance de l'objet lui-même ?
    Entre 2 appels à ce wrapper, garderais-je une instance active ?
    Quel type de concept dois-je respecter ou sur lesquels m'appuyer pour construire un tel wrapper ?



    Voici mon code de test ce trouvant dans la partie script d'une vue.js :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    import { sequelizeWrap } from '../../sequelize/sequelize'
     
    console.log(sequelizeWrap.test)
    console.log(sequelizeWrap.create())
    console.log(sequelizeWrap.auth())
    console.log(sequelizeWrap.User())
    console.log(sequelizeWrap.userSync())
    console.log(sequelizeWrap.userSync().findAll())
    console.log(sequelizeWrap.User.findAll())

    Voici mon wrapper :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    const Sequelize = require('sequelize')
     
    export let sequelizeWrap = {
      test: function () {
        console.log('ici2')
      },
      sequelize: null,
      create: function () {
        this.sequelize = new Sequelize('database', 'username', 'password', {
          host: 'localhost',
          dialect: 'sqlite',
          operatorsAliases: false,
     
          pool: {
            max: 5,
            min: 0,
            acquire: 30000,
            idle: 10000
          },
     
          // SQLite only
          storage: './database.sqlite'
        })
      },
      auth: function () {
        this.sequelize
          .authenticate()
          .then(() => {
            console.log('Connection has been established successfully.')
          })
          .catch(err => {
            console.error('Unable to connect to the database:', err)
          })
      },
      User: function () {
        this.sequelize.define('User', {
          firstName: {
            type: Sequelize.STRING
          },
          lastName: {
            type: Sequelize.STRING
          }
        })
      },
      userSync: function () {
        this.User.sync({force: true}).then(() => {
          return this.User.create({
            firstName: 'John',
            lastName: 'Hancock'
          })
        })
      }
    }
     
    // Or you can simply use a connection uri
    // const sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname')
    Merci d'avance pour vos éclairages et précieux conseils.

  2. #2
    Expert éminent sénior
    Avatar de Marco46
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2005
    Messages : 4 413
    Points : 19 609
    Points
    19 609
    Par défaut
    Dans le cadre d'une mise en place d'un projet JS avec le framework Vue.js, j'aimerais travaillé avec une base local comme Sqlite.
    Pour cela j'utilise la librairie Sequelize.
    Du coup ton problème est côté backend et n'a pas de lien avec Vue ? Ou bien tu fais un client lourd via Electron ?

    Néanmoins je ne souhaite pas utiliser directement cette librairie dans mes scripts de vue afin d'alléger le code et de centraliser la logique autour de cette librairie.
    Via quelle fonction ? userSync ?

    Tu n'as pas de gestion des erreurs dans l'implémentation de cette fonction, pas de clause catch, du coup impossible de savoir de quoi il retourne.

    C'est le premier point dont tu dois t'occuper pour savoir de quoi il retourne.

    Entre 2 appels à ce wrapper, garderais-je une instance active ?
    Les objets définis comme module sont en quelque sort des singletons (les instances retournées par require / import sont cachées). Mais ce n'est pas de cette manière que l'on crée un singleton habituellement.

    On passerait plutôt par une classe et une instanciation lors de l'exécution du module, par exemple :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    class Singleton {
      constructor() {
        // the class constructor
        if(! Singleton.instance){
          Singleton.instance = this;
        }
        return Singleton.instance;
      }
     
      publicMethod() {
        console.log('Public Method');
      }
    }
     
    const instance = new Singleton();
     
    // prevents new properties from being added to the object
    Object.freeze(instance);
     
    export default instance;
    Un problème avec Git ? Essayez la FAQ, sinon posez votre question sur le forum.



    "Toute personne croyant qu'une croissance exponentielle peut durer indéfiniment dans un monde fini est soit un fou, soit un économiste."
    Kenneth E. Boulding

    "Les richesses naturelles sont inépuisables, car, sans cela, nous ne les obtiendrions pas gratuitement. Ne pouvant être ni multipliées ni épuisées, elles ne sont pas l’objet des sciences économiques."
    Jean-Baptiste Say, Traité d'économie politique, 1803.

    "/home/earth is 102% full ... please delete anyone you can."
    Inconnu

  3. #3
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2015
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2015
    Messages : 76
    Points : 58
    Points
    58
    Par défaut
    Effectivement mon problème n'a pas trop de lien avec vue.js. Je ne faisais qu'expliquer le contexte technologique mais je pense que m'a problématique peut être identique à partir du moment ou l'on utilise une librairie JS. Et oui j'utilise node.js pour compiler une application Electron.

    Via quel fonction ? Je ne comprends pas bien la question...

    +1 pour la gestion des erreurs.

    Merci pour ton aide sur le singleton. Mais de manière plus générale :
    • est-ce une pratique courante de wrapper ses librairies ?
    • suis-je le seul à vouloir réduire/factoriser le code de la partie script d'un composant vue
    • quels seraient les autres bonnes pratiques dans ce genre de contexte ?
    • quel serait la bonne pratique d'architecture de fichier de code communément constaté pour faire ce genre de chose ?


    Il s'agit pour moi plus d'un sujet d'ordre général de développement JS plutôt que d'une résolution de problème. Tout retour d'expérience et bon à prendre.

  4. #4
    Expert éminent sénior
    Avatar de Marco46
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2005
    Messages : 4 413
    Points : 19 609
    Points
    19 609
    Par défaut
    Et oui j'utilise node.js pour compiler une application Electron.
    C'est important de poser le contexte parce que de prime abord vouloir manipuler une base de données dans un client classique (dans un browser donc) ça pose un problème de compréhension de l'architecture.

    Donc c'est bien de préciser, on voit souvent des questions passer du genre "comment je peux me connecter à la base de données depuis mon application <nom-du-framework>". Du coup je préfère demander.

    Oui surtout dans ce cas de figure, tu ne vas pas réécrire ta connexion dans chaque composant ça n'a pas de sens. De même tu ne vas te connecter qu'une seule fois à ta base de données au démarrage de ton application, donc tu dois absolument avoir ça dans un code à part.

    suis-je le seul à vouloir réduire/factoriser le code de la partie script d'un composant vue
    Non, le code d'appel à une base de données n'a rien à faire dans un composant d'ihm. Ca doit être dans un module séparé qui sera appelé par ta vue. Tu devrais même avoir une séparation entre le modèle de ta vue et celui tiré de la base de données, donc quelque chose comme ça :

    Composant Vue <--- Module gérant le modèle de la vue <--- Module DAO
    Ce que je nomme ici module DAO c'est ce que tu essaies d'écrire.

    Dans ces applications il faut faire la distinction entre ce que te retournes ta base de données (ou les webservices quand c'est sur le web) et ce que tu vas afficher dans ta vue. Il y a souvent des différences (transformations).

    Tu aurais intérêt à regarder du côté de Vuex.

    Mais pour l'heure ce n'est pas le problème de ton post, je pense même que ton problème n'a aucun rapport avec Vue.

    +1 pour la gestion des erreurs.
    Ben du coup ajoute la, et dis nous ce ça que te retourne comme erreur. Tu nous as dit au début que tu arrives bien à initier la connexion à ta base mais que tu n'arrives pas à ajouter des enregistrements et à les lire. Or tu ne regardes quelles erreurs sont remontées lorsque tu manipules ta base.

    Il faut le faire, et il nous faut les messages d'erreurs sinon on ne peut pas t'aider.

    De même tu nous as mis plein de console.log mais sans nous mettre le résultat que ça te donne.

    Bon je viens de relire ton code et ton problème est vraisemblablement ici :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    User: function () {
        this.sequelize.define('User', {
          firstName: {
            type: Sequelize.STRING
          },
          lastName: {
            type: Sequelize.STRING
          }
        })
      },
      userSync: function () {
        this.User.sync({force: true}).then(() => {
          return this.User.create({
            firstName: 'John',
            lastName: 'Hancock'
          })
        })
      }

    Tu as une fonction qui ne retourne rien (User). Et dans ta fonction userSync tu fais référence à la fonction User mais sans l'invoquer (il manque les parenthèses).

    Tu as un problème ici.

    Je ne connais pas sequelize mais vu le peu que j'ai lu dans la doc tu dois définir ton modèle via la fonction [C]User[C] puis manipuler la table correspondante via ses fonctions. A noter que le {force: true} dans sync va drop tes tables même si elles existent à chaque appel (c'est dans la doc).

    Je déplace ce sujet dans Biblio & framework vu que ça n'a aucun rapport avec Vue.
    Un problème avec Git ? Essayez la FAQ, sinon posez votre question sur le forum.



    "Toute personne croyant qu'une croissance exponentielle peut durer indéfiniment dans un monde fini est soit un fou, soit un économiste."
    Kenneth E. Boulding

    "Les richesses naturelles sont inépuisables, car, sans cela, nous ne les obtiendrions pas gratuitement. Ne pouvant être ni multipliées ni épuisées, elles ne sont pas l’objet des sciences économiques."
    Jean-Baptiste Say, Traité d'économie politique, 1803.

    "/home/earth is 102% full ... please delete anyone you can."
    Inconnu

Discussions similaires

  1. Conseils pour création d'un wrapper C++ -> C#
    Par Splatoon dans le forum Langages
    Réponses: 0
    Dernier message: 02/08/2016, 11h24
  2. Réponses: 114
    Dernier message: 09/07/2012, 12h09
  3. Cherche conseil Certification + bonnes pratiques
    Par babass77 dans le forum Certifications
    Réponses: 3
    Dernier message: 09/02/2009, 17h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo