Come ospitare frontend e backend?

Back4app Copertura per la distribuzione di applicazioni full stack

In questo tutorial, forniremo una guida completa sull’hosting di un frontend e di un backend di un’applicazione.

A questo scopo, ospiteremo un’applicazione full-stack su Back4app. Lavoreremo prima sul backend, poi passeremo al frontend e infine collegheremo i due componenti.

Obiettivi

Alla fine di questo articolo, sarete in grado di:

Quali sono le differenze tra frontend e backend?

Il backend e il frontend si riferiscono alla separazione delle preoccupazioni nella costruzione di moderne applicazioni web e mobili. Il modo più semplice per comprenderne le differenze è visualizzare un iceberg.

Backend vs Frontend

Il frontend (o lato client) è tutto ciò che l’utente può vedere e con cui può interagire. I frontend sono disponibili in vari formati, come applicazioni mobili, applicazioni web, interfacce web o qualsiasi altro tipo di client.

Questa parte dell’applicazione è responsabile di UI/UX, design, animazioni, grafica e altri tipi di media. Il lato client costituisce il 20% del lavoro del progetto e non è ripetitivo.

D’altra parte, il backend (o lato server) è tutto ciò che l’utente non può vedere. È il ponte tra il frontend e il database.

È responsabile della logica aziendale, delle attività in background, dell’archiviazione dei dati, della scalabilità, delle integrazioni con terze parti e così via. Anche se l’utente non può interagire direttamente con esso, ha comunque un forte impatto sulla qualità di un’applicazione.

Rappresenta circa l’80% del lavoro del progetto e spesso include attività ripetitive come la gestione degli utenti, l’autenticazione, la crittografia, ecc.

Potete distribuire le vostre applicazioni frontend e backend su varie piattaforme. Nella tabella seguente ho riassunto alcune delle mie preferite:

Piattaforme di frontendPiattaforme backend
Contenitori Back4appBack4app
VercelRender
NetlifyHeroku
Pagine GitHubLinode

In questo tutorial, imparerete come distribuire il vostro frontend e backend su Back4app — gratuitamente! Continuate a leggere per imparare a distribuire backend e frontend.

Introduzione al progetto

Ho preparato un’applicazione full-stack per dimostrare come distribuire un frontend e un backend su Back4app.

L’applicazione funge da semplice blog in markdown. Gli amministratori possono aggiungere, modificare e cancellare articoli, mentre gli utenti possono leggerli.

Il progetto finale avrà un aspetto simile a questo:

Back4app Blog sulle app full-stack

Come già detto, l’applicazione è composta da due parti: il frontend e il backend. Se visualizziamo l’architettura dell’applicazione, l’aspetto è simile a questo:

Back4app Architettura dell'app full-stack

Distribuiremo il backend su Back4app e l’applicazione frontend su Back4app Containers. Infine, collegheremo i due componenti tramite Parse SDK.

Vi suggerisco di seguire prima questa applicazione e poi di verificare le vostre conoscenze distribuendo le vostre applicazioni full-stack.

Continuate a leggere per scoprire come ospitare il backend e il frontend.

Come ospitare un backend?

In questa sezione ci occuperemo della parte backend dell’applicazione.

Obiettivi

  1. Creare un’applicazione Back4app
  2. Definire le classi del database
  3. Impostazione delle ACL/CLP del database
  4. Popolare il database
  5. Abilitare l’applicazione Admin

Creare l’applicazione Back4app

Per seguirci è necessario un account Back4app gratuito. Se non sei ancora registrato, iscriviti gratuitamente!

Per lavorare con Back4app, è necessario creare un’applicazione. Una volta effettuata l’autenticazione su Back4app, si verrà reindirizzati alla visualizzazione dell’applicazione. Fare clic sul pulsante “Crea nuova applicazione”.

Back4app Crea app

Quindi, selezionare “Backend as a Service”, poiché stiamo distribuendo un backend.

Back4app Backend as a Service

Dare un nome all’applicazione, selezionare il database “NoSQL” e fare clic su “Crea”.

Configurazione di Back4app BaaS

