@allnulled/express-boilerplate

0.0.15 • Public • Published

express-boilerplate

Código fuente base para servidores basados en Node.js + Express + SQL.

Ebo

NPM Github

Índice

Prestaciones

  1. ✔ Documentación en profundidad con REFERENCE.md.
  2. ✔ Herramienta de línea de comandos de serie.
  3. ✔ Comandos de serie fácilmente ampliables.
  4. ✔ Variables de entorno.
  5. ✔ Drivers de base de datos ampliables
  6. ✔ Scripts de creación y migración de bases de datos mediante sistema de plantillas EJS.
  7. ✔ Estructuras JSON del modelo de la base de datos automáticamente extraído del SQL.
  8. ✔ Drivers ampliables de bases de datos para:
    • ✔ SQLite
    • ✔ MySQL
  9. ✔ Decoradores de serie y fácilmente ampliables para:
    • ✔ Condicionales
    • ✔ Consecuenciales
    • ✔ Interceptores
    • ✔ Formateadores
  10. ✔ Documentación autogenerada mediante javadoc.
  11. ✔ Subida de ficheros incluída como funcionalidad nativa.
  12. ✔ Interfaces desde servidor a 3 bandas:
    • ✔ Caché: sistema de cacheo incorporado para páginas optimizadas.
    • ✔ Plantillas EJS: sistema de plantillas para páginas que requieren lógica fresca en cada llamada.
    • ✔ Ficheros estáticos: sistema de ficheros estáticos para ficheros inmutables.
  13. ✔ Middlewares de serie y fácilmente ampliables, basados en clases.
  14. ✔ Controladores de serie y fácilmente ampliables, basados en clases. Incluyen:
    • ControllerForCache.js: controlador para el sistema de caché de interfaces de servidor.
    • ControllerForFiles.js: controlador para ficheros estáticos.
    • ControllerForIndex.js: controlador específico para el fichero index.js
    • ControllerForTemplates.js: controlador para el sistema de plantillas de interfaces de servidor.
    • ControllerForUploads.js: controlador para ficheros estáticos de las subidas.
    • Debug.js: controlador para propósitos de debugging.
    • Delete.js: controlador para eliminar instancia del sistema automático CRUD.
    • Environment.js: controlador para propósitos de debugging.
    • Insert.js: controlador para insertar instancia del sistema automático CRUD.
    • Login.js: controlador para entrar al sistema.
    • Logout.js: controlador para salir del sistema.
    • Schema.js: controlador para averiguar el esquema de datos.
    • Select.js: controlador para seleccionar instancias del sistema automático CRUD.
    • SetFile.js: controlador para subir fichero del sistema automático CRUD.
    • Update.js: controlador para actualizar instancia del sistema automático CRUD.
  15. ✔ Modelos de serie basados en clase y en Sequelize, autogenerados a partir del SQL.
  16. ✔ Sistema de queries para separar las consultas puramente del resto de lógica.
  17. ✔ Carpeta de recursos, con librerías que puede interesar ampliar fácilmente. Incluye:
    • ✔ Librería de comprobaciones check-that.
    • ✔ Librería de parsing del SQL hql.pegjs y su hql.js.
  18. ✔ Utilidades globales disponibles en toda la aplicación, basadas en clases, fácilmente ampliables.
  19. ✔ Destacablemente, ofrece un sistema REST automático propio que resuelve las 4 operaciones CRUD mediante HTTP.
  20. ✔ También autogenera modelos para el ORM de Sequelize.
  21. ✔ Los decoradores son la prestación más avanzada, con la cual puedes reusar mucha lógica, además de ahorrar mucho código.

Instalación

Primero, instalas la herramienta globalmente:

npm install -g express-boilerplate

Después, ya puedes crear proyectos desde 0, colocándote en el directorio en el que quieres empezar el proyecto, y luego simplemente con:

ebo create .

Alternativamente, también puedes descargarte el proyecto git o clonarlo directamente en el directorio que desees, que al final sería lo mismo.

Ejecución

Para ejecutarlo simplemente

npm start

Filosofía

Este proyecto es completamente minimalista.

La ejecución se basa prácticamente en 2 ficheros:

  • src/load.js: carga toda la api. Pero no arranca el servidor.
  • src/main.js: carga toda la api y luego arranca el servidor.

Los datos se basan en 2 ficheros más:

