JSagon NodeJS Framework - Em Breve

A JSagon NodeJS Framework tem como propósito fornecer um modelo simples, leve e rápido de desenvolvimento. Abstraindo a complexidade e focando principalmente nas questões essenciais. A framework fornece uma interface de fácil entendimento e customização.


Atenção

Este artigo foi criado antes do lançamento da JSagon Framework. Desde então novos recursos foram acrescentados, incluindo a nova padronização de criação de rotas a partir de decorators e um sistema de registro de middlewares mais completo.


Este artigo é uma apresentação resumida e uma visão geral do que esperar da JSagon Framework. E que será devidamente documentada assim que estiver disponível.

A base deste mesmo site, jsagon.com, e seus projetos implementados já estão construídos em cima da versão desta framework aqui apresentada.

Os exemplos estão em TypeScript, mas poderão ser igualmente implementados com JavaScript puro.



A JSagon Framework abstrai a implementação de recursos padrões, identificados nos variados projetos do Github e tutorias, agilizando assim o seu desenvolvimento. Além de trazer conceitos de implementação como Monorepo, uma divisão de projetos num único lugar, automatizações, entre outros.

O uso de plataformas HTTP robustas, como Express e Fastify, potencializam de forma abrangente as implementações. O Express é utilizado como base por padrão, escolhido devido a sua grande disseminação. Mas você pode igualmente utilizar o Fastify mudando apenas um único campo na configuração e a qualquer momento do desenvolvimento devido a abstração implementada.

O código abaixo apresenta a inicialização da aplicação pronta para uso. Exemplos de algumas implementações padrões feitas por baixo dos panos são: Tratamento de error 404; json para envio de dados; configuração de diretórios para fornecimento de arquivos estáticos e views; View Engine; entre outros.

import { JSagon } from '@jsagon/core'
import configApp from './config/app.config'

JSagon.create(configApp).listen(3000)

A framework fornece um nível de abstração acima das plataformas utilizadas, permitindo assim uma fácil e rápida troca entre elas a qualquer momento. Porém, caso seja necessário, ela possibilita também o acesso a suas APIs diretamente. Dando assim uma liberdade maior para os desenvolvedores fazerem uso extensivo de componentes de terceiros. Podendo ser implementado como no exemplo a seguir:

import { JSagon } from '@jsagon/core'
import configApp from './config/app.config'

const boostrap = JSagon.create(configApp)
const express = bootstrap.getApplication().getApp()

//O que desejar implementar, ex.:
express.use(..)

bootstrap.listen(3000)
                

Implementando Rotas

Uma atenção especial foi dada ao registro de rotas. Para facilitar a criação e possibilitar futuras trocas entre Express, Fastify ou qualquer outra plataforma, foi criado um construtor de rotas com métodos padronizados e abrangentes.

Todas as rotas são registradas automaticamente ao inicializar a aplicação. A automatização leva em consideração se o módulo está ativo, uri base, entre outros. Será amplamente detalhado da documentação.

Segue abaixo alguns exemplos de implementação:

import Route from '@jsagon/RouteBuilder'
import HomeController from '../Controller/HomeController'

// cria uma rota example.com/ apontando para o metodo padrão index do controlador
const routeBuilder = Route('/', HomeController).index()

export default routeBuilder
                

Exemplo de rotas padrões e customizadas:

/** 
 *  .allDefaults(): Cria as rotas de CRUD padrões do MVC: uris > método interno
 *  get  example.com/product > index
 *  get  example.com/product/create > create
 *  post example.com/product/store > store
 *  entre outros
 */ 
const routeBuilder = Route('/product', ProductController).allDefaults()

/**
 *  Caso deseje criar rotas customizadas
 *  post example.com/product/items > createSubItem
 *  get  example.com/product/items > getSubItems
 */
const routeBuilder = Route('/product', ProductController)
  .post({uri:'/items', action:'createSubItem'})
  .get({uri:'/items', action:'getSubItems'})
                

Implementações de middlewares

Obs.: Há a possibilidade também de middlewares aplicáveis a todas as rotas do sistema.

import AuthMiddleware from '../Middleware/Auth'

// Adição de um middleware pontual, será aplicado a todas as definições de rotas seguidas
const routeBuilder = Route('/admin', AdminController, AuthMiddleware).index()

// Atribuição de middleware em rotas especificas
const routeBuilder = Route('/users', AdminController)
  .login()
  .post({uri:'/forgot-password', action: 'forgotPassword'})
  // A partir daqui todas as rotas checarão a autenticação
  .setBaseMiddlewares(AuthMiddleware) 
  .index()
  .logout()
                

Controladores

Controladores são basicamente classes responsáveis por tratar requisições e retornar respostas(dados) para o cliente. A JSagon Framework implementa também métodos padrões para facilitar e agilizar o desenvolvimento.

Segue abaixo um exemplo de controlador que renderiza uma tela inicial ao ser acessado a url principal do site (como a primeira rota criada na explicação Implementando Rotas).

Explicando um pouco do funcionamento: Quando é criado uma rota index para o controlador Home, e é acessado a url example.com/, existe uma inteligência interna que monta o caminho da view (exemplo: views/app/website/home/index) sem que seja necessário o desenvolvedor para cada ação definir o caminho da view manualmente.

import Controller from '@jsagon/controller/AbstractController'

class HomeController extends Controller {}

export default HomeController
                

Segue abaixo um exemplo de implementação onde é deliberadamente implementado um método com retorno de dados para a view.

Obs.: this.viewPath é o caminho montado na explicação anterior.

import Controller from '@jsagon/controller/AbstractController'

class ProductController extends Controller {
  public async create (req, res) {
    return res.render(this.viewPath, {..})
  }
}

export default ProductController
                

Entendendo a estrutura

Entendendo um pouco a estrutura da aplicação e dos arquivos explicados anteriormente.

Um ponto a ser destacado é a implementação do conceito de monorepo. Onde é possível separar, desenvolver e disponibilizar os projetos. Toda a estrutura foi e está sendo pensada para fornecer uma organização que abrange desde projetos simples até aqueles mais complexos, permitindo escalabilizar conforme o crescimento.

public // arquivos estáticos
resources 
  views
    layouts
    app
      website/home/welcome/index.hbs 
src
  config
    app.config.ts // configuração de plataforma HTTP, caminhos, entre outros.
  app
    Website // Projeto 1: Website do sistema
      app.config.ts // define a uri base do app, se está ativo e disponível, etc.
      module
        Home
          Config
            Routes.ts
          Controller
            WelcomeController.ts
    Blog // Projeto 2: Blog do sistema
  server.ts
                

Considerações finais

Muitos outros recursos foram implementados e faltam ser apresentados, como Restful API, View Engine e Middlewares gerais.

Por ser tratar de uma apresentação e uma visão geral, fica para artigos futuros e para a própria documentação após a disponibilização da JSagon NodeJS Framework.

Em breve a versão final, originada da mesma já em uso neste site, estará disponibilizada para uso. Caso tenha gostado da abordagem e filosofia da framework, inscreva-se abaixo para receber uma notificação de release. E caso fique alguma dúvida ou tenha alguma sugestão, entre em contato, sua opinião será bem recebida. 👍

Até breve.