Comment déployer une application React avec PostgreSQL ?

How to build and deploy a web application with a PostgreSQL database_
How to build and deploy a web application with a PostgreSQL database_

PostgreSQL est un système de gestion de base de données relationnelle avancé, prêt pour l’entreprise, avec de nombreux cas d’utilisation. C’est actuellement la deuxième base de données SQL la plus populaire, juste après MySQL.

Dans cet article, nous nous penchons sur l’essence de PostgreSQL, explorons les distinctions entre les bases de données SQL et NoSQL, et fournissons un guide étape par étape sur le déploiement d’une application web soutenue par PostgreSQL.

Qu’est-ce que PostgreSQL ?

PostgreSQL est une base de données relationnelle objet libre et gratuite qui prend en charge SQL et JSON.

Il a été lancé en 1996 et est donc considéré comme un système de gestion de base de données relationnelle (SGBDR) mature, robuste et sûr.

Postgres peut être utilisé comme base de données transactionnelle polyvalente, base de données géospatiale, base de données d’applications web dynamiques, base de données fédérée, etc.

Par rapport à d’autres bases de données populaires telles que MySQL, elle prend en charge l’héritage des tables, les types définis par l’utilisateur, la réplication asynchrone et le contrôle de concurrence multi-version (MVCC).

Il est connu pour ses performances, son évolutivité, son extensibilité, sa tolérance aux pannes et sa conformité à la norme ACID.

Le SGBDR est pris en charge par la plupart des grands systèmes d’exploitation, notamment Windows, Linux et macOS.

En outre, il prend en charge les langages de programmation les plus courants tels que Java, Python, C, Go, Perl et JavaScript.

Bases de données SQL et NoSQL

Les bases de données peuvent être divisées en deux catégories en fonction de leur structure de données :

  • Bases de données relationnelles (SQL)
  • Bases de données non relationnelles (NoSQL)

Bases de données relationnelles (SQL)

Les bases de données relationnelles utilisent le langage SQL (Structured Query Language). SQL est un langage spécifique à un domaine, utilisé pour l’interrogation et la manipulation de données.

Le langage prend en charge les commandes simples, les transactions et les procédures intégrées, telles que les fonctions stockées ou les vues.

Les bases de données SQL sont basées sur des schémas prédéfinis. Elles sont composées de tables avec un ensemble de colonnes, chacune ayant son propre type de données. Elles ont généralement des propriétés ACID :

  • Atomicité
  • Cohérence
  • L’isolement
  • Durabilité

Les bases de données SQL sont largement utilisées depuis les années 1970.

Les bases de données SQL les plus populaires sont MySQL, PostgreSQL, SQLite et Oracle Database.

Bases de données non relationnelles (NoSQL)

Les bases de données non relationnelles, ou bases de données non SQL, ne suivent pas un schéma strict. Elles sont parfaites pour stocker d’énormes quantités de données non structurées ou dynamiques, le plus souvent JSON.

Il existe de nombreux types de bases de données NoSQL, notamment :

  • Bases de données documentaires
  • Bases de données clé-valeur
  • Bases de données graphiques

Ces dernières années, les bases de données NoSQL sont devenues de plus en plus populaires en raison de la disponibilité de grandes quantités de données non structurées.

Les bases de données NoSQL les plus utilisées sont Redis, Cassandra et AWS DynamoDB.

Quelle est la meilleure solution : SQL ou NoSQL ?

Le choix entre les bases de données SQL et NoSQL dépend de votre cas d’utilisation et de vos données.

Si vous traitez d’énormes quantités de données non structurées, optez sans hésiter pour NoSQL. En revanche, si vos données sont essentiellement structurées, SQL est un meilleur choix.

Deux autres facteurs à prendre en compte sont les performances et l’évolutivité. Les bases de données NoSQL ont tendance à être plus rapides que les bases de données SQL. Les bases de données SQL ne peuvent évoluer que verticalement, alors que les bases de données NoSQL peuvent évoluer horizontalement.

Enfin, certains cadres web ne prennent en charge que les bases de données SQL, tandis que d’autres ne prennent en charge que les bases de données NoSQL.

Comment déployer une application React avec PostgreSQL ?

Dans cette section de l’article, vous apprendrez comment déployer une application web soutenue par Postgres sur Back4app.

Conditions préalables

Qu’est-ce que la pile Back4app ?

