Tutorial

Cómo crear una aplicación de citas inspiradoras con AdonisJs y MySQL

MySQLDevelopmentJavaScript

El autor seleccionó el Tech Education Fund para que recibiese una donación como parte del programa Write for DOnations.

Introducción

AdonisJs es un marco web simple de Node.js escrito en JavaScript que funciona en los principales sistemas operativos. Utiliza el popular patrón de diseño MVC (modelo-vista-controlador) y ofrece un ecosistema estable para escribir aplicaciones web del lado del servidor. El marco presenta características de autenticación sin inconvenientes, SQL ORM (mapeo de objetos a datos relacionales), migraciones y propagación de bases de datos. AdonisJs tiene una arquitectura similar a la del marco PHP de aplicaciones web Laravel e incluye la misma estructura de carpeta y varios conceptos de configuración compartidos.

Por defecto, AdonisJs usa el motor de plantillas de Edge que está diseñado para usarse de forma intuitiva. Al igual que Laravel, AdonisJs incluye una ORM llamada Lucid que sirve como interfaz para la comunicación entre los modelos de una aplicación y la base de datos. Con AdonisJs, los desarrolladores pueden crear una aplicación completa en la que el servidor de backend se encargará de aplicar la lógica de negocios, realizar direccionamientos y mostrar todas las páginas de la aplicación. También es posible crear una API de servicio web para mostrar respuestas de JSON desde un controlador; estos servicios web pueden utilizarse en frameworks de frontend, como Vue.js, React y Angular.