La piattaforma richiederà un po’ di tempo per preparare tutto (ad esempio, database, scaling, backup, livello applicativo). Sentitevi liberi di fare una breve pausa caffè nel frattempo.

Una volta che la vostra applicazione è pronta, vi verrà presentato l’esploratore di database.

Vista del database di Back4app

Definire il database

In questa sezione, lavoreremo sulle classi del database.

Avremo bisogno di una sola classe, poiché stiamo costruendo un’applicazione semplice. Fare clic su “Crea una classe” nella barra laterale, assegnarle il nome Articolo, lasciare tutto il resto come predefinito e fare clic su “Crea classe e aggiungi colonne”.

Back4app Crea classe database

Aggiungete le seguenti cinque colonne:

+-----------+--------------+----------------+----------+
| Data type | Name         | Default value  | Required |
+-----------+--------------+----------------+----------+
| String    | slug         | <leave blank>  | 1        |
+-----------+--------------+----------------+----------+
| String    | title        | <leave blank>  | 1        |
+-----------+--------------+----------------+----------+
| File      | cover        | <leave blank>  | 0        |
+-----------+--------------+----------------+----------+
| String    | shortContent | <leave blank>  | 1        |
+-----------+--------------+----------------+----------+
| String    | content      | <leave blank>  | 1        |
+-----------+--------------+----------------+----------+

Assicurarsi di aggiungere le colonne per i dati aggiuntivi che si desidera memorizzare.

Per impostazione predefinita, le classi di database sono in “modalità protetta”. Se vogliamo interagire con esse dalla nostra applicazione frontend, dobbiamo modificare leggermente i permessi a livello di classe (CLP). Fare clic sull’icona del lucchetto nella parte superiore dello schermo e modificare le CLP in questo modo:

Back4app Classe CLP

Leggete il seguente articolo per saperne di più su Parse Security.

Infine, popolate il database con alcuni articoli di esempio.

Se non avete idee, importate pure il dump del database. Per importarlo, fare clic sull’opzione più in alto a destra dello schermo e poi su “Importa > Dati della classe”, quindi importare il JSON.

Database Back4app popolato

Eccellente, così!

Ora abbiamo alcuni dati di prova su cui lavorare.

App amministrativa

Attualmente, l’unico modo per gestire gli articoli è la visualizzazione del database di Back4app. Questo non è ottimale perché non si vogliono condividere le proprie credenziali Back4app o aggiungere persone non tecnologiche alla propria dashboard Back4app.

Fortunatamente, Back4app dispone di un’interfaccia di amministrazione dinamica per i modelli di database. Per attivarla, selezionare “Altro > Admin App” nella barra laterale, quindi fare clic su “Abilita Admin App”.

Back4app Abilita l'applicazione Admin

Scegliere un nome utente, una password e un sottodominio dell’app di amministrazione. Io sceglierò:

username:     admin
password:     verystrongpassword123
admin url:    https://fullstack.admin.back4app.com/

Ora è possibile accedere al pannello di amministrazione all’URL di amministrazione selezionato.

Aprire una nuova scheda e navigare nel pannello di amministrazione. Utilizzate le vostre credenziali per accedere ed esplorare l’interfaccia. È possibile creare un articolo, aggiornarlo e quindi eliminarlo.

Back4app Admin App Dashboard

Per saperne di più sull’Admin App di Back4app, consultate la documentazione.

Abbiamo creato con successo un backend completo senza codice.

Come ospitare un frontend?

In questa sezione ci occuperemo dell’applicazione frontend.

Obiettivi

  1. Impostare un ambiente di sviluppo locale
  2. Dockerizzare l’applicazione
  3. Testare le immagini Docker in locale
  4. Spingere il codice sorgente su GitHub
  5. Distribuire l’applicazione nei contenitori Back4app

Impostazione locale

Iniziare a fare il fork di tutti i rami di questo repository e poi clonare il fork sulla propria macchina locale:

$ git clone <fork_remote_git_url> --branch dummy
$ cd back4app-heroku-deploy && git branch -m master

Abbiamo clonato il ramo dummy perché non include il codice di backend. Lavoreremo sul codice del backend nella prossima sezione.