Avant de plonger dans le processus de déploiement, discutons brièvement des solutions offertes par Back4app.

  1. Back4app (BaaS) est une solution backend à part entière. Elle inclut la gestion des utilisateurs, l’authentification, les bases de données en temps réel (NoSQL ou PostgreSQL), l’exécution de code personnalisé, les API auto-générées, les SDK, les notifications push, et plus encore.
  2. Back4app Containers (CaaS ) est une plateforme de gestion et de déploiement de conteneurs alimentée par Docker. Elle permet de créer des conteneurs Docker en quelques clics !
  3. Back4app AI-agent est un tout nouvel agent doté d’une intelligence artificielle. Il vous permet d’effectuer toutes les tâches liées au cloud grâce à la puissance de la conversation. L’agent s’intègre étroitement avec les deux autres solutions de Back4app.

Tout au long de cet article, nous utiliserons Back4app BaaS et Back4app Containers. Néanmoins, vous devriez consulter Comment utiliser l’IA pour le développement web ? pour apprendre comment tirer parti de l’IA pour accélérer votre processus de développement.

Aperçu du projet

Nous allons créer une application web simple de suivi de budget. L’application web permettra aux utilisateurs d’ajouter des dépenses, de les supprimer et de calculer différentes statistiques (par exemple, le montant dépensé, le pourcentage du budget).

L’application sera divisée en deux parties : le backend et le frontend. Le backend sera construit avec Back4app (soutenu par PostgreSQL), et le frontend sera construit avec React (utilisant Next.js).

Nous allons connecter les deux en utilisant Parse SDK et déployer le frontend sur Back4app Containers.

Backend

Commençons par le backend.

Créer l’application Back4app

Pour créer une application Back4app, naviguez d’abord sur votre tableau de bord Back4app et cliquez sur “Créer une nouvelle application”.

Back4app Construire une nouvelle application

Ensuite, sélectionnez “Backend as a Service” puisque nous construisons un backend.

Back4app Backend as a Service

Donnez un nom descriptif à votre application, sélectionnez “PostgreSQL” comme base de données et cliquez sur “Créer”.

Configuration de l'application Back4app

À l’heure actuelle, il n’y a pas de grande différence entre les deux types de bases de données du point de vue du développeur. Les mêmes méthodes du SDK Parse s’appliquent aux deux.

Back4app prendra un peu de temps pour préparer tout ce qui est nécessaire à votre application. Cela inclut la base de données, la couche d’application, l’auto-scaling, l’auto-backup et les paramètres de sécurité.

Dès que votre application est prête, vous êtes redirigé vers la vue de la base de données en temps réel de l’application.

Vue de la base de données de Back4app

Architecture de la base de données

Passons maintenant à la conception de la base de données.

Notre application étant relativement simple, nous n’aurons besoin que d’une seule classe. Appelons-la Expense.

Pour créer une nouvelle classe de base de données, cliquez sur “Créer une classe”, nommez-la ” Dépenses" et assurez-vous que l’option “Lecture et écriture publiques” est cochée.

Back4app Créer une nouvelle classe

L’activation de la lecture et de l’écriture publiques est considérée comme une mauvaise pratique car elle permet à n’importe qui d’effectuer des opérations CRUD sur vos classes. La sécurité n’entre pas dans le cadre de cet article. Cependant, il peut être intéressant d’étudier la sécurité de Parse Server.

Par défaut, les classes de base de données comportent les quatre champs suivants :

+-----------+------------------------------------------------------------------------+
| Name      | Explanation                                                            |
+-----------+------------------------------------------------------------------------+
| objectId  | Object's unique identifier                                             |
+-----------+------------------------------------------------------------------------+
| updatedAt | Date time of the object's last update.                                 |
+-----------+------------------------------------------------------------------------+
| createdAt | Date time of object's creation.                                        |
+-----------+------------------------------------------------------------------------+
| ACLs      | Allow you to control the access to the object (e.g. read, update).     |
+-----------+------------------------------------------------------------------------+

Jetez-y un coup d’œil rapide, car nous les utiliserons lors de la construction du frontend.

Ensuite, ajoutez les champs suivants à la classe Dépenses :

+-----------+-------------+--------------------+----------+
| Data type | Name        | Default value      | Required |
+-----------+-------------+--------------------+----------+
| String    | name        | <leave blank>      | yes      |
+-----------+-------------+--------------------+----------+
| String    | description | <leave blank>      | no       |
+-----------+-------------+--------------------+----------+
| Number    | price       | 0                  | yes      |
+-----------+-------------+--------------------+----------+

Ensuite, alimentez la base de données avec quelques exemples de données.

Créez quelques articles en indiquant les noms, les descriptions et les prix. Vous pouvez également importer ces données.

Base de données Back4app alimentée

Les données de test nous permettront plus tard de tester le backend et le frontend.

Code du nuage