En este tutorial, creará una aplicación con AdonisJs usando su CLI. Creará rutas, controladores, modelos y vistas en su aplicación, y ejecutará validaciones de formularios. El ejemplo de este tutorial será una aplicación de citas inspiradoras en la que un usuario puede registrarse e iniciar sesión para crear una cita inspiradora. Esta aplicación de prueba le dará la oportunidad de realizar operaciones CURD (crear, leer, actualizar y norrar").

Requisitos previos

Para comenzar a seguir los pasos de esta guía, necesitará lo siguiente:

Nota: En este tutorial se usa una máquina macOS para el desarrollo. Si usa otro sistema operativo, es posible que deba usar sudo para comandos npm en los primeros pasos.

Paso 1: Instalar Adonis CLI

En esta sección, instalará Adonis CLI y todos sus paquetes necesarios en su máquina local. El CLI le permitirá escribir un nuevo proyecto AdonisJs, así como crear y generar código estándar para los controladores, los middlewares y los modelos de su aplicación. También creará su base de datos para el proyecto.

Ejecute el siguiente comando para instalar AdonisJs CLI de forma global en su máquina a través de npm:

Una vez que se complete el proceso de instalación, ingrese el siguiente comando en la terminal para confirmar la instalación de AdonisJs y ver la versión actual:

  • adonis --version

Verá un resultado que mostrará la versión actual de AdonisJs:

Output
4.1.0

Con la instalación correcta de AdonisJs CLI, ahora tendrá acceso al comando adonis y podrá usarlo para crear nuevas instalaciones de un proyecto de AdonisJs, administrar su proyecto y generar archivos pertinentes, como controladores y modelos, entre otros.

Ahora, puede proceder a crear un nuevo proyecto de AdonisJs usando el comando adonis como se muestra aquí:

  • adonis new adonis-quotes-app

Con el comando anterior se creará una aplicación llamada adonis-quotes-app en un nuevo directorio con el mismo nombre del directorio de su proyecto local, con la estructura MVC pertinente de AdonisJs.

Diríjase a la nueva carpeta de la aplicación:

  • cd adonis-quotes-app

Luego, inicie su aplicación ejecutando lo siguiente:

  • adonis serve --dev

Esto iniciará el servidor de desarrollo en el puerto predeterminado 3333, como se especifica dentro del archivo root .env para su aplicación. Diríjase a http://localhost:3333 para ver la página de bienvenida de AdonisJs.

Página de bienvenida de AdonisJs

A continuación, completará la configuración de su base de datos. Aquí, instalará el controlador mysql para establecer conexión con su servidor de MySQL desde su aplicación de Node.js a través de npm. Para comenzar, vuelva a su terminal, donde la aplicación esté actualmente en ejecución, detenga el proceso con CTRL + C y ejecute el siguiente comando:

  • npm i mysql

Ahora que ha instaló correctamente el controlador de Node.js de MySQL para esta aplicación, deberá crear la base de datos de la aplicación y configurar la conexión correspondiente.

En la última versión de MySQL que instaló en el tutorial de los requisitos previos se utiliza un complemento de autenticación predeterminado llamado caching_sha2_password. Actualmente, esta no es compatible con los controladores de Node.js de MySQL. Para evitar cualquier problema de conexión de la base de datos de su aplicación, deberá crear un nuevo usuario de MySQL y usar el complemento de autenticación que se admite actualmente: mysql_native_password.

Para comenzar, acceda al cliente MySQL usando la cuenta root:

  • mysql -u root -p

Se le solicitará ingresar la contraseña de su cuenta root configurada durante la instalación de MySQL.

Luego, cree el usuario y la contraseña usando el complemento mysql_native_password:

  • CREATE USER 'sammy'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

Verá lo siguiente:

Output
Query OK, 0 rows affected (0.02 sec)

Luego, cree una base de datos para la aplicación con lo siguiente:

  • CREATE DATABASE adonis;

Verá lo siguiente:

Output
Query OK, 1 row affected (0.03 sec)

Con esto, habrá creado con éxito la base de datos para esta aplicación.

Ahora, habilite el acceso a la base de datos creada para el nuevo usuario de MySQL. Ejecute el siguiente comando para conceder todos los privilegios al usuario en la base de datos:

  • GRANT ALL PRIVILEGES ON adonis.* TO 'sammy'@'localhost';

Vuelva a cargar las tablas de concesión ejecutando el siguiente comando para aplicar los cambios que acaba de realizar:

  • FLUSH PRIVILEGES;

Verá lo siguiente:

Output
Query OK, 0 rows affected (0.00 sec)

Cierre el cliente MySQL con lo siguiente:

  • quit;

Instaló el AdonisJs CLI, creó un nuevo proyecto de AdonisJs e instaló mysql​​​​ a través de npm con éxito. También creó la base de datos para esta aplicación y configuró un usuario MySQL con los privilegios correspondientes. Esta es la configuración básica para su aplicación y, en la siguiente sección, comenzará a crear las vistas necesarias para ella.

Paso 2: Usar el motor de creación de plantillas Edge

AdonisJs se envía con su propio motor de plantillas llamado Edge. Le permite crear una plantilla HTML reutilizable y permite la introducción de lógica de frontend en su aplicación con un volumen de código mínimo. Edge proporciona a los desarrolladores de JavaScript las herramientas mientras desarrollan una aplicación para crear un diseño basado en componentes, escribir condicionales, usar iteraciones y crear diseños de vista para contener lógicas. Todos los archivos de plantilla llevan la extensión .edge y se almacenan en el directorio resources/views.

Las siguientes son las vistas que su aplicación necesitará para funcionar correctamente:

  • Diseño maestro: con Edge, puede crear una página que contendrá el CSS, los archivos de JavaScript comunes, jQuery y partes comunes de la interfaz de usuario que se mantendrán sin cambios en toda la aplicación; por ejemplo, la barra de navegación, el logo y el encabezado. Una vez que haya establecido la página de diseño maestro, otras vistas (páginas) en su aplicación la heredarán.
  • Vista de índice: esta página usará el diseño maestro para heredar archivos comunes y también mostrará el contenido de la página de inicio de la aplicación.
  • Página de inicio de sesión: en esta página también se usará el diseño maestro y se mostrará el formulario con los campos de entrada para el nombre de usuario y la contraseña, para que los usuarios inicien sesión.
  • Página de registro: en ella, los usuarios verán un formulario para registrarse y sus datos se guardarán en la base de datos.
  • Página de creación de citas: los usuarios usarán esta página para crear una cita inspiradora.
  • Página de edición de citas: los usuarios usarán esta página para editar una cita.
  • Página de visualización de citas: los usuarios usarán esta página para ver una cita en particular.

Para comenzar, utilice el comando adonis para crear la página de diseño maestro ejecutando el siguiente comando:

  • adonis make:view layouts/master

Visualizará un resultado similar al siguiente:

Output
✔ create resources/views/layouts/master.edge

Este comando creará automáticamente un archivo master.edge en su carpeta resources/views/layouts. Abra el nuevo archivo:

  • nano resources/views/layouts/master.edge

Añádale el siguiente código:

/resources/views/layouts/master.edge
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>adonis-quotes-app</title>
    {{ style('https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css') }}
    {{ style('style') }}
    {{ script('https://code.jquery.com/jquery-3.3.1.slim.min.js') }}
</head>
<body>
    <div class="container-fliud">
        @include('navbar')
        @!section('content')
    </div>
    {{ script('https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js') }}

</body>
</html>

En este archivo, incluya los archivos de CDN para Bootstrap CSS, Bootstrap JavaScript y jQuery. Se agrega un nombre de archivo CSS global style.css y, dentro del div, se incluye un archivo partial llamado navbar. Para volver a la utilizar los fragmentos de código HTML que necesita en varias páginas de su aplicación, como nav o footer, puede incorporar parciales. Estos son archivos más pequeños que contienen el código repetido y agilizan su actualización para estos elementos en un lugar, en vez de hacerlo en cada instancia en la que aparece. La navbar contiene marcado para los botones de Login y Register, un logo y un enlace de inicio.

Una vez hecho esto, todas las páginas posteriores que se crearán para esta aplicación pueden extender el diseño maestro y mostrar la navbar sin la necesidad de volver a escribir el contenido. Creará este archivo navbar más tarde en el tutorial.

Por último, se define una etiqueta de sección @! section() para incluir contenido de otras páginas y que el diseño maestro las muestre. Para que esto funcione como se espera, todas las nuevas páginas que ampliarán el diseño maestro también deben definir una etiqueta de sección con el mismo nombre (es decir, @section('content')).

Guarde y cierre el archivo una vez que termine de editarlo.

Luego, use el comando adonis para crear la barra de navegación:

  • adonis make:view navbar

Verá un resultado similar a lo siguiente:

Output
✔ create resources/views/navbar.edge

Abra el archivo recién creado:

  • nano resources/views/navbar.edge

Luego, añádale el siguiente código:

/resources/views/navbar.edge
<nav class="navbar navbar-expand-lg navbar-dark text-white">
    <a class="navbar-brand" >LOGO</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
            <li class="nav-item active ">
                <a class="btn text-white" href="/">Home</a>
            </li>
        </ul>
    </div>
    <div class="navbar-right" id="navbarNav">
        @loggedIn
            <ul class="navbar-nav">
                    <li>
                        <div class="text-right">
                             <a href="{{route('create.quote')}}" class="btn btn-outline-primary">Create Quote</a>
                        </div>
                    </li>

                <li class="nav-item dropdown">
                    <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                       {{ auth.user.username}}
                    </a>
                    <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
                        <form method="POST" action="{{route('logout')}}">
                            {{ csrfField() }}
                              <button  type="submit" class="dropdown-item" href="">logout</button>
                        </form>
                    </div>
                </li>
            </ul>
        @else
            <ul class="navbar-nav">
                <li class="nav-item active pr-2">
                    <a href="{{route('login.create')}}" class="btn btn-outline-danger">
                      login
                    </a>
                </li>
                <li class="nav-item active pr-2">
                    <a href="{{route('register.create')}}" class="btn btn-outline-primary">
                        Register
                    </a>
                </li>
            </ul>
        @endloggedIn
    </div>
</nav>

Además de definir los enlaces a la página de inicio de sesión y los botones para registrarse e iniciar sesión, añada la etiqueta @loggedIn. Después de hacer hecho esto, puede escribir una instrucción condicional para el usuario autenticado y mostrar los contenidos apropiados cuando sea necesario. Para un usuario autenticado, la aplicación mostrará su nombre de usuario y un botón para crear una nueva cita. Si el usuario no inició sesión, su aplicación mostrará un botón para hacerlo o para registrarse. Esta página se incluirá como parcial en cada página, al igual que en el diseño maestro anterior de esta aplicación.

Guarde el archivo y ciérrelo.

Ahora, deberá crear la página de índice que usará para la página de inicio de la aplicación. Esta brindará y mostrará la lista de todas las citas inspiradoras que los usuarios escriban:

  • adonis make:view index

Visualizará un resultado similar al siguiente:

Output
✔ create resources/views/index.edge

El archivo creado aquí estará ubicado en resources/views/index.edge. Abra el archivo:

  • nano resources/views/index.edge

Luego, añada el siguiente código:

/resources/views/index.edge
@layout('layouts/master')
@section('content')

<div class="container">
    <div class="text-center">
        @if(flashMessage('successmessage'))
            <span class="alert alert-success p-1">{{ flashMessage('successmessage') }}</span>
        @endif
    </div>
    <div class="row">
        @each(quote in quotes)
            <div class="col-md-4 mb-4 quote-wrapper">
                <a href="/view-quote/{{quote.id}}" class="w-100">
                    <div class="card shadow-lg bg-dark text-white">
                        <div class="card-body">
                            <blockquote class="blockquote mb-0">
                                <p>{{quote.body}}</p>
                                <footer class="blockquote-footer">
                                    <cite title="Source Title"> {{quote.username}}</cite>
                                </footer>
                            </blockquote>
                            @if(auth.user.id == quote.user_id)
                              <div>
                                <a  href="/edit-quote/{{quote.id}}" class="btn btn-primary">edit</a>
                                <a href="/delete-quote/{{quote.id}}" class="btn btn-danger">delete</a>
                              </div>
                            @endif
                        </div>
                    </div>
                </a>
            </div>
        @else
         <div class="col-md-12 empty-quote text-center">
                <p>No inspirational quote has been created</p>
         </div>
        @endeach
    </div>
</div>
@endsection

Aquí, debe indicar que esta vista usará el diseño master extendiéndolo. Esta página ahora tendrá acceso a todas las bibliotecas, las hojas de estilos y la navbar​​ incluida en el diseño master. Luego, debe iterar la matriz de quotes​​​ usando la etiqueta integrada @each. La matriz de quotes pasará a esta vista desde el QuoteController que creará más tarde en este tutorial. Si no hay citas, se mostrará un mensaje apropiado.

Guarde este archivo y ciérrelo.

Para crear la página de inicio de sesión, ejecute el siguiente comando desde la terminal:

  • adonis make:view auth/login

Verá un resultado similar a este:

Output
✔ create resources/views/auth/login.edge

Esto creará automáticamente una carpeta auth dentro de resources/views y también un archivo login.edge dentro de ella. Abra el archivo login.edge:

  • nano resources/views/auth/login.edge

Añada el siguiente contenido:

/resources/views/auth/login.edge
@layout('layouts/master')
@section('content')
  <div class="container">
    <div class="row">
      <div class="col-md-4 shadow bg-white mt-5 rounded offset-md-4">
        <form method="POST" action="{{route('login.store')}}">
          {{ csrfField() }}
            <div>
              @if(flashMessage('successmessage'))
                <span class="alert alert-success p-1">{{ flashMessage('successmessage') }}</span>
              @endif
            </div>
            <div class="form-group">
              <label for="email">Email address</label>
              <input type="email" class="form-control" id="email" name="email" value="{{old('email','')}}"  placeholder="Enter email">
              {{ elIf('<span class=text-danger>$self</span>', getErrorFor('email'), hasErrorFor('email')) }}
            </div>
            <div class="form-group">
              <label for="pasword">Password</label>
              <input type="password" class="form-control" id="password" name="password" value="{{old('password','')}}" placeholder="Password">
              {{ elIf('<span class=text-danger>$self</span>', getErrorFor('password'), hasErrorFor('password')) }}
            </div>

            <div class="text-center">
              <button type="submit" class="btn btn-primary">Submit</button>
            </div>
        </form>
      </div>
    </div>
  </div>
@endsection

Este archivo posee un formulario que contendrá elementos de entrada que se utilizarán a fin de recopilar el nombre de usuario y la contraseña de un usuario registrado para su correcta autenticación y comenzar a crear citas. Otro elemento importante que se debe tener en cuenta en esta página es {{ csrf Field()}. Es una variable global que AdonisJs usará para pasar el token de acceso CSRF al enviar una solicitud POST, PUT y DELETE desde su aplicación.

Esto se implementó para proteger su aplicación contra ataques de falsificación de petición en sitios cruzados (CSRF). Funciona generando un secreto de CSRF único para cada usuario que visite su sitio web y una vez que sus usuarios envían una solicitud HTTP del frontend, se genera un token secreto correspondiente que se pasa junto con la solicitud. Esto permitirá que el middleware creado para esta solicitud en AdonisJs verifique que el token y el secreto de CSRF sean válidos y pertenezcan al usuario autenticado.

Guarde y cierre el archivo una vez que termine.

Luego, cree la página de registro con este comando:

  • adonis make:view auth/register

Verá un resultado similar a este:

Output
✔ create resources/views/auth/register.edge

Ubique y abra el archivo recién creado en resources/views/auth/register.edge:

  • nano resources/views/auth/register.edge

Añada el siguiente código:

resources/views/auth/register.edge
@layout('layouts/master')
@section('content')
  <div class="container ">
    <div class="row">
        <div class="col-md-4  bg-white p-3 mt-5 shadow no-border rounded offset-md-4">
          <form method="POST" action="{{route('register.store')}}">
            {{ csrfField() }}
              <div class="form-group">
                <label for="name">Fullname</label>
                <input type="text" class="form-control" id="name" name="name"  value="{{old('name','')}}" placeholder="Enter Fullname">
                {{ elIf('<span class=text-danger>$self</span>', getErrorFor('name'), hasErrorFor('name')) }}
              </div>
              <div class="form-group">
                <label for="email">Email address</label>
                <input type="email" class="form-control" id="email"  name="email" value="{{old('email','')}}" placeholder="Enter email">
                {{ elIf('<span class=text-danger>$self</span>', getErrorFor('email'), hasErrorFor('email')) }}
              </div>
              <div class="form-group">
                <label for="pasword">Password</label>
                <input type="password" class="form-control" id="password" name="password" placeholder="Password">
                {{ elIf('<span class=text-danger>$self</span>', getErrorFor('password'), hasErrorFor('password')) }}
              </div>
              <div class="text-center">
                  <button type="submit" class="btn btn-primary">Submit</button>
              </div>
          </form>
        </div>
    </div>
  </div>
@endsection

De manera similar a lo que figura en la página de inicio de sesión, este archivo contiene un formulario HTML con campos de entrada para recopilar el name, el email y la password del usuario durante el proceso de registro. También se incluye el {{ csrfField()}}​​, debido que este se requiere para cada solicitud post de una aplicación de AdonisJs.

Guarde el archivo y ciérrelo.

Ahora, debe generar un nuevo archivo para crear una cita inspiradora ejecutando el siguiente comando desde la terminal:

  • adonis make:view quotes/create-quote

Verá un resultado como este:

Output
✔ create resources/views/quotes/create-quote.edge

Abra resources/views/quotes/create-quote.edge:

  • nano resources/views/quotes/create-quote.edge

Añada a este el siguiente contenido:

/resources/views/quotes/create-quote.edge
@layout('layouts/master')
@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-3"></div>
        <div class="col-md-6 shadow bg-white mt-5 rounded p-3">
            <div class="float-right">
                <a href="/" class="btn btn-outline-dark ">back</a>
            </div>
                <br>

            <div class="clear-fix"></div>
                <form method="POST" action="{{route('store.quote')}}">
                    {{ csrfField() }}
                    <div class="form-group">
                        <label for="quote">Create Quote</label>
                        <textarea type="text" rows="5"  name='body' id="body" class="form-control" id="quote" placeholder="Write an inspirational quote"></textarea>
                    </div>

                    <div class="text-center">
                        <button type="submit" class="btn btn-primary">Submit</button>
                    </div>
                </form>
            </div>
        </div>
        <div class="col-md-3"></div>
    </div>
</div>
@endsection

Esta página extiende el diseño maestro y contiene un formulario HTML con un elemento de área de texto que permite al usuario ingresar texto en varias filas antes de su publicación y su manipulación a través de la ruta correspondiente.

Guarde y cierre el archivo una vez que termine.

Luego, cree una página para editar una cita en particular. Ejecute el siguiente comando desde la terminal:

  • adonis make:view quotes/edit-quote

Verá lo siguiente:

Output
✔ create resources/views/quotes/edit-quote.edge

Abra el archivo con lo siguiente:

  • nano resources/views/quotes/edit-quote.edge

Añada el siguiente contenido a resources/views/quotes/edit-quote:

/resources/views/quotes/edit-quote.edge
@layout('layouts/master')
@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-6 shadow bg-white rounded p-3 offset-md-3">
            <div class="float-right">
                <a href="/" class="btn btn-outline-dark ">back</a>
            </div>
            <br>

            <div class="clear-fix"></div>
            <form method="POST" action="/update-quote/{{quote.id}}">
                {{ csrfField() }}
                <div class="form-group">
                    <label for="pasword">Edit Quote</label>
                    <textarea type="text" rows="5"  name='body' id="body" class="form-control" id="quote" placeholder="write the inspirational quote">{{quote.body}}</textarea>
                </div>
                <div class="text-center">
                    <button type="submit" class="btn btn-primary">Update</button>
                </div>

            </form>
        </div>
    </div>
</div>
@endsection

Esta página tiene contenido similar al del archivo create-quote.edge. La diferencia radica en que que contiene los detalles de una cita en particular que es necesario editar, <form method="POST" action="/update-quote/{{quote.id}}">​​​.

Guarde el archivo y ciérrelo.

Por último, genere una página para ver una única cita inspiradora:

  • adonis make:view quotes/quote

Verá un resultado similar a este:

Output
✔ create resources/views/quotes/quote.edge

Abra el archivo con lo siguiente:

  • nano resources/views/quotes/quote.edge

Añada el siguiente código:

/resources/views/quotes/quote.edge
@layout('layouts/master')
@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-6 offset-md-3">
            <div class="card shadow-lg bg-dark text-white">
                <div class="card-body">
                    <div class="float-right">
                        <a href="/" class="btn btn-outline-primary ">back</a>
                    </div>
                        <br>
                    <div class="clear-fix"></div>
                    <blockquote class="blockquote mb-0">
                        <p>{{quote.body}}</p>
                        <footer class="blockquote-footer">
                            <cite title="Source Title">{{quote.username}}</cite>
                        </footer>
                    </blockquote>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Esta página brinda los detalles de una cita en particular, que incluye el cuerpo de la cita, quote.body y el nombre del autor que la creó, quote.username.

Una vez que terme con el archivo, guárdelo y ciérrelo.

Creó todas las páginas necesarias para su aplicación usando el motor de plantillas Edge. Luego, configure y cree una conexión con la base de datos de su aplicación.

Paso 3: Crear un esquema de base de datos

Si utiliza su aplicación ahora, generará un error porque aún no conectó la aplicación con una base de datos. En esta sección, configurará una conexión a la base de datos y luego usará el comando adonis a fin de generar un archivo de migración que se usará para crear las tablas.

AdonisJs usa una ORM llamada Lucid ORM, que proporciona la implementación de active record para trabajar con su base de datos. Elimina la molestia de escribir consultas SQL que recuperan datos de la base de datos en tiempo real. Es especialmente útil cuando se trabaja en una aplicación compleja que requiere muchas consultas. Como ejemplo, puede recuperar todas las citas de su aplicación escribiendo lo siguiente:

const quotes = await Quote.all()

Para proceder con la configuración apropiada de la base de datos de su aplicación, asegúrese de estar aún posicionado en el directorio root de su aplicación y cree un archivo .env:

  • nano .env

Abra el archivo recién creado y añada el siguiente contenido:

.env
HOST=127.0.0.1
PORT=3333
NODE_ENV=development
APP_URL=http://${HOST}:${PORT}
CACHE_VIEWS=false
APP_KEY=bTVOEgUvmTCfkvgrK8gEBC3Qxt1xSYr0
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=sammy
DB_PASSWORD=password
DB_DATABASE=adonis
SESSION_DRIVER=cookie
HASH_DRIVER=bcrypt

Por defecto, la conexión de la base de datos para una aplicación AdonisJs es SQLite, que actualizará a MySQL aquí. Especifique también el PORT para la aplicación, el entorno de la aplicación y las credenciales de su base de datos. Asegúrese de sustituir el DB_USER, DB_PASSWORD y el marcador de posición DB_DATABASE por sus credenciales.

Luego, creará el modelo y un archivo de migración para Quote usando Adonis CLI. Para hacer esto, ejecute el siguiente comando:

  • adonis make:model Quote --migration

Visualizará un resultado similar al siguiente:

Output
✔ create app/Models/Quote.js ✔ create database/migrations/1568209992854_quote_schema.js

Este comando creará un modelo para Quote en la carpeta app/Models y un archivo de esquema en la carpeta database/migrations​​​. El archivo de esquema recién creado llevará la marca de tiempo actual como prefijo. Abra el archivo de esquema con lo siguiente:

  • nano database/migrations/1568209992854_quote_schema.js

Actualice su contenido con el siguiente código:

database/migrations/…quote_schema.js
'use strict'
/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')
class QuoteSchema extends Schema {
  up () {
    this.create('quotes', (table) => {
      table.increments()
      table.integer('user_id').notNullable()
      table.string('username', 80).notNullable()
      table.string('body').notNullable()
      table.timestamps()
    })
  }
  down () {
    this.drop('quotes')
  }
}
module.exports = QuoteSchema

Un archivo de esquema de AdonisJs requiere dos métodos diferentes, que son los siguientes:

  • up: Se utiliza para crear una nueva tabla o modificar una tabla existente.
  • down: se utiliza para revertir los cambios aplicados en el método up.

Además de los campos timestamps() y increments(), debe el contenido del archivo de esquema con los atributos de campo user_id​​​, username y el body de la cita que se creará Los campos user_id y username hacen referencia a los detalles del usuario que crea una cita en particular. Esto define una relación de uno a muchos y significa que un usuario puede poseer un número infinito de citas mientras que una sola cita solo puede pertenecer a un usuario.

Guarde el archivo y ciérrelo.

AdonisJs viene instalado con un modelo User y su archivo de migración por defecto, el cual requiere solo una pequeña modificación para establecer la relación entre el modelo User y Quote.

Abra el modelo User en app/Models/User.js:

  • app/Models/User.js

Añada este método de inmediato después del método tokens():

app/Models/User.js
...
class User extends Model {
  ...
  tokens () {
    return this.hasMany('App/Models/Token')
  }

  quote () {
    return this.hasMany('App/Models/Quote')
  }
}

module.exports = User

Esto establecerá una relación de uno a muchos con la tabla Quote usando user_id como la clave externa.

Guarde el archivo y ciérrelo.

Para finalizar esta sección, utilice el siguiente comando para ejecutar migraciones, el cual ejecutará el método up() de todos los archivos de migración:

  • adonis migration:run

El resultado debe ser similar a lo siguiente:

Output
migrate: 1503248427885_user.js migrate: 1503248427886_token.js migrate: 1568209992854_quote_schema.js Database migrated successfully in 3.42 s

Ya configuró y protegió una conexión con su base de datos. También creó un modelo Quote con su archivo de esquema correspondiente y una relación uno a muchos entre User y Quote. Luego, debe generar las rutas y crear controladores para gestionar solicitudes HTTP y la lógica de negocios para crear, editar y eliminar una cita inspiradora.

Paso 4: Crear controladores y configurar rutas

En esta sección, primero creará controladores para gestionar toda la lógica de la aplicación y luego añadirá estos controladores a una ruta específica para que los usuarios puedan acceder a ella a través de una URL.

Para comenzar, usando Adonis CLI creará un nuevo controlador de solicitud HTTP para gestionar todos los procesos de autenticación de su aplicación con el siguiente comando:

  • adonis make:controller Auth --type http

Este comando creará un archivo AuthController.js y lo guardará en la carpeta app/Controllers/Http. Utilice el indicador --type para indicar que desea que este controlador sea HTTP.

Visualizará un resultado similar al siguiente:

Output
✔ create app/Controllers/Http/AuthController.js

Luego, abra el archivo del controlador recién creado:

  • nano app/Controllers/Http/AuthController.js

Actualícelo con el siguiente contenido:

app/Controllers/Http/AuthController.js
'use strict'
const User = use('App/Models/User')
class AuthController {

    loginView({ view }) {
        return view.render('auth.login')
    }
    registrationView({ view }) {
        return view.render('auth.register')
    }

    async postLogin({ request, auth, response}) {
        await auth.attempt(request.input('email'), request.input('password'))
        return response.route('index')
    }

    async postRegister({ request, session, response }) {
        const user = await User.create({
            username: request.input('name'),
            email: request.input('email'),
            password: request.input('password')
        })
        session.flash({ successmessage: 'User have been created successfully'})
        return response.route('login.create');
    }

    async logout ({ auth, response }) {
        await auth.logout()
        return response.route('/')
    }
}
module.exports = AuthController

En este archivo, debe importar el modelo User y luego crear dos métodos denominados loginView() y registerView() para mostrar las páginas de inicio de sesión y registro respectivamente. Por último, se deben crear los siguientes métodos asíncronos:

  • postLogin(): este método obtendrá los valores de email y password publicados con ayuda del método request incorporado de AdonisJs, y luego validará este usuario con los detalles de la base de datos. Si dicho usuario existe en la base de datos e ingresó la credencial correcta, regresará a la página de inicio y se autenticará para crear una nueva cita. De lo contrario,aparecerá un mensaje que indicará que las credenciales ingresadas son incorrectas.
  • postRegister(): este método recibirá el valor de username, email y password para que un usuario cree una cuenta para dicho usuario en la base de datos. Se pasará a la sesión un mensaje que indicará que se creó correctamente dicho usuario y este accederá a la página de inicio de sesión para autenticarse y comenzar a crear una cita.
  • logout(): este método gestionará la función de inicio de sesión y redireccionará el usuario de vuelta a la página de inicio.

Guarde el archivo y ciérrelo.

Ahora que configuró el controlador para registrar y autenticar usuarios, proseguirá creando un controlador de solicitudes HTTP para administrar todas las operaciones relacionadas con citas.

En el terminal, ejecute el siguiente comando para crear el QuoteController:

  • adonis make:controller Quote --type http --resource

Usar el indicador --resource creará un controlador con métodos ingeniosos predefinidos para realizar operaciones CRUD (crear, leer, actualizar y borrar).

Verá lo siguiente:

Output
✔ create app/Controllers/Http/QuoteController.js

Ubique este archivo en app/Controllers/Http/QuoteController.js:

  • nano app/Controllers/Http/QuoteController.js

Actualícelo con el siguiente contenido:

app/Controllers/Http/QuoteController.js
'use strict'
const Quote = use('App/Models/Quote')

class QuoteController {

  async index ({ view }) {
    const quote = await Quote.all()
    return view.render('index', {
      quotes: quote.toJSON()
    })
  }

  async create ({ view }) {
    return view.render('quotes.create-quote')
  }

  async store ({ request,auth,session, response }) {
    const quote = await Quote.create({
      user_id: auth.user.id,
      username: auth.user.username,
      body: request.input('body')
    })
    session.flash({ 'successmessage': 'Quote has been created'})
    return response.redirect('/')
  }

  async show ({ params, view }) {
    const quote = await Quote.find(params.id)
    return view.render('quotes.view-quote', {
      quote: quote.toJSON()
    })
  }

  async edit ({ params, view }) {
    const quote = await Quote.find(params.id)
    return view.render('quotes.edit-quote', {
      quote: quote.toJSON()
    })
  }

  async update ({ params, request, response, session }) {
    const quote = await Quote.find(params.id)
    quote.body = request.input('body')
    await quote.save()
    session.flash({'successmessage': 'Quote has been updated'})
    return response.redirect('/')
  }

  async destroy ({ params, response, session }) {
    const quote = await Quote.find(params.id)
    await quote.delete()
    session.flash({'successmessage': 'Quote has been deleted'})
    return response.redirect('/')
  }
}
module.exports = QuoteController

En este controlador, importó el modelo Quote y actualizó los siguientes métodos que se crearon automáticamente mediante AdonisJs CLI:

  • index(): permite buscar todas las citas de la base de datos y mostrarlas en la página de inicio de la aplicación.
  • create(): permite representar una página para crear citas.
  • store(): permite persistir una cita recién creada en la base de datos y mostrar una respuesta adecuada.
  • show(): permite obtener el id de una cita en particular, obtenerlo de la base de datos y procesarlo en la página para editar citas.
  • edit(): permite obtener el detalle de una cita en particular de la base de datos y representarla para su edición
  • update(): permite procesar cualquier actualización de una cita y redirigir al usuario de vuelta a la página de inicio.
  • destroy(): permite eliminar una cita en particular y eliminarla por completo de la base de datos.

Guarde el archivo y ciérrelo.

Después de crear todos los controladores necesarios para esta aplicación, podrá configurar las rutas para que los usuarios puedan interactuar fácilmente con su aplicación. Para comenzar, diríjase al archivo start/routes.js

  • nano start/routes.js

Reemplace su contenido con lo siguiente:

start/routes.js
'use strict'
const Route = use('Route')

Route.get('/','QuoteController.index').as('index')
Route.get('/register','AuthController.registrationView').as('register.create')
Route.post('/register-store','AuthController.postRegister').as('register.store').validator('Register')
Route.get('/login','AuthController.loginView').as('login.create')
Route.post('/login-store','AuthController.postLogin').as('login.store')
Route.get('/view-quote/:id','QuoteController.show').as('view.quote')

Route.group(() => {
    Route.get('/create-quote','QuoteController.create').as('create.quote')
    Route.post('/store-quote','QuoteController.store').as('store.quote')
    Route.get('/edit-quote/:id','QuoteController.edit').as('edit.quote')
    Route.post('/update-quote/:id','QuoteController.update').as('update.quote')
    Route.get('/delete-quote/:id','QuoteController.destroy').as('delete.quote')
    Route.post('/logout','AuthController.logout').as('logout')
}).middleware(['auth'])

Aquí, debe definir el camino para cada ruta en su aplicación, especificar los verbos del HTTP para cada acción y vincular la ruta a un método particular en cada controlador. También debe nombrar cada una de estas rutas, ya que se referencian en los controladores y las vistas.

Para garantizar que solo los usuarios autenticados puedan acceder a todas las rutas de citas, asigne un middleware de grupo con nombre. Por último, debe añadir un método validator a la ruta de register.store para validar la entrada del usuario.

Guarde el archivo y ciérrelo.

Creó sus controladores y configuró las rutas para su aplicación. Luego, cree el método de validación definido en este paso.

Paso 5: Validar el resultado del usuario

AdonisJs no tiene validadores incorporados por defecto. Por ello, instale y registre el validador para su aplicación manualmente.

Ejecute el siguiente comando para instalarlo:

Abra el siguiente archivo para registrar el proveedor del validador:

  • nano start/app.js

Luego, registre el proveedor del validador agregándolo a la lista de proveedores, como se muestra a continuación:

start/app.js
...
const providers = [
   ...
   '@adonisjs/cors/providers/CorsProvider',
   '@adonisjs/shield/providers/ShieldProvider',
   '@adonisjs/session/providers/SessionProvider',
   '@adonisjs/auth/providers/AuthProvider',
   '@adonisjs/validator/providers/ValidatorProvider'
]

Ahora que instaló y registró el proveedor del validador en su aplicación, cree un validador personalizado para validar la entrada del usuario durante el registro con el siguiente comando:

  • adonis make:validator Register

Con esto se creará un archivo Register.js en el directorio App/validators. Abra el archivo con:

  • nano app/Validators/Register.js

Añada el siguiente código al archivo:

app/Validators/Register.js
'use strict'
class Register {
  get rules () {
    return {
      name:'required',
      email:'required|email|unique:users',
      password:'required|min:8'
    }
  }

  get messages(){
    return{
      'name.required':'Full name is required',
      'email.required':'email is required',
      'email.unique':'email already exists',
      'password.required':'password is required',
      'password.min':'password should be at least 8 characters'
    }
  }
}
module.exports = Register

En su aplicación, debe definir reglas para campos específicos. Si las validaciones fallan en algún momento, el validador establecerá automáticamente el error como mensaje flash y el usuario regresará al formulario.

Guarde y cierre el archivo una vez que termine de editarlo.

Por último, para añadir estilo a su aplicación, abra el siguiente archivo:

  • nano public/style.css

Reemplace su contenido por lo siguiente:

/public/style.css
@import url('https://fonts.googleapis.com/css?family=Montserrat:300');

html, body {
  height: 100%;
  width: 100%;
}

body {
  font-family: 'Montserrat', sans-serif;
  font-weight: 300;
  background-image: url("/splash.png");
  background-color: #220052;
}

* {
  margin: 0;
  padding: 0;
}

a {
  color: inherit;
  text-decoration: underline;
}

p {
  margin: 0.83rem 0;
}

.quote-wrapper {
  margin-top: 20px;
}

.quote-wrapper a {
  text-decoration: none;
}

.quote-wrapper a:hover {
  color: #ffffff;
}

.empty-quote {
  color: #ffffff;
}

form {
  padding: 20px;
}

En este archivo, debe actualizar el estilo CSS de su aplicación en el archivo style.css.

Instaló y registró un proveedor de validador para verificar la entrada de los usuarios durante el proceso de registro. También actualizó el contenido de su hoja de estilos para añadir más estilos a la aplicación. En el último paso, probará su aplicación.

Paso 6: Presentar la aplicación

En este paso, presentará su aplicación y creará un usuario y una contraseña para probar la autenticación. También agregará una cita a su aplicación y la verá en la página de inicio.

Para probar su aplicación, inicie el servidor de desarrollo con el siguiente comando desde el directorio root de su aplicación:

  • adonis serve --dev

Esto iniciará la aplicación en el puerto definido dentro del archivo .env root, el cual es 3333. Diríjase a http://localhost:3333 desde su navegador.

Página de inicio de la aplicación de citas

La página de inicio estará vacía en este momento, ya que no creó citas. Haga clic en el botón Register.

Página de registro

Ingrese sus detalles y haga clic en el botón Submit para completar el proceso de registro. Accederá a la página de inicio de sesión. Ingrese su dirección de correo electrónico y su contraseña para la autenticación.

Página de inicio de sesión

Una vez que esté autenticado, haga clic en el botón Crear cita.

Página de creación de citas

Ingrese una cita y diríjase a la página View all para ver su cita.

Página de visualización de todas las citas

Probó su aplicación creando y autenticando un usuario y, luego, escribiendo una cita.

Conclusión

A lo largo de este tutorial, creó una aplicación web con AdonisJs. Configuró la aplicación usando el AdonisJs CLI y aprovechó el CLI para crear otros archivos importantes, como controladores, modelos y vistas.

Puede crear aplicaciones web con este marco independientemente de su tamaño y complejidad. Puede descargar el código fuente de este proyecto aquí en GitHub. Para ver más características, también puede visitar la documentación oficial.

Si desea ver algunos de nuestros otros tutoriales del marco de JavaScript, puede consultar lo siguiente:

0 Comments

Creative Commons License