Enfreindre les règles : utiliser SQLite pour faire la démonstration d'applications Web
Publié: 2022-03-10La plupart des utilisateurs potentiels voudront essayer le logiciel ou le service avant d'engager du temps et de l'argent. Certains produits fonctionnent très bien en offrant simplement aux utilisateurs un essai gratuit, tandis que d'autres applications sont mieux expérimentées avec des exemples de données déjà en place. C'est souvent là que le compte de démonstration séculaire entre en jeu.
Cependant, toute personne ayant déjà mis en place un compte de démonstration peut témoigner des problèmes associés. Vous savez comment les choses fonctionnent sur Internet : n'importe qui peut entrer des données (que cela ait un sens ou non pour le produit) et il y a de fortes chances que le contenu ajouté par des utilisateurs anonymes ou des bots puisse être offensant pour les autres. Bien sûr, vous pouvez toujours réinitialiser la base de données, mais à quelle fréquence et quand ? Et finalement, est-ce que ça résout vraiment le problème ? Ma solution pour utiliser SQLite .
Pourquoi ne pas utiliser SQLite pour la version de production ?
Il est bien connu que SQLite ne gère pas plusieurs threads car toute la base de données est verrouillée lors d'une commande d'écriture, ce qui est l'une des raisons pour lesquelles vous ne devriez pas l'utiliser dans un environnement de production normal. Cependant, dans ma solution, un fichier SQLite distinct est utilisé pour chaque utilisateur faisant la démonstration du logiciel. Cela signifie que la limitation d'écriture est uniquement limitée à cet utilisateur, mais plusieurs utilisateurs simultanés (chacun avec son propre fichier de base de données) ne seront pas confrontés à cette limitation. Cela permet une expérience contrôlée pour l'utilisateur testant le logiciel et lui permet de voir exactement ce que vous voulez qu'il voie.
Ce didacticiel est basé sur une solution du monde réel que j'exécute avec succès pour une application Web de démonstration SaaS depuis 2015. Le didacticiel est écrit pour Ruby on Rails (mon framework de choix) version 3 et ultérieure, mais les concepts de base doivent être pouvant être adapté à tout autre langage ou framework. En fait, étant donné que Ruby on Rails suit le paradigme logiciel "convention over configuration", il peut même être plus facile à implémenter dans d'autres frameworks, en particulier les langages nus (comme le PHP pur) ou les frameworks qui ne font pas grand-chose en termes de gestion des connexions à la base de données. .
Cela dit, cette technique est particulièrement bien adaptée à Ruby on Rails. Pourquoi? Parce que, pour la plupart, il est "indépendant de la base de données". Cela signifie que vous devriez pouvoir écrire votre code Ruby et basculer entre les bases de données sans aucun problème.
Un échantillon d'une version finale de ce processus peut être téléchargé à partir de GitHub.
Première étape : environnement de déploiement
Nous reviendrons au déploiement plus tard, mais Ruby on Rails est par défaut divisé en environnements de développement, de test et de production. Nous allons ajouter à cette liste un nouvel environnement de démonstration pour notre application qui sera presque identique à l'environnement de production mais nous permettra d'utiliser différents paramètres de base de données.
Dans Rails, créez un nouvel environnement en dupliquant le fichier config/environments/production.rb
et renommez-le demo.rb
. Étant donné que l'environnement de démonstration sera utilisé dans un environnement de production, vous n'aurez peut-être pas besoin de modifier de nombreuses options de configuration pour ce nouvel environnement, bien que je suggère de modifier config.assets.compile
de false
à true
, ce qui facilitera le test local sans avoir à précompiler.
Si vous utilisez Rails 4 ou supérieur, vous devrez également mettre à jour config/secrets.yml
secrets.yml pour ajouter une secret_key_base
pour l'environnement de démonstration. Assurez-vous que cette clé secrète est différente de celle de la production pour vous assurer que les sessions sont uniques entre chaque environnement, ce qui sécurise davantage votre application.
Ensuite, vous devez définir la configuration de la base de données dans config/database.yml
. Alors que l'environnement de démonstration utilisera principalement la base de données dupliquée que nous aborderons dans la section suivante, nous devons définir le fichier de base de données par défaut et les paramètres à utiliser pour notre démonstration. Ajoutez ce qui suit à config/database.yml
:
demo: adapter: sqlite3 pool: 5 timeout: 5000 database: db/demo.sqlite3
Dans Rails, vous pouvez également vérifier votre Gemfile
pour vous assurer que SQLite3 est disponible dans le nouvel environnement de démonstration. Vous pouvez définir cela de plusieurs façons, mais cela peut ressembler à ceci :
group :development, :test, :demo do gem 'sqlite3' end
Une fois la base de données configurée, vous devez rake db:migrate RAILS_ENV=demo
, puis ensemencer les données dans la base de données comme vous le souhaitez (que ce soit à partir d'un fichier de départ, en saisissant manuellement de nouvelles données ou même en dupliquant le fichier development.sqlite3
). À ce stade, vous devez vérifier que tout fonctionne en exécutant rails server -e demo
à partir de la ligne de commande. Pendant que vous exécutez le serveur dans le nouvel environnement de démonstration, vous pouvez vous assurer que vos données de test sont comme vous le souhaitez, mais vous pouvez toujours revenir et modifier ce contenu plus tard. Lors de l'ajout de votre contenu à la base de données de démonstration, je vous recommande de créer un ensemble de données propre afin que le fichier soit aussi petit que possible. Toutefois, si vous devez migrer des données à partir d'une autre base de données, je recommande YamlDb, qui crée un format indépendant de la base de données pour le vidage et la restauration des données.
Si votre application Rails fonctionne comme prévu, vous pouvez passer à l'étape suivante.
La deuxième étape : utiliser la base de données de démonstration
La partie essentielle de ce tutoriel est de pouvoir permettre à chaque session d'utiliser un fichier de base de données SQLite différent. Normalement, votre application se connectera à la même base de données pour chaque utilisateur, de sorte qu'un code supplémentaire sera nécessaire pour cette tâche.
Pour commencer à autoriser Ruby on Rails à changer de base de données, nous devons d'abord ajouter les quatre méthodes privées suivantes dans application_controller.rb
. Vous devrez également définir un filtre avant pour la méthode set_demo_database
afin que la logique référençant la base de données de démonstration correcte soit appelée à chaque chargement de page.
# app/controllers/application_controller.rb # use `before_filter` for Rails 3 before_action :set_demo_database, if: -> { Rails.env == 'demo' } private # sets the database for the demo environment def set_demo_database if session[:demo_db] # Use database set by demos_controller db_name = session[:demo_db] else # Use default 'demo' database db_name = default_demo_database end ActiveRecord::Base.establish_connection(demo_connection(db_name)) end # Returns the current database configuration hash def default_connection_config @default_config ||= ActiveRecord::Base.connection.instance_variable_get("@config").dup end # Returns the connection hash but with database name changed # The argument should be a path def demo_connection(db_path) default_connection_config.dup.update(database: db_path) end # Returns the default demo database path defined in config/database.yml def default_demo_database return YAML.load_file("#{Rails.root.to_s}/config/database.yml")['demo']['database'] end
Étant donné que chaque session de serveur aura une base de données différente, vous stockerez le nom de fichier de la base de données dans une variable de session. Comme vous pouvez le voir, nous utilisons session[:demo_db]
pour suivre la base de données spécifique de l'utilisateur. La méthode set_demo_database
contrôle la base de données à utiliser en établissant la connexion à la base de données définie dans la variable de session. La méthode default_demo_database
charge simplement le chemin de la base de données tel que défini dans le fichier de configuration database.yml
.
Si vous utilisez un langage simple, à ce stade, vous pouvez probablement simplement mettre à jour votre script de connexion à la base de données pour pointer vers la nouvelle base de données, puis passer à la section suivante. Dans Rails, les choses nécessitent quelques étapes supplémentaires car elles suivent le paradigme logiciel "convention over configuration".
La troisième étape : dupliquer le fichier SQLite
Maintenant que l'application est configurée pour utiliser la nouvelle base de données, nous avons besoin d'un déclencheur pour la nouvelle session de démonstration. Par souci de simplicité, commencez par utiliser simplement un bouton "Démarrer la démo" de base. Vous pouvez également en faire un formulaire où vous collectez un nom et une adresse e-mail (pour un suivi de l'équipe de vente, etc.) ou un certain nombre de choses.
En respectant les conventions Rails, créez un nouveau contrôleur "Démo":
rails generate controller demos new
Ensuite, vous devez mettre à jour les routes pour qu'elles pointent vers vos nouvelles actions de contrôleur, en les enveloppant dans une condition pour éviter qu'elles ne soient appelées dans l'environnement de production. Vous pouvez nommer les itinéraires comme vous le souhaitez ou les nommer en utilisant les conventions Rails standard :
if Rails.env == 'demo' get 'demos/new', as: 'new_demo' post 'demos' => 'demos#create', as: 'demos' end
Ensuite, ajoutons un formulaire très basique au views/demos/new.html.erb
. Vous pouvez ajouter des champs de formulaire supplémentaires pour capturer :
<h1>Start a Demo</h1> <%= form_tag demos_path, method: :post do %> <%= submit_tag 'Start Demo' %> <% end %>
La magie opère dans l'action de create
. Lorsque l'utilisateur se soumet à cette route, l'action copie le fichier demo.sqlite3
avec un nouveau nom de fichier unique, définit les variables de session, connecte l'utilisateur (le cas échéant), puis redirige l'utilisateur vers la page appropriée (nous appellerons cela le 'tableau de bord').
class DemosController < ApplicationController def new # Optional: setting session[:demo_db] to nil will reset the demo session[:demo_db] = nil end def create # make db/demos dir if doesn't exist unless File.directory?('db/demos/') FileUtils.mkdir('db/demos/') end # copy master 'demo' database master_db = default_demo_database demo_db = "db/demos/demo-#{Time.now.to_i}.sqlite3" FileUtils::cp master_db, demo_db # set session for new db session[:demo_db] = demo_db # Optional: login code (if applicable) # add your own login code or method here login(User.first) # Redirect to wherever you want to send the user next redirect_to dashboard_path end end
Vous devriez maintenant pouvoir essayer le code de démonstration localement en lançant à nouveau le serveur en utilisant rails server -e demo
.
Si le serveur était déjà en cours d'exécution, vous devrez le redémarrer pour toute modification apportée car il est configuré pour mettre en cache le code comme le serveur de production.
Une fois que tout le code fonctionne comme prévu, validez vos modifications dans votre contrôle de version et assurez-vous de valider le fichier demo.sqlite3
, mais pas les fichiers du répertoire db/demos
. Si vous utilisez git, vous pouvez simplement ajouter ce qui suit à votre fichier .gitignore
:
Si vous souhaitez collecter des informations supplémentaires auprès de l'utilisateur de démonstration (telles que le nom et/ou l'e-mail), vous souhaiterez probablement envoyer ces informations via une API à votre application principale ou à un autre pipeline de vente, car votre base de données de démonstration ne sera pas fiable. (il se réinitialise à chaque fois que vous redéployez).
!/db/demo.sqlite3 db/demos/*
Dernière étape : déploiement de votre serveur de démonstration
Maintenant que votre configuration de démonstration fonctionne localement, vous voudrez évidemment la déployer pour que tout le monde puisse l'utiliser. Bien que chaque application soit différente, je recommanderais que l'application de démonstration réside sur un serveur séparé et donc un domaine en tant qu'application de production (comme demo.myapp.com). Cela garantira que vous gardez les deux environnements isolés. De plus, comme le fichier SQLite est stocké sur le serveur, des services comme Heroku ne fonctionneront pas car il ne donne pas accès au système de fichiers. Cependant, vous pouvez toujours utiliser pratiquement n'importe quel fournisseur VPS (comme AWS EC2, Microsoft Azure, etc.). Si vous aimez la commodité automatisée, il existe d'autres options de plates-formes en tant que service qui vous permettent de travailler avec VPS.
Quel que soit votre processus de déploiement, vous devrez peut-être également vérifier que l'application dispose des autorisations de lecture/écriture appropriées pour votre répertoire dans lequel vous stockez les fichiers de démonstration SQLite. Cela peut être géré manuellement ou avec un hook de déploiement.
SQLite ne fonctionnera pas pour moi. Qu'en est-il des autres systèmes de bases de données ?
Il n'y a pas deux applications créées identiques et leurs exigences en matière de base de données non plus. En utilisant SQLite, vous avez l'avantage de pouvoir dupliquer rapidement la base de données, ainsi que de pouvoir stocker le fichier en contrôle de version. Bien que je pense que SQLite fonctionnera dans la plupart des situations (en particulier avec Rails), il existe des situations dans lesquelles SQLite peut ne pas convenir aux besoins de votre application. Heureusement, il est toujours possible d'utiliser les mêmes concepts ci-dessus avec d'autres systèmes de base de données. Le processus de duplication d'une base de données sera légèrement différent pour chaque système, mais je vais décrire une solution pour MySQL et un processus similaire existe avec PostgreSQL et d'autres.
La majorité des méthodes décrites ci-dessus fonctionnent sans aucune modification supplémentaire. Cependant, au lieu de stocker un fichier SQLite dans votre contrôle de version, vous devez utiliser mysqldump
(ou pg_dump
pour PostgreSQL) pour exporter un fichier SQL de la base de données dont vous souhaitez utiliser le contenu pour votre expérience de démonstration. Ce fichier doit également être stocké dans votre contrôle de version.
Les seules modifications apportées au code précédent se trouveront dans l'action demos#create
. Au lieu de copier le fichier SQLite3, l'action du contrôleur créera une nouvelle base de données, chargera le fichier sql dans cette base de données et accordera des autorisations à l'utilisateur de la base de données si nécessaire. La troisième étape d'octroi de l'accès n'est nécessaire que si l'administrateur de votre base de données est différent de l'utilisateur utilisé par l'application pour se connecter. Le code suivant utilise des commandes MySQL standard pour gérer ces étapes :
def create # database names template_demo_db = default_demo_database new_demo_db = "demo_database_#{Time.now.to_i}" # Create database using admin credentials # In this example the database is on the same server so passing a host argument is not require `mysqladmin -u#{ ENV['DB_ADMIN'] } -p#{ ENV['DB_ADMIN_PASSWORD'] } create #{new_demo_db}` # Load template sql into new database # Update the path if it differs from where you saved the demo_template.sql file `mysql -u#{ ENV['DB_ADMIN'] } -p#{ ENV['DB_ADMIN_PASSWORD'] } #{new_demo_db} < db/demo_template.sql` # Grant access to App user (if applicable) `mysql -u#{ ENV['DB_ADMIN'] } -p#{ ENV['DB_ADMIN_PASSWORD'] } -e "GRANT ALL on #{new_demo_db}.* TO '#{ ENV['DB_USERNAME'] }'@'%';"` # set session for new db session[:demo_db] = new_demo_db # Optional: login code (if applicable) # add your own login code or method here login(User.first) redirect_to dashboard_path end
Ruby, comme de nombreux autres langages, y compris PHP, vous permet d'utiliser des backticks pour exécuter une commande shell (c'est-à-dire `ls -a`
) à partir de votre code. Cependant, vous devez l'utiliser avec prudence et vous assurer qu'aucun paramètre ou variable visible par l'utilisateur ne peut être inséré dans la commande pour protéger votre serveur contre le code injecté de manière malveillante. Dans cet exemple, nous interagissons explicitement avec les outils de ligne de commande MySQL, qui est le seul moyen de créer une nouvelle base de données. C'est de la même manière que le framework Ruby on Rails crée une nouvelle base de données. Assurez-vous de remplacer ENV['DB_ADMIN']
et ENV['DB_ADMIN_PASSWORD']
par votre propre variable d'environnement ou par tout autre moyen de définir le nom d'utilisateur de la base de données. Vous devrez faire de même pour l' ENV['DB_USERNAME']
si votre utilisateur admin est différent de l'utilisateur de votre application.
C'est tout ce qu'il faut pour passer à MySQL ! L'avantage le plus évident de cette solution est que vous n'avez pas à vous soucier des problèmes potentiels qui pourraient apparaître à cause de la syntaxe différente entre les systèmes de base de données.
Finalement, une décision finale est prise en fonction de la qualité et du service attendus, plutôt que de la commodité et de la rapidité, et elle n'est pas nécessairement influencée uniquement par le prix.
Dernières pensées
Ceci n'est qu'un point de départ pour ce que vous pouvez faire avec votre nouveau serveur de démonstration. Par exemple, votre site Web de marketing peut contenir un lien vers "Essayer la fonctionnalité XYZ". Si vous n'avez pas besoin d'un nom ou d'un e-mail, vous pouvez lier la méthode demos#create
avec un lien tel que /demos/?feature=xyz
et l'action redirigera simplement vers la fonctionnalité et/ou la page souhaitée, plutôt que vers le tableau de bord dans l'exemple ci-dessus.
De plus, si vous utilisez SQLite pour les environnements de développement et de démonstration, avoir toujours cet exemple de base de données dans le contrôle de version donnerait à tous vos développeurs l'accès à une base de données propre à utiliser dans le développement local, les environnements de test ou les tests d'assurance qualité. Les possibilités sont infinies.
Vous pouvez télécharger une démo terminée à partir de GitHub.