Back4app vous permet d’exécuter du code JavaScript personnalisé via des fonctions Cloud Code. Les fonctions peuvent être programmées en tant que tâches ou invoquées par des requêtes Parse ou HTTP.

Comme ils sont exploités dans un environnement géré, il n’est pas nécessaire de gérer et de faire évoluer vos propres serveurs.

Pour en savoir plus sur les fonctions en tant que service (FaaS), consultez Qu’est-ce que les fonctions sans serveur ?

Nous utiliserons une fonction de Cloud Code pour calculer les statistiques de dépenses.

Pour en créer un, sélectionnez “Cloud Code > Functions & Web Hosting” dans la barre latérale. Ouvrez ensuite cloud/main.js et collez le code suivant :

// cloud/main.js

const totalBudget = 100;

Parse.Cloud.define("getStatistics", async (request) => {
  const query = new Parse.Query("Expense");
  const totalExpenses = await query.count();
  const results = await query.find();

  const totalSpent = results.reduce(
    (sum, expense) => sum + expense.get("price"), 0);
  const spentPercentage = totalSpent > 0 ? 
    Math.round((totalSpent / totalBudget) * 100) : 0;

  return {
    totalExpenses,
    totalSpent,
    totalBudget,
    spentPercentage
  };
});
  1. Ce code définit une nouvelle fonction du code cloud appelée getStatistics.
  2. La fonction agrège les données et calcule le total des dépenses et le pourcentage des dépenses.

Enfin, cliquez sur “Déployer” pour déployer la fonction dans le nuage.

Et nous en avons terminé avec le backend. C’était facile !

Frontend

Dans cette section de l’article, nous allons mettre en place le frontend de l’application.

Créer l’application suivante

La façon la plus simple de démarrer une application Next.js est d’utiliser l’utilitaire create-next-app. Pour l’utiliser, ouvrez le terminal et exécutez la commande suivante :

$ npx create-next-app@latest back4app-postgres

√ Would you like to use TypeScript? ... No
√ Would you like to use ESLint? ... Yes
√ Would you like to use Tailwind CSS? ... Yes
√ Would you like to use `src/` directory? ... Yes
√ Would you like to use App Router? (recommended) ... Yes
√ Would you like to customize the default import alias (@)? ... No

Creating a new Next.js app in /back4app-postgres.

Si vous n’avez jamais utilisé l’utilitaire create-next-app, il sera automatiquement installé.

Assurez-vous d’activer TailwindCSS car nous l’utiliserons à la place d’une bibliothèque de composants.

Ensuite, nettoyez le projet bootstrapped en supprimant d’abord le contenu du dossier public/.

Ne conserver que les trois premières lignes de src/app/globals.css:

/* app/src/globals.css */
@tailwind base; @tailwind components; @tailwind utilities;

Et remplacer app/src/globals.css par le code suivant :

// src/app/page.js 
export default function Page() { 
  return ( 
      <p>Back4app rocks!</p> 
  ); 
}

Démarrer le serveur de développement :

$ next dev

Ouvrez votre navigateur web préféré et rendez-vous sur http://localhost:3000/. Si tout se passe bien, vous devriez voir apparaître le message “Back4app rocks !

Points de vue

Le frontend aura les points d’extrémité suivants :

  1. / affiche le tableau des dépenses et des statistiques de dépenses
  2. /add/ affiche un formulaire permettant d’ajouter une nouvelle dépense
  3. /delete/ / affiche une confirmation de la suppression d’une dépense

Pour mettre en œuvre ces points finaux, créez la structure de répertoire suivante :

src/
├── add/
│   └── page.js
└── delete/
    └── [objectId]/
        └── page.js

En outre, créez le dossier des composants avec Container.js et Header.js:

src/
└── components/
    ├── Container.js
    └── Header.js

Collez ce qui suit dans Container.js:

// src/app/components/Container.js

const Container = ({children}) => {
  return (
    <div className="container mx-auto px-4 sm:px-6 lg:px-8">
      {children}
    </div>
  )
}

export default Container;

Et faites de même pour Header.js:

// src/app/components/Header.js

import Container from "@/app/components/Container";
import Link from "next/link";

const Header = () => {
  return (
    <Container>
      <div className="py-4">
        <Link href="/">
          <div 
            className="text-2xl font-semibold text-indigo-500 hover:text-indigo-700"
          >
            back4app-postgres
          </div>
        </Link>
      </div>
    </Container>
  )
}

export default Header;

Utilisez Container.js et Header.js dans layout.js comme suit :

// src/app/layout.js

"use client";

import {Inter} from "next/font/google";
import "./globals.css";
import Header from "@/app/components/Header";
import Container from "@/app/components/Container";