Además, en el código original, la base de datos es SQLite, por lo cual es un proyecto compacto, que no depende de URLs/servidores externos.

Uso

En esta sección se desarrollan una serie de procesos que el usuario probablemente quiera hacer.

Crear un fichero estático

Simplemente añadiendo un fichero cualquiera bajo la carpeta src/Interface/www.

Crear una plantilla HTML con EJS

Simplemente añadiendo un fichero *.html bajo la carpeta src/Interface/ejs.

Crear una plantilla CSS con EJS

Simplemente añadiendo un fichero *.css bajo la carpeta src/Interface/ejs.

Crear un controlador

En src/Controllers puedes crear un fichero como éste:

module.exports = class {
    
    method = "use";
    
    route = "/";

    priority = 5000;
    
    getMiddleware() {
      return [];
    }
    
    async dispatch(request, response, next) {
        this.api.Utilities.Trace("api.Controllers.ControllerForIndex");
        try {
            const errorParameter = this.api.Utilities.GetRequestParameter(request, "error", false);
            if(typeof errorParameter === "string") {
                throw new Error(errorParameter);
            }
            const db = this.api.Utilities.GetDatabaseConnection();
            const [{ Result: result }] = await db.Execute("SELECT 100 as 'Result';");
            const [{ Result: result2 }] = await this.api.Utilities.QueryDatabase("SELECT 200 as 'Result';");
            return this.api.Utilities.DispatchSuccess(response, {
                message: "The API is working",
                result: result + result2
            });
        } catch (error) {
            return this.api.Utilities.DispatchError(response, error);
        }
    }

};

La api (con Utilities) se inyecta en todas las clases de controlador, una vez instanciado. También se recibe como parámetro en el constructor.

Por cierto, el auténtico ControllerForIndex, en cambio, redirecciona automáticamente la petición a /index.html. En este ejemplo se quería mostrar el acceso a las utilidades desde la API inyectada en todos los controladores al igual que utilidades.

Crear una utilidad

En src/Utilities puedes crear un fichero como éste:

module.exports = class {
    action() {
        this.api.Utilities.Trace("api.Utilities.GetDatabaseConnection");
        return this.api.Database.Connection;
    }
}

Esta utilidad es una action, pero también puedes crear una utilidad factory simplemente escribiendo el método factory (y no action) a modo de factory propiamente, o fábrica del valor final de la utilidad.

La api (con Utilities) se inyecta en todas las clases de utilidad, una vez instanciada. También se recibe como parámetro en el constructor.

Crear un modelo de dato

En src/Database/Scripts/creation.sql añades la tabla de datos que deseas.

Crear un modelo de dato programático

En src/Models añades la clase de modelo que deseas. No tienen una interfaz obligatoria, el consenso se delega a la lógica del proyecto particular. Eso sí, se inyectará api y se pasará al constructor.

Crear datos de migración inicial

En src/Database/Scripts/migration.sql añades la tabla de datos que deseas.

Crear una consulta

En src/Queries/ añades una nueva clase con el método query o factory.

Crear un comando

Los comandos se ejecutarían mediante ebo. Deberías ampliar los scripts del npm también. Pero ebo {Comando} es el que hará la función para llamar a los comandos. La carpeta de src/Commands está pretendidamente puesta para almacenar el código de casos como estos.

Crear una configuración

En src/load.js tienes la función setupConfigurations, donde se establecen los valores para las variables de entorno de process.env. Puedes añadrila ahí.

Alternativamente puedes usar el fichero src/Configurations/.env para establecer las variables globales directamente, sin intervenir código.

Crear librería de interfaz

En src/Interface/www/lib añades una nueva carpeta para la nueva librería.

Crear componente de interfaz

En src/Interface/www/lib/components añades una nueva carpeta para el nuevo componente. Luego típicamente crearías un fichero con el mismo nombre pero terminado en js para usar como componente, otro con .css y otro con .md para guía de uso.

Habilitar o deshabilitar controladores

Para habilitar controladores solo tienes que mover los controladores, que deben seguir la especificación de clase, en la carpeta src/Controllers.

Para deshabilitar controladores solo tienes que mover los controladores de la carpeta src/Controllers a la carpeta src/Controllers/Off.

¿Qué más ofrece el boilerplate?

