{"id":19302976,"url":"https://github.com/jsagon/nodejs-framework-api","last_synced_at":"2025-02-24T01:44:46.634Z","repository":{"id":93071236,"uuid":"323480708","full_name":"jsagon/nodejs-framework-api","owner":"jsagon","description":"Estrutura, helpers e mecanismos que facilitam o desenvolvimento de uma API de fácil e rápida implementação, e completamente customizável.","archived":false,"fork":false,"pushed_at":"2020-12-29T01:50:21.000Z","size":213,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-05T23:27:42.232Z","etag":null,"topics":["api","framework","nodejs","nodejs-api"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jsagon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-22T00:35:46.000Z","updated_at":"2020-12-29T01:50:24.000Z","dependencies_parsed_at":null,"dependency_job_id":"f52a528b-7236-4fa4-a942-3da85d9a5293","html_url":"https://github.com/jsagon/nodejs-framework-api","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsagon%2Fnodejs-framework-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsagon%2Fnodejs-framework-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsagon%2Fnodejs-framework-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsagon%2Fnodejs-framework-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jsagon","download_url":"https://codeload.github.com/jsagon/nodejs-framework-api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240404682,"owners_count":19796062,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","framework","nodejs","nodejs-api"],"created_at":"2024-11-09T23:24:30.405Z","updated_at":"2025-02-24T01:44:46.603Z","avatar_url":"https://github.com/jsagon.png","language":"JavaScript","readme":"# NodeJS Framework API\n\n\u003e Estrutura, helpers e mecanismos que facilitam o desenvolvimento de uma API de fácil e rápida implementação, e completamente customizável.\n\n\u003c!--Primeiramente, não se trata de um Package a ser instalado como dependência do projeto, mas sim o próprio projeto propriamente dito.\nObs.: Versão em TypeScript em desenvolvimento, e futuramente com intenção de estruturar como Package npm.--\u003e\n\n### Sumário\n\n- [Descrição](#descrição)\n- [Instalação e Configuração](#instalação-e-configuração)\n- [Entendendo a arquitetura](#entendendo-a-arquitetura)\n- [Criando um módulo - Exemplo](#criando-um-módulo---exemplo)\n- [Consumo da API e Demo](#consumo-da-api-e-demo)\n- [Automação de Testes](#automação-de-testes)\n- [Futuro e novas funcionalidades](#futuro-e-novas-funcionalidades)\n- [Autor Info](#autor-info)\n\n---\n\n## Descrição\n\nA Framework tem como propósito inicial mostrar a simplicidade de implementação de um projeto NodeJS, funcionando também como um modelo para ensino e estudo.\n\nPara aqueles que preferem não utilizar uma framework muito robusta como o NestJS, mas ainda assim não abrir mão de determinadas facilidades, aqui encontrarão uma abordagem estrutural similar, e completamente customizável sem perder a escalabilidade para um projeto maior.\n\nPor padrão, o projeto já vem com uma mini implementação de autenticação de usuário e criação de tarefas para exemplificar a implementação, e visando também aqueles que querem apenas testar integrações.\n\n---\n\n## Instalação e Configuração\n\n#### Instalação\nPor abrir mão de ser um Package em prol de dar uma liberdade mais ampla ao desenvolvedor, o download deverá ser realizado por meio do próprio repositório.\n\n```shell\ngit clone https://github.com/jsagon/nodejs-framework-api.git\n```\n\nPara instalação das dependências da Framework, entre na pasta e rode o comando\n\n```\nnpm install\n```\n\n#### Configuração\n\nNa pasta /config, possui um arquivo de exemplo das variáveis a serem utilizadas na aplicação. Renomeie o arquivo ou crie um novo apenas \".env\"\n\nConfiguração do arquivo até o momento: \n``` \nPORT=3000\nDATABASE_MAIN=mongodb://127.0.0.1:27017/\u003cnome da base de dados aqui\u003e\n#exemplo: DATABASE_MAIN=mongodb://127.0.0.1:27017/task-manager-api\nJWT_SECRET_KEY='Insira a sua chave secreta aqui'\n``` \nObs.: O projeto utiliza o MongoDB e Mongoose na implementação de exemplo. Fique a vontade para utilizar outro banco de dados e outras ferramentas como o Sequelize.\n\nPor motivos de segurança, não existe um arquivo específico para ambiente de produção para não correr o risco de envio junto aos arquivos do projeto. Recomendo setar ou criar diretamente na hospedagem que utilizar. \n\n#### Inicializando\n\n```\nnpm run dev\n```\n\nSe tudo ocorrer bem, será mostrado a mensagem \"Server online\". Indo a url http://localhost:3000/ você provavelmente verá um retorno da API com informações resumidas da aplicação.\n\nResumo do exemplo de retornado \n```\n{\n  \"uris\": {\n    \"users\": {\n      \"create\": \"/users\",\n      \"login\": \"/users/login\",\n      \"logout\": \"/users/logout\"\n\t\t  ...\n    },\n    \"tasks\": {\n      \"create\": \"/tasks\",\n      \"list\": \"/tasks\",\n      \"getOne\": \"/tasks/:id\",\n      ...\n    }\n  },\n  \"version\": \"1.0\",\n  \"github\": \"https://github.com/jsagon/nodejs-framework-api\",\n  \"created_by\": \"JSagon\"\n}\n```\nObs.: Fique a vontade para modificar como quiser.\n\n---\n\n## Entendendo a arquitetura\n\nA estrutura de diretórios bem como determinadas funcionalidades se assemelham bastante a outras frameworks como Laravel e Zend Framework. Fornecendo assim, melhor divisão das implementações e entendimento para aqueles que estão migrando.\n\nExemplo da estrutura:\n```\nconfig\n  .env\nsrc\n  bootstrap\n  database\n  middlewares\n  modules\n    User\n      Config\n        Routes.js\n      Controller\n        UserController.js\n      Models\n        User.js\n  utils\n    error\n      CustomError.js\n    route\n      RouteBuilder.js\n\t\t\n```\n\n#### Funcionalidades especiais\n\n**RouteBuilder**\n\n\u003e Construção de rotas abstraindo as complexidades de cada implementação e registro na aplicação. Tratamento de exceções padrões, instância única de controlador por requisição para evitar conflitos indesejados, uris padrões, entre outros.\n \nAbaixo um exemplo de um CRUD padrão com autenticação \n\n**Sem o uso** do RouteBuilder desenvolvido nesta framework\n```\nconst router = express.Router()\n\nrouter.post('/tasks', authMiddleware, async (req, res) =\u003e {\n    try {\n       ...\n    } catch(e) {\n        res.status(500).send(e)\n    }\n})\n\nrouter.get('/tasks', authMiddleware, async (req, res) =\u003e {\n    try {\n        ...\n    } catch(e) {\n        res.status(500).send(e)\n    }\n})\n\nrouter.get('/tasks/:id', authMiddleware, async (req, res) =\u003e {\n    try {\n        ...\n    } catch(e) { \n        res.status(500).send(e)\n    }\n})\n\nrouter.patch('/tasks/:id', authMiddleware, async (req, res) =\u003e {\n    try{\n        ...\n    } catch(e) {\n        res.status(500).send(e)\n    }\n})\n\nrouter.delete('/tasks/:id', authMiddleware, async (req, res) =\u003e {\n    try {\n        ...\n    } catch(e) {\n        res.status(500).send(e)\n    }\n})\n```\n\n**Com o uso** do RouteBuilder desenvolvido nesta framework\n```\nconst router = express.Router()\n\nnew RouteBuilder(router, '/tasks', TaskController, authMiddleware)\n    .get()\n    .getOne()\n    .post()\n    .patch()\n    .del()\n```\n\nExemplo mais complexo envolvendo uris e actions customizáveis\n```\nnew RouteBuilder(router, '/users', UserController)\n    //sem middleware de autenticação\n    .post()\n    .post({uri:'/login', action:'login'})\n    //com middleware de autenticação\n    .setBaseMiddlewares([authMiddleware])\n    .get({uri:'/me', action:'get'})\n    .post({uri:'/logout', action:'logout'})\n    .patch({uri:'/me', action:'update'})\n```\n\n**RoutesRegister**\n\nO arquivo /src/bootstrap/routes.js (RoutesRegister) fornece um modelo fácil para registro das rotas do sistema, sendo necessário apenas inserir o arquivo Routes.js do módulo em questão.\n\u003e Funcionalidade em desenvolvimento: Registro automático das rotas sem a necessidade de setar manualmente.\n\n**CustomError**\n\nO arquivo /src/utils/error/CustomError.js (CustomError) fornece uma interface de erro padrão quando necessário levantar exceção. A utilidade dessa exception está no tratamento automático das rotas ao identificar um erro levantado, e retornar de forma padronizada.\n\n**HandleMongooseError**\n\nO arquivo /src/utils/error/HandleMongooseError.js fornece métodos para tratamento dos erros levantados especificamente no Mongoose. Devido a estrutura da exceção servir um padrão não muito interessante para retorno da API, os métodos deste arquivo fornecem uma padronização de retorno.\n\nQuando por exemplo, o mongoose levanta um erro de chave única, a mensagem é ilegível para o usuário final e necessitando de um tratamento por parte do programador.\n\nUm exemplo de retorno utilizando os métodos do HandleMongooseError:\n```\n{\n  validation: {\n    email: 'Este e-mail já se encontra em nossos registros'\n  }\n}\n```\n---\n\n## Criando um módulo - Exemplo\n\n\u003e Exemplo simplificado da criação de um módulo novo para a aplicação. Passo a passo\n\nExemplo de criação de um módulo de Boas Vindas.\n\nPrimeiro construiremos a estrutura de pastas e arquivos\n```\nsrc\n  modules\n    Welcome\n      Config\n        Routes.js\n      Controller\n        WelcomeController.js\n```\n\nAgora, editaremos o arquivo WelcomeController.js. Criaremos a classe do controlador e um método inicial\n\n```\nclass WelcomeController {\n  async index (req, res) {\n    res.send({msg:'Bem-vindo a sua primeira implementação'})\n  }\n}\n\nexport default WelcomeController \n```\n\nEm seguida, editaremos a classe Routes.js da seguinte forma\n```\nimport WelcomeController from '../Controller/WelcomeController'\nimport RouteBuilder from '../../../utils/route/RouteBuilder'\nimport express from 'express'\nconst router = express.Router()\n\nnew RouteBuilder(router, '/welcome', WelcomeController)\n  .get({uri:'/', action:'index'})\n\nexport default router\n```\n\nAgora só nos resta registrá-la no RoutesRegister.js\n```\n...\nimport WelcomeRoutes from '../modules/Welcome/Config/Routes'\n\n...\ngetRoutesRegistered() {\n  return [\n    ...\n    WelcomeRoutes\n  ]\n}\n```\n\nReiniciando a aplicação, caso não esteja utilizando o nodemon, e acessando a url http://localhost:3000/welcome você deverá ver a sua primeira action sendo retornada.\n\n---\n\n## Consumo da API e Demo\n\n\u003e A explicação é a partir de uma url online, mas as chamadas são igualmente para o localhost. \nObs.: Para aqueles que desejam utilizar a url online para testes de integração, com apps mobile ou outros, é preciso ter ciência de que a base de dados está programada para limpar-se de tempo em tempo. Não utilizar para produção.\n\nExemplos de consumo da API com autênticação\n\nurl: https://jsagon-task-manager-api.herokuapp.com\n\nCriação de usuário e retorno:\n```\n// post {url}/users\n{\n    \"name\": \"User Test\",\n    \"password\": \"usertest\",\n    \"email\": \"usertest@user.com\"\n}\n\n// Retorno\n{\n    \"user\": {\n        \"_id\": \"5fe8d557206c05001791f5e1\",\n        \"name\": \"User Test\",\n        \"email\": \"usertest@user.com\",\n        \"createdAt\": \"2020-12-27T18:41:27.074Z\",\n        \"updatedAt\": \"2020-12-27T18:41:27.169Z\"\n    },\n    \"token\": \"...\"\n}\n```\n\nLogin de usuário e retorno:\n```\n// post {url}/users/login\n{\n    \"password\": \"usertest\",\n    \"email\": \"usertest@user.com\"\n}\n\n// Retorno\n{\n    \"user\": {\n        \"_id\": \"5fe8d557206c05001791f5e1\",\n        \"name\": \"User Test\",\n        \"email\": \"usertest@user.com\",\n        \"createdAt\": \"2020-12-27T18:41:27.074Z\",\n        \"updatedAt\": \"2020-12-27T18:41:27.169Z\"\n    },\n    \"token\": \"...\"\n}\n```\n\nCriação de uma Tarefa e retorno.\n\nObs.: Por necessitar de autenticação, será preciso passar o Token no cabeçalho da requisição\n```\n// post {url}/tasks\n// Authorization: Bearer \u003ctoken\u003e\n{\n    \"title\": \"Tarefa de testes\",\n    \"description\": \"...\",\n    \"completed\": true\n}\n\n// Retorno\n{\n    \"completed\": true,\n    \"_id\": \"5fe8d683206c05001791f5e4\",\n    \"title\": \"Tarefa de testes\",\n    \"userCrt\": \"5fe8d557206c05001791f5e1\",\n    \"createdAt\": \"2020-12-27T18:46:27.843Z\",\n    \"updatedAt\": \"2020-12-27T18:46:27.843Z\",\n}\n```\n\n\u003e Para outras ações, verificar actions retornadas no resumo inicial ou no código internamente. Não inserido aqui para não ficar muito extenso.\n\n---\n\n## Automação de Testes\n\n\u003e Certificar-se de que os recursos foram implementados corretamente nunca é demais ^^\n\nPor padrão, esta framework já vem com uma configuração para testes utilizando o Jest, e uma pasta para os códigos de implementação. Sendo eles na raiz do projeto, ./tests, e um arquivo com testes iniciais ./tests/simple.test.js.\n\nPara executar os testes, utilize o comando a seguir:\n```\nnpm test\n```\n\nProvavelmente ao final da execução, você verá o resultado como na imagem seguinte:\n\n![tests](https://user-images.githubusercontent.com/11699360/103250978-64601b80-4955-11eb-9ce8-1c65d573d09c.JPG)\n\n\n---\n\n## Futuro e novas funcionalidades\n\nApesar da proposta inicial de ser uma Framework básica, o projeto ainda tem variadas funcionalidades para acrescentar. \n\nDentre as funcionalidades, estão:\n- Versão completamente em TypeScript.\n- Registro dos módulos e rotas dinamicamente, removendo a necessidade manual.\n- Arquitetura monorepo para múltiplas aplicações. \n- Implementação front-end: Views. MVC.\n- Abstração para o Fastify além do já Express.\n\n---\n\n## Autor Info\n\nNome: Jhonatan Gonçalves\u003cbr\u003e\nAlias: JSagon\u003cbr\u003e\nLinkedin: https://www.linkedin.com/in/jhonatan-goncalves/\u003cbr\u003e\nE-mail: na descrição do github\u003cbr\u003e\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsagon%2Fnodejs-framework-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjsagon%2Fnodejs-framework-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsagon%2Fnodejs-framework-api/lists"}