const inter = Inter({ subsets: ["latin"] });

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <Header/>
        <Container>
          {children}
        </Container>
      </body>
    </html>
  );
}

Enfin, collez le code de la vue dans les fichiers correspondants :

  1. src/app/page.js
  2. src/app/add/page.js
  3. src/app/delete/[objectId]/page.js

Relancez le serveur de développement et visitez http://localhost:3000 dans votre navigateur. Vous devriez voir quelque chose de similaire à ceci :

Back4app App Postgress

En cliquant sur le bouton “Ajouter une dépense”, vous serez redirigé vers le formulaire d’ajout de dépenses.

Parse SDK

Il y a plusieurs façons de se connecter à un backend Back4app :

  1. API RESTful
  2. API GraphQL
  3. Parse SDK

Nous opterons pour cette dernière solution, car c’est la plus robuste et la plus simple à mettre en œuvre.

Parse SDK est un ensemble d’outils pratiques pour interroger les données, les gérer, exécuter des fonctions Cloud Code, etc.

Il est disponible pour de nombreux langages de programmation et frameworks, tels que JavaScript, PHP, Flutter et Objective-C.

Commencez par installer Parse via npm :

$ npm install parse

Pour utiliser Parse dans nos vues React, nous devons d’abord l’initialiser. Mais avant cela, nous allons créer un contexte React, ce qui nous permettra de passer l’instance de Parse à toutes nos vues.

Créez un dossier context dans le dossier src/app, et un fichier parseContext.js dans ce dossier :

import {createContext} from "react";

const ParseContext = createContext();

export default ParseContext;

Ensuite, initialisez Parse dans layout.js et enveloppez toute l’application avec ParseContext.Provider comme suit :

// src/app/layout.js

import Parse from "parse/dist/parse";
import ParseContext from "@/app/context/parseContext";

Parse.initialize(
  "<your_parse_application_id>",
  "<your_parse_javascript_key>",
);
Parse.serverURL = "https://parseapi.back4app.com/";

export default function RootLayout({ children }) {
  return (
    <ParseContext.Provider value={Parse}>
      <html lang="en">
        // ...
      </html>
    </ParseContext.Provider>
  );
}

Veillez à remplacer <your_parse_application_id> et <your_parse_javascript_key> par vos véritables clés. Pour les obtenir, accédez à votre tableau de bord Back4app et sélectionnez “Paramètres de l’application > Sécurité et clés” dans la barre latérale.

Clés API de Back4app

Nous pouvons maintenant obtenir l’instance Parse dans nos vues comme suit :

const parse = useContext(ParseContext);

Ensuite, modifiez légèrement les vues pour invoquer les méthodes Parse.

src/app/page.js:

// src/app/page.js

export default function Page() {

  // ...

  const parse = useContext(ParseContext);

  const fetchExpenses = () => {
    const query = new parse.Query("Expense");
    query.find().then((fetchedExpenses) => {
      const expenses = fetchedExpenses.map(expense => ({
        objectId: expense.id,
        name: expense.get("name"),
        description: expense.get("description"),
        price: expense.get("price"),
        createdAt: expense.get("createdAt"),
      }));
      setExpenses(expenses);
      console.log("Expenses fetched successfully.");
    }).catch((error) => {
      console.error("Error while fetching expenses:", error);
    });
  }

  const fetchStatistics = () => {
    parse.Cloud.run("getStatistics").then((statistics) => {
      setStatistics(statistics);
      console.log("Statistics fetched successfully.");
    }).catch((error) => {
      console.error("Error while fetching statistics:", error);
    });
  }

  // ...
}

src/app/add/page.js:

// src/app/add/page.js

export default function Page() {

  // ...

  const parse = useContext(ParseContext);

  const onAddClick = () => {
    const Expense = parse.Object.extend("Expense");
    const expense = new Expense();

    expense.set("name", name);
    expense.set("description", description);
    expense.set("price", parseFloat(price));

    expense.save().then((expense) => {
        console.log("Expense created successfully with objectId: ", expense.id);
        router.push("/");
      }, (error) => {
        console.error("Error while creating expense: ", error);
      }
    );
  }

  const onCancelClick = () => {
    router.push("/");
  }

  // ...
}

src/app/delete/[objectId]/page.js:

// src/app/delete/[objectId]/page.js

export default function Page() {

  // ...

  const parse = useContext(ParseContext);

  const onDeleteClick = () => {
    const Expense = parse.Object.extend("Expense");
    const query = new parse.Query(Expense);

    query.get(objectId).then((expense) => {
      return expense.destroy();
    }).then((response) => {
      console.log("Expense deleted successfully");
      router.push("/");
    }).catch((error) => {
      console.error("Error while deleting expense: ", error);
    });
  }

  const onCancelClick = () => {
    router.push("/");
  }

  // ...
}

N’oubliez pas les importations en tête de fichier :

import {useContext} from "react";
import ParseContext from "@/app/context/parseContext";

C’est bien, c’est tout.

Votre frontend est maintenant connecté au backend. Si vous visitez l’application dans votre navigateur, vous devriez voir que les données sont chargées correctement depuis le backend. Toutes les modifications apportées au frontend sont maintenant reflétées dans le backend.

Dockerize

Back4app Containers étant une plateforme CaaS, votre projet doit être dockerisé avant d’être déployé. La méthode recommandée pour dockeriser votre projet est d’utiliser un fichier Docker.

Un fichier Docker est un script qui fournit des instructions pour créer une image de conteneur.

Créer un fichier Docker à la racine du projet :

# Dockerfile

FROM node:18

WORKDIR /app
COPY package*.json ./

RUN npm ci

COPY . .

RUN npm run build
RUN npm install -g next

EXPOSE 3000

CMD ["next", "start", "-p", "3000"]

Ce fichier Docker utilise l’image node:18-alpine, établit le répertoire de travail, gère les dépendances, copie le projet et construit l’application.

Une fois terminé, il expose le port 3000 et lance un serveur Next.js pour écouter sur ce port.

Ensuite, créez un fichier .dockerignore pour minimiser la taille de l’image :

# .dockerignore

.idea/

node_modules/
.next/
/out/
build/

.vercel

Les fichiers .dockerignore fonctionnent de la même manière que les fichiers .gitignore.

Assurez-vous que tout fonctionne en construisant et en exécutant l’image localement :

$ docker build -t back4app-postgres:1.0 .
$ docker run -it -p 3000:3000 back4app-postgres:1.0

Ouvrez votre navigateur web et naviguez vers http://localhost:3000. L’application web devrait encore être pleinement fonctionnelle.

Pousser vers le VCS

Pour déployer votre code dans Back4app Containers, vous devez le pousser sur GitHub.

  1. Connectez-vous à votre compte GitHub.
  2. Créer un nouveau dépôt.
  3. Copiez l’URL de l’origine distante — par exemple [email protected]:duplxey/repo.git.
  4. Initialiser le dépôt Git : git init
  5. Ajouter le serveur distant : git remote add origin
  6. Ajouter tous les fichiers : git add .
  7. Créer un commit : git commit -m "project init"
  8. Pousser le code source : git push origin main

Ouvrez votre navigateur web préféré et assurez-vous que tout le code a été ajouté au référentiel.

Déployer le code

Maintenant que l’application est dockerisée et hébergée sur GitHub, nous pouvons enfin la déployer.

Naviguez vers votre tableau de bord Back4app et cliquez à nouveau sur le bouton “Construire une nouvelle application”.

Back4app Build New App

Sélectionnez “Containers as a Service” puisque nous déployons une application dockerisée.

Back4app Containers as a Service

Si c’est la première fois que vous travaillez avec Back4app Containers, vous devez lier votre GitHub à votre compte Back4app.

Lorsque vous choisissez les dépôts auxquels Back4app a accès, assurez-vous d’autoriser l’accès au dépôt créé à l’étape précédente.

Ensuite, il faut “sélectionner” le référentiel.

Back4app Select Repository

Les conteneurs Back4app vous permettent de configurer les paramètres de déploiement tels que le port, le déploiement automatique, les variables environnementales et les contrôles de santé.

Comme notre application est simple, nous devons fournir un nom et nous pouvons garder tout le reste par défaut.

Back4app Configure Deployment

Lorsque vous cliquez sur “Créer une application”, Back4app extrait le code de GitHub, construit l’image Docker, l’envoie au registre des conteneurs et la déploie.

Après quelques instants, votre application sera disponible à l’URL de la barre latérale.

Déploiement réussi de Back4app

Conclusion

Dans cet article, vous avez appris ce qu’est PostgreSQL, les différences entre les bases de données SQL et NoSQL, et comment déployer une application web soutenue par Postgres sur Back4app.

Pour tester votre compréhension, je vous propose de mettre en œuvre certaines de ces idées :

  • Authentification de l’utilisateur
  • Au lieu d’avoir un budget global, faites-le reposer sur l’utilisateur.
  • Ajouter un domaine personnalisé à l’application Back4app Containers

Obtenir le code source final depuis le repo de back4app-postgres.


Leave a reply

Your email address will not be published.