Hay algunas otras ventajas, como clases utilitarias, o herramientas para análisis de software.

Clases utilitarias

Unas pocas clases utilitarias:

Generador de documentación

Con express-boilerplate también tienes un generador de documentación basado en comentarios javadoc. Solo tienes que hacer:

npm run build-documentation

Así puedes generar documentación en src/Documentation/REFERENCE.md.

Decoradores de base de datos

Los decoradores de base de datos son una de las features estrella de «express-boilerplate». Con ellos, podemos decorar partes de la base de datos (tabla o columna, básicamente) con referencias que podemos recuperar luego en el código, y usarlas para que tenga comportamientos específicos en según qué partes del código.

Los adaptadores que actualmente están disponibles son:

Las sintaxis del lenguaje de metabases de datos HQL

El lenguaje HQL o Hyper-Query-Language está por detrás parseando el fichero de creación de base de datos. Con el fin de extender las funcionalidades del servidor, a la hora de capacitarlo para decisiones de seguridad, se pueden usar una serie de expresiones incrustadas como comentarios multilínea del SQL.

Estas expresiones o sintaxis son las que siguen:

  • Permissions
  • Restrictions
  • Interceptors

A continuación se explicarán uno por uno.

La sintaxis de permissions

La sintaxis de permissions se usa como sigue:

CREATE TABLE Tabla_determinada /*
  @comprobar_permiso:
    al         { OPERACIONES CRUD: select | insert | update | delete }
    si         { CONDICION }
    entonces   { CONSECUENCIA }
*/ ( ... );

Un ejemplo típico es cuando aplicas (un consecuencial) una prohibición cuando (sucede un condicional) no tiene un permiso.

CREATE TABLE Tabla_determinada /*
  @comprobar_permiso:
    al         select | insert | update | delete
    si         $conditionals.no_tiene_permiso(data, "permiso de administración") && $conditionals.no_tiene_permiso(data, "supervisión del almacén")
    entonces   $consequencials.prohibir(data, "Esta operación requiere de privilegios específicos")
*/ ( ... );

Ten en cuenta que:

  • Las permissions se aplican por tabla.
  • Las permissions se aplican por operación CRUD.
  • Las permissions se aplican según un condicional.
  • Las permissions se aplican mediante un consecuencial, un interceptor, o un método predeterminado cualquiera al fin y al cabo.

La sintaxis de restrictions

La sintaxis de restrictions se usa como sigue:

CREATE TABLE Tabla_determinada (
  nombre VARCHAR(500) /*
    @comprobar_restriccion:
      { SUBOPERACION CRUD }
      si { CONDICION }
  */
);
CREATE TABLE Tabla_determinada (
  nombre VARCHAR(500) /*
    @comprobar_restriccion:
      no es seleccionable
      si $conditionals.no_tiene_permido(data, "permiso de administración")
  */
);

Ten en cuenta que:

  • Las restrictions se aplican por columna.
  • Las restrictions se aplican por suboperaciones CRUD, éstas son:
    • no es seleccionable
    • no es filtrable
    • no es ordenable
    • no es insertable
    • no es actualizable
  • Las restrictions se aplican según un condicional.
  • Las restrictions se aplican mediante una expresión de suboperación CRUD.

La sintaxis de interceptors

La sintaxis de interceptors es mucho más sencilla y permite aplicar decoradores completamente personalizados. Se usa como sigue:

CREATE TABLE Tabla_determinada /*
  @interceptar: $interceptors.Tables.registrar_cambios_en(data, this, "Tabla_determinada_historial")
*/

También puede tener aplicaciones en las columnas:

CREATE TABLE Tabla_determinada (
  creado_por VARCHAR(500) /*
    @interceptar: $interceptors.Columns.fijar_id_de_usuario_al_insertar(data, "creado_por", this)
  */
);
  • Los interceptors se aplican por tabla y/o por columna.
  • Los interceptors se aplican independientemente de la operación CRUD concreta. Eso se discrimina dentro del interceptor en sí.
  • Los interceptors son mucho más sencillos y personalizables que las otras categorías de decoradores de base de datos.

Readme

Keywords

none

Package Sidebar

Install

npm i @allnulled/express-boilerplate

Weekly Downloads

1

Version

0.0.15

License

WTFPL

Unpacked Size

14.8 MB

Total Files

768

Last publish

Collaborators

  • allnulled