Quindi, installare le dipendenze del progetto:

$ npm install

Infine, avviare il server di sviluppo:

$ npm run dev

Aprite il vostro browser web preferito e visitate il sito http://localhost:3000. Dovreste essere in grado di vedere la pagina indice del blog. Provate a fare clic su un articolo per vedere se venite reindirizzati alla pagina dei dettagli dell’articolo.

Al momento la pagina dei dettagli dell’articolo è codificata in modo rigido. Non preoccupatevi, lo sistemeremo in seguito.

Dockerizzare

Per distribuire un’applicazione su Back4app Containers, è necessario prima dockerizzarla.

La dockerizzazione è il processo di impacchettamento del codice in un contenitore che può essere distribuito ovunque. Il modo più semplice per dockerizzare un’applicazione è usare un file Docker.

Profilo Docker

Uno script Dockerfile contiene le istruzioni per creare l’immagine di un contenitore Docker. È possibile usare questo file per definire l’ambiente, installare le dipendenze ed eseguire i comandi necessari per costruire ed eseguire un’applicazione.

Creare un file Docker nella root del progetto con i seguenti contenuti:

# Dockerfile

FROM node:18-alpine

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"]

Questo file Docker è basato sull’immagine node:18-alpine. Imposta la directory di lavoro, gestisce le dipendenze, copia il progetto e costruisce l’applicazione.

Una volta costruita, l’applicazione espone la porta 3000 e avvia un server Next.js in ascolto su quella porta.

Per saperne di più sui Dockerfiles, consultate i documenti ufficiali.

.dockerignore

Le dimensioni di un’immagine Docker devono essere ridotte al minimo. Il modo più semplice per ridurre le dimensioni di un’immagine Docker è creare un file .dockerignore. Questo file consente di specificare quali file e cartelle devono essere esclusi dall’immagine finale.

Ad esempio, non si vogliono includere i file IDE, build, .git o node_modules nell’immagine.

Ecco un esempio di file .dockerignore che si può utilizzare:

# .dockerignore

.idea/

/node_modules
/.next/
/out/
/build

.vercel

Assicurarsi di modificare il file .dockerignore in base alle proprie esigenze.

Costruire, eseguire, testare

È sempre una buona idea testare il progetto Docker in locale prima di inviarlo al cloud. Il modo più semplice per testare il vostro file Docker è installare Docker Desktop.

Una volta installato, è possibile creare l’immagine:

$ docker build -t blog-frontend:1.0 .

Elencare le immagini per vedere se l’immagine è stata creata correttamente:

$ docker images

REPOSITORY        TAG       IMAGE ID       CREATED             SIZE
blog-frontend     1.0       d361534a68da   2 minutes ago       1.08GB

Eseguire un contenitore usando l’immagine appena costruita:

$ docker run -p 3000:3000 --name blog-frontend blog-frontend:1.0

Aprite il vostro browser web preferito e visitate il sito http://localhost:3000. La vostra applicazione dovrebbe essere lì!

Per terminare il contenitore, premere CTRL + c sulla tastiera.

Spingere su GitHub

Back4pp Containers è strettamente integrato con GitHub. Fornisce un sistema CI/CD automatico che reimposta l’applicazione a ogni commit. Per distribuire il codice nella prossima sezione, è necessario prima inviare le modifiche al VCS.

Impegnare tutte le modifiche e inviarle al cloud:

$ git add .
$ git commit -m "dockerized the application"
$ git push origin master

Navigare nel proprio repo GitHub e assicurarsi che il file Docker sia presente nel repository.

Distribuire l’applicazione

Per seguirci è necessario un account Back4app gratuito. Se non sei ancora registrato, iscriviti gratuitamente!

Iniziate navigando nella dashboard di Back4app e cliccando su “Build new app”.

Back4app Crea applicazione

Poiché stiamo distribuendo un’applicazione dockerizzata, selezionare “Containers as a Service”.

Back4app Seleziona CaaS

Se è la prima volta che utilizzate Back4app Containers, vi verrà chiesto di collegare il vostro account GitHub con il vostro account Back4app. Assicuratevi di abilitare l’accesso a tutti i repository che desiderate distribuire.

Quindi, trovare il repository back4app-full-stack e selezionarlo facendo clic su “Seleziona”.

Back4app Seleziona il repository GitHub

L’applicazione che stiamo distribuendo non richiede alcuna configurazione particolare. Tutto ciò che si deve fare è fornire un “nome di app” descrittivo. Sceglierò back4app-full-stack per mantenere le cose organizzate.

Infine, fare clic su “Deploy”.

Ambiente dei contenitori Back4app

Back4app Containers impiegherà alcuni minuti per costruire e distribuire l’immagine Docker. Lo stato della vostra applicazione cambierà in “Ready” una volta che sarà stata distribuita con successo.

Per visitare l’applicazione, fare clic sull’URL verde come mostrato nell’immagine sottostante.

Distribuzione di successo di Back4app

Bene, avete distribuito con successo un’applicazione frontend fittizia su Back4app Containers.

Come collegare il frontend al backend?

In questa sezione, collegheremo il nostro frontend al backend di Back4app.

Obiettivi

  1. Installare l’SDK Parse
  2. Configurare l’SDK Parse
  3. Recuperare i dati (ad esempio, con ParseQuery)

Installare l’SDK Parse

Innanzitutto, installare Parse SDK:

$ npm install parse

Configurare l’SDK Parse

Per inizializzare Parse SDK, è necessario fornire l'”ID applicazione” e la “chiave JavaScript” di Back4app. Per ottenerli, navigare nell’applicazione Back4app e selezionare “Impostazioni dell’applicazione > Sicurezza e chiavi” nella barra laterale.

Poiché non vogliamo esporre questi segreti nel codice sorgente, creiamo un file .env.local:

# .env.local

NEXT_PUBLIC_PARSE_APPLICATION_ID=<your_parse_app_id>
NEXT_PUBLIC_PARSE_JAVASCRIPT_KEY=<your_parse_js_key>

Assicurarsi di sostituire i segnaposto con i valori reali.

Inizializzare l’SDK Parse

Quindi, spostarsi nel file providers.js e inizializzare Parse in questo modo:

// src/app/providers.js

// ...

import Parse from "parse/dist/parse";

const PARSE_APPLICATION_ID = process.env.NEXT_PUBLIC_PARSE_APPLICATION_ID;
const PARSE_JAVASCRIPT_KEY = process.env.NEXT_PUBLIC_PARSE_JAVASCRIPT_KEY;
Parse.initialize(PARSE_APPLICATION_ID, PARSE_JAVASCRIPT_KEY);
Parse.serverURL = "https://parseapi.back4app.com/";

export function Providers({children}) {
    return (
        // ...
    );
}

Per poter accedere all’istanza di Parse in tutte le nostre viste. Utilizzeremo il contesto di React.

Creare un nuovo file denominato context/parseContext.js e incollarvi il seguente codice:

// src/app/context/parseContext.js

"use client";

import {createContext} from "react";

const ParseContext = createContext();

export default ParseContext;

Quindi, avvolgere l’intera applicazione con il ParseContext e fornirgli l’istanza di Parse:

// src/app/providers.js

// ...

import ParseContext from "@/app/context/parseContext";

export function Providers({children}) {
  return (
    <CacheProvider>
      <ColorModeScript initialColorMode={theme.config.initialColorMode} />
      <ChakraProvider theme={theme}>
        <ParseContext.Provider value={Parse}>
          {children}
        </ParseContext.Provider>
      </ChakraProvider>
    </CacheProvider>
  );
}

Ecco fatto! Ora possiamo accedere all’istanza di Parse utilizzando l’hook useContext().

Recuperare i dati

L’ultima cosa da fare è recuperare i dati dal backend. Per farlo, utilizzeremo Parse.Query. Questa classe è fondamentalmente un ORM per i database basati su Parse.

Per prima cosa, sostituire src/app/page.jsx con il seguente:

// src/app/page.jsx

"use client";

import NextLink from "next/link";
import {useContext, useEffect, useState} from "react";
import ParseContext from "@/app/context/parseContext";
import {Card, CardBody, Heading, Link, Spinner, Stack, Text} from "@chakra-ui/react";

export default function Home() {

  const parse = useContext(ParseContext);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  const [articles, setArticles] = useState([]);

  useEffect(() => {
    (async () => {
      try {
        const query = new parse.Query("Article");
        query.descending("createdAt");
        const articles = await query.find();
        setArticles(articles);
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    })();
  }, [parse.Query]);

  if (loading) {
    return <Spinner size="lg"/>;
  }

  if (error) {
    return <Text color="red">{error}</Text>;
  }

  return (
    <>
      <Stack>
        {articles.map((article) => (
          <Card key={article.get("slug")}>
            <CardBody>
              <Stack>
                <Heading size="lg">
                  <Link as={NextLink} href={article.get("slug")}>
                    {article.get("title")}
                  </Link>
                </Heading>
                <Text>{article.get("shortContent")}</Text>
              </Stack>
            </CardBody>
          </Card>
        ))}
      </Stack>
    </>
  );
}
  1. Abbiamo ottenuto l’istanza di Parse tramite l’hook useContext().
  2. Abbiamo creato alcuni stati, tra cui caricamento, errore e articoli.
  3. Abbiamo usato il gancio useEffect() per eseguire Parse.Query all’apertura della pagina.
  4. Parse.Query recupera tutti gli articoli ordinati per createdAt.
  5. Abbiamo modificato l’istruzione return per rendere i dati.

Quindi sostituire src/app/[slug]/page.js con questo:

// src/app/[slug]/page.js

"use client";

import {formatDate} from "@/app/util/date-util";
import {useContext, useEffect, useState} from "react";
import ParseContext from "@/app/context/parseContext";
import {Card, CardBody, Heading, Image, Spinner, Stack, Text} from "@chakra-ui/react";
import ReactMarkdown from "react-markdown";
import ChakraUIRenderer from "chakra-ui-markdown-renderer";

export default function Article({params}) {

  const parse = useContext(ParseContext);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  const [article, setArticle] = useState(null);

  useEffect(() => {
    (async () => {
      try {
        const query = new parse.Query("Article");
        query.equalTo("slug", params.slug);
        const article = await query.first();
        if (!article) {
          setError("This article does not exist.");
        } else {
          setArticle(article);
        }
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    })();
  }, [params.slug, parse.Query]);

  if (loading) {
    return <Spinner size="lg"/>;
  }

  if (error) {
    return <Text color="red">{error}</Text>;
  }

  return (
    <>
      {article && (
        <Stack>
          <Card>
            <CardBody>
              <Stack>
                <Heading as="h2" size="lg">{article.get("title")}</Heading>
                <Text>Posted on {formatDate(article.get("createdAt"))}</Text>
                {article.get("cover") && (
                  <Image 
                      src={article.get("cover").url()} 
                      alt={`${article.get("title")} cover`} 
                      borderRadius="lg"
                  />
                )}
                <ReactMarkdown 
                    components={ChakraUIRenderer()} 
                    children={article.get("content")} 
                    skipHtml
                />
              </Stack>
            </CardBody>
          </Card>
        </Stack>
      )}
    </>
  );
}

Abbiamo utilizzato gli stessi concetti del codice precedente. La differenza principale tra i due frammenti di codice è che in questo caso stiamo recuperando un articolo specifico invece di tutti.

E il gioco è fatto! Procedete a testare il progetto in locale:

$ next dev

Una volta che si è sicuri che tutto funzioni, si può fare il push al VCS:

$ git add .
$ git commit -m "connected the frontend with the backend"
$ git push origin master

Back4app Containers distribuirà automaticamente l’applicazione con le ultime modifiche.

Conclusione

In conclusione, abbiamo distribuito con successo un’applicazione full-stack su Back4app. Grazie a questo processo, avete acquisito una preziosa esperienza nell’ospitare il frontend e il backend di un’applicazione. Ora non dovreste avere problemi a distribuire le vostre applicazioni full-stack.

Il codice sorgente finale è disponibile sul repo back4app-full-stack e si è appreso dove ospitare frontend e backend.


Leave a reply

Your email address will not be published.