Veja nesse artigo uma rápida introdução ao SOLID e um exemplo prático sobre o SRP (Principio da responsabilidade unica) utilizando TypeScript
Princípios do SOLID com TypeScript – OCP
Veja nesse artigo um exemplo prático do principio OCP — Princípio Aberto-Fechado
Introdução
Dando continuidade a minha série de artigos sobre os princípios do SOLID com TypeScript e aproveitando a liberação do episódio 2 do nosso podcast: DevShow #22 SOLID OCP. Hoje irei abordar o segundo principio do SOLID, OCP.
OCP — Princípio Aberto-Fechado
O OCP diz que as entidades de software (classes, módulos, funções… ) devem ser abertas para ampliação, mas fechadas para modificação.
De forma mais detalhada, diz que podemos estender o comportamento de uma classe por meio de herança, interface e composição, mas não podemos permitir a abertura dessa classe para fazer modificações.
Em uma pesquisa rápida pela internet eu achei uma imagem que descreve bem esse principio:
Violação: Note que na imagem com fundo rosa nós temos um robo que começa com uma faca falando que pode cortar e depois de uma nova demanda esse mesmo robo troca a faca por um rolo de pintar.
Essa imagem lembra algo? rs
É muito comum no desenvolvimento de software situações como essa onde temos uma classe que tem uma determinada funcionalidade e ao decorrer da evolução do sistema ela tenha que sofrer algumas mudanças. É nesse momento que devemos lembrar desse principio (OCP).
Na segunda imagem nós temos um robo que começa com uma faca falando que pode cortar e depois de uma nova demanda aparece com um rolo de pintar na outra mão.
Em uma breve analise, note que ele não alterou (perdeu) como na primeira imagem a funcionalidade de cortar, com a evolução ele acabou ganhando uma nova funcionalidade, a de pintar.
Esse seria o comportamento perfeito para que consigamos atender a nova demanda e ainda garantir que o que esta no publicado não seja alterado.
Bom, mas como ficaria isso no código?
Para que esse principio fique mais claro, vamos criar um exemplo prático utilizando o TypeScript.
Exemplo prático
Vamos começar com um código simples:
enum TipoDeArquivo { pdf, excel } class Arquivos { Exportar(arquivo: TipoDeArquivo, data: any) { if (arquivo == TipoDeArquivo.excel) { // exportar data para excel } if (arquivo == TipoDeArquivo.pdf) { // exportar data para pdf } } }
Nessa classe nós temos uma classe com um método chamado Export, que valida o tipo de documento e dependendo do tipo que ele for, ele exporta os dados que estiverem em data para um dos formatos: pdf ou excel.
Até aqui tranquilo, nós temos um código simples que esta validando o tipo de arquivo que esta em um enum.
Agora imagine o seguinte cenário, chegou uma nova demanda para exportar os dados para Word, como você faria essa alteração?
Pensando rapidamente nós colocaríamos o novo tipo no enum e adicionaríamos um if no método exportar correto?
Algo assim:
enum TipoDeArquivo { pdf, excel, word } class Arquivos { Exportar(arquivo: TipoDeArquivo, data: any) { if (arquivo == TipoDeArquivo.excel) { // exportar data para excel } if (arquivo == TipoDeArquivo.pdf) { // exportar data para pdf } if (arquivo == TipoDeArquivo.word) { // exportar data para word } } }
Demanda done, mas dai vem aquela pergunta, essa é a melhor forma de resolver a nossa demanda?
A resposta é não, resolvemos a demanda, mas em uma breve analise estamos dando mais uma responsabilidade para nossa classe Arquivos, além de estar violando o primeiro principio do SOLID o SRP, o correto pensando no OCP seria estender essa classe, não atribuir mais uma funcionalidade nela, com a possibilidade de quebrar algo existente.
Agora pensando no OCP, como resolver essa demanda ?
Na realidade é bem simples, veja a seguir como ficaria a nossa classe:
abstract class Arquivos { Exportar(data: any) { } } class GerarExcel extends Arquivos { Exportar(data: any) { } } class GerarPDF extends Arquivos { Exportar(data: any) { } } class GerarWord extends Arquivos { Exportar(data: any) { } }
Com essa implementação nós estamos atendendo a nova demanda, garantindo o SRP (Removendo a responsabilidade de validar o tipo da classe) e o OCP, garantindo que a classe Arquivos esteja fechada para mudança, mas aberta para extensão.
Bem simples e mais organizado né?
Bom, com isso nós finalizamos mais esse artigo, espero que tenham gostado e até um próximo artigo pessoal.
Gostou deste artigo? Comente abaixo!
Referência: https://programadriano.medium.com/princ%C3%ADpios-do-solid-com-typescript-2c6a4911242d
Upload de arquivos com TypeScript + Node.js + Azure Storage
Veja nesse artigo como criar um projeto para upload de arquivo utilizando Node.js + TypeScript e Azure. A seguir você tem dois links demonstrando um passo a passo do upload para uma pasta até o envio para o Azure Storage e depois alguns vídeos demonstrando a construção de um middler.
Introdução do módulo
Node.js + TypeScript: Criação de um middler
TypeScript + Nodejs: Criação de middler para upload de arquivos
Testando o nosso projeto
JWT — JSON Web Token / Vídeos
Veja nesse artigo como trabalhar com JWT
Recentemente eu liberei mais um módulo do meu curso: Criando API’s RESTful utilizando TypeScript, Node.js, mongoDB, nesse estou demonstrando como trabalhar com JWT. Caso tenha interesse em ver esse conteudo, segue alguns links abaixo:
- Node.js: criando um token JWT sem plugin
- Conhecendo o (JWT) na teoria e na prática
- Angular decode payload JWT
- programadriano/nodejs-jwt
Introdução ao JWT
JWT — JSON Web Token — 2 Parte
JWT — Criando a secret key
Criando a classe de Autenticação
Importando o middler de autenticação
JQT — Gerando o token
Testando a segurança nas rotas
Gostou deste artigo? Comente abaixo!
Referência: https://programadriano.medium.com/jwt-json-web-token-2039797ba126
(JWT) JSON Web Token
Conhecendo o (JWT) na teoria e na prática.
Introdução
Quando estamos trabalhando com API’s, nós precisamos pensar na segurança no momento no momento de trafegar os dados e principalmente no nível de permissão que cada usuário deverá ter. Existem muitas formas de se fazer isso, mas uma que vem se destacando a cada dia que se passa é o JWT (JSON Web Token), por ser muito seguro e fácil de se implementar. Nas próximas sessões, será abordado a sua teoria com alguns exemplos e no final iremos criar uma aplicação com Node.js para exemplificarmos melhor o seu funcionamento.
Bom, o JWT (JSON Web Token) é um sistema de transferência de dados que pode ser enviado via POST ou em um cabeçalho HTTP (header) de maneira “segura”, essa informação é assinada digitalmente por um algoritmo HMAC, ou um par de chaves pública/privada usando RSA. Podemos ver na imagem a baixo um cenário onde será requisitado um token através do Verbo HTTP POST, que irá devolver um token validado para que nas próximas requisições que utilizem os Verbos HTTP possam utilizar.
A estrutura dele é formada por 3 partes: Header, Payload e Signature. Vamos entender melhor elas:
Header
O Header consiste em duas partes encodados em Base64 sendo:
- O Tipo (JWT)
- E o algoritmo de Hash que pode ser (HMAC SHA256 ou RSA).
{ "alg": "HS256", "typ": "JWT" }
Payload (Claims)
Os payloads são objetos JSON que contem os claims, nessa parte que nós trabalhamos com os “pedidos”, carga de dados ou dados enviados. Existem 3 tipos de claims em Payloads: reserved, public, e private claims.
Reserved claims: Atributos não obrigatórios (mas recomendados) que podem ser um conjunto de informações uteis e interoperáveis normalmente utilizados por protocolos de segurança em API’s:
- “iss” (Issuer) Origem do token
- “iat” (issueAt) Timestamp de quando o token foi gerado
- “exp” (Expiration) Timestamp de quando o token expira
- “sub” (Subject) Entidade a quem o token pertence, normalmente o ID do usuário
- Public claims: São atributos que definem o uso do JWT e informações úteis para a aplicação.
- Private claims: São atributos definidos especialmente para compartilhar informações entre aplicações.
Exemplo:
{ "iss": "127.0.0.13", "exp": 1300819380, "user": "programadriano", "admin": true }
Signature
Essa é a terceira e última parte do JWT, para que possamos ter um token, nós precisamos de um Header, Payload, o algoritmo definido na header, um secret definido pela nossa aplicação. Vamos ver um exemplo com a utilização do HMAC SHA256:
var encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload); + "." + HMACSHA256(encodedString, 'secret');
O seu retorno seria o token a baixo:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IlRoaWFnbyIsInN1YiI6IjEzIiwianRpIjoiZDBlMGFkZDItOTlkMC00NWY1LThlYzEtY2FiYzIwZjkxMGYyIiwiaWF0IjoxNTAwMDMzMjE0LCJKd3RWYWxpZGF0aW9uIjoiVXN1YXJpbyIsIm5iZiI6MTUwMDAzMzIxMywiZXhwIjoxNTAwMDMzMjczLCJpc3MiOiJJc3N1ZXIiLCJhdWQiOiJBdWRpZW5jZSJ9.SmjuyXgloA2RUhIlAEetrQwfC0EhBmhu-xOMzyY3Y_Q
Podemos perceber que o nosso token está dividido em três partes separadas por “.”, conforme nós utilizamos no momento da criação.
Primeira parte: Header .
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
Segunda parte: Payload.
eyJ1bmlxdWVfbmFtZSI6IlRoaWFnbyIsInN1YiI6IjEzIiwianRpIjoiZDBlMGFkZDItOTlkMC00NWY1LThlYzEtY2FiYzIwZjkxMGYyIiwiaWF0IjoxNTAwMDMzMjE0LCJKd3RWYWxpZGF0aW9uIjoiVXN1YXJpbyIsIm5iZiI6MTUwMDAzMzIxMywiZXhwIjoxNTAwMDMzMjczLCJpc3MiOiJJc3N1ZXIiLCJhdWQiOiJBdWRpZW5jZSJ9.
Terceira parte: Secret.
SmjuyXgloA2RUhIlAEetrQwfC0EhBmhu-xOMzyY3Y_Q
Quando um usuário faz uma requisição ao servidor passando os seus dados de login, o servidor analisa e retorna um token com uma validade, para que o usuário possa navegar pelo sistema.
Para que possamos validar se o nosso token está correto podemos utilizar o próprio site do JWT. Para isso, basta copiar o token acima que criamos para esse exemplo e colar na parte Encoded do site. Podemos ver o seu retorno dessa validação na imagem a baixo:
Agora lembra que acima comentamos sobre a palavra chave? Podemos adicionar ela na parte VERIFY SIGNATURE do site, para esse exemplo nós utilizamos a frase: batman batman batman, notem que após colocarmos ela irá mudar o status da nossa assinatura conforme a baixo de Invalid Signature para Signature Verified.
Nessa primeira parte nós conseguimos criar o nosso token e validar ele pelo próprio site do JWT, mas como funcionária em um projeto real? Vamos criar uma API em Node.js e utilizar o postman para que possamos validar as nossas requisições.
Exemplo prático
Nosso primeiro passo será a criação de um novo projeto Node.js, para que esse artigo não fique muito longo, vamos resumir essa etapa em:
1º Crie um diretório para o nosso projeto;
2º Execute o comando npm init -y;
3º Abrir uma IDE de nossa preferencia e criar uma estrutura básica como na imagem a baixo, para esse exemplo nós iremos utilizar o Visual Studio Code, ele é uma ferramente muito completa e grátis desenvolvida pela Microsoft. Caso queria instalar ele, basta baixar o seu executável no link Download.
Vamos agora adicionar os pacotes necessários para esse artigo, no seu arquivo package.json adicione as seguintes dependências:
},"dependencies": { "body-parser": "^1.15.0", "express": "^4.13.4", "jsonwebtoken": "^5.7.0", "mongoose": "^4.4.5", "morgan": "^1.7.0" }
Para que possamos baixar esse pacotes para o nosso projeto, execute o comando npm install, a execução dele irá criar uma pasta chamada node_modules e dentro dela os nossos pacotes.
Nosso próximo passo será a implementação da nossa classe user. Para isso, copie e cole o código a baixo dentro do seu arquivo user.js, que está dentro do diretório models.
class User { constructor(name, admin) { this.name = name; this.admin = admin; }}; module.exports = User;
Agora nós iremos implementar o nosso server.js, esse será o arquivo principal do nosso projeto.
var express = require('express'); var app = express(); var bodyParser = require('body-parser'); var morgan = require('morgan'); var jwt = require('jsonwebtoken'); var user = require('./models/user');
Nessa primeira parte estamos importando os nossos pacotes, até aqui nenhuma novidade, vamos agora adicionar o código que será responsável para realizar a conversão dos nossos dados para JSON:
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json());
Vamos agora referenciar o código que será responsável por gerenciar os logs das nossas requisições e apresentar eles na nossa console:
app.use(morgan(‘dev’));
Para que possamos testar o pacote Morgan e validar o nosso código, vamos criar a nossa primeira rota:
var apiRoutes = express.Router(); apiRoutes.get('/', function (req, res) { res.json({ message: 'Node.js com JWT' }); }); app.use('/', apiRoutes); var port = process.env.PORT || 8000; app.listen(port); console.log('Aplicação rodando na porta:' + port);
Vamos entender o código acima, na primeira linha nós estamos chamando o Router do pacote Express, em seguida nós criamos o nosso primeiro método Get retornando uma mensagem, por fim estamos passando a porta que o nosso projeto irá rodar e adicionando um listen nela. Para executar o código, dentro da console digite o comando node server.js, em seguida vamos abrir no nosso navegador o endereço: http://localhost:8000/ ele deve retornar a mensagem: “Node.js com JWT” e o senguinte log na nossa console:
Com isso nos conseguimos validar o pacote morgan e a nossa requisição HTTP com o express, vamos agora implementar o JWT. Para isso, vamos criar um novo método POST no nosso arquivo server.js.
apiRoutes.post('/', function (req, res) { if (req.body.UserName != "tadriano" || req.body.PassWord != "102030") { res.json({ success: false, message: 'Usuário ou senha incorreto(s)!' }); } else { let usuario = new user() { name : "tadriano"; admin: true }; var token = jwt.sign(usuario, 'batman batman batman', { expiresInMinutes: 1440 }); res.json({ success: true, message: 'Token criado!!!', toke: token }); } });
Para que esse artigo não fique muito longo, nós criamos uma validação conhecida como Hard Code, em seguida como não estamos buscando o nosso usuário no banco nós criamos um novo, para que possamos implementar os dados da nossa assinatura, em seguida nós retornamos uma mensagem de sucesso e o nosso token. Para validar essa etapa nós iremos utilizar o Postman, uma ferramenta do google chrome que auxilia nos testes a requisições HTTP. Com ele aberto adicione a URL do projeto com a porta e o usuário e senha na Body. A imagem a baixo demonstra esse implementação:
Feito isso podemos enviar a nossa requisição que irá retornar o nosso token. Podemos ver esse retorno na imagem a baixo:
Agora para finalizar esse artigo vamos criar um middler para verificar se a requisição está com o token ou se ele é um token é valido. Para isso, vamos colar o código a baixo depois do nosso método POST.
apiRoutes.use(function(req, res, next) { var token = req.body.token || req.query.token || req.headers['x-access-token']; if(token) { jwt.verify(token, 'batman batman batman', function(err, decoded) { if (err) { return res.json({ success: false, message: 'Falha ao tentar autenticar o token!' }); } else { //se tudo correr bem, salver a requisição para o uso em outras rotas req.decoded = decoded; next(); } }); } else { // se não tiver o token, retornar o erro 403 return res.status(403).send({ success: false, message: '403 - Forbidden' }); } });
Nessa etapa nós estamos verificando se a requisição está com o token, caso não esteja enviando ele ou caso ele seja um token invalido nós retornamos o status 403, que é utilizado para passar que o usuário não tem permissão para realizar aquela requisição. Caso o token seja valido, nós retornamos o status 200 e uma mensagem no navegador.
Por fim, para que possamos validar um requisição com o token, nós precisamos realizar o mesmo procedimento acima para gerar um token e em seguida preencher o Postman conforme a imagem a baixo, assim conseguiremos ter acesso aos nossos métodos.
Com isso nós conseguimos abordar a teoria do JWT e entender o seu funcionamento através de um exemplo criado em uma linguagem de programação que vem sendo adotada por muitos programadores a cada dia que se passa.
Gostou deste artigo? Comente abaixo!
Referência: https://programadriano.medium.com/json-web-token-jwt-c469834849a8
Publicando projeto Docker + Node.js + TypeScript + MongoDB No Azure
Veja nessa artigo alguns links sobre como publicar o seu projeto Node.js, TypeScript e MongoDB com Docker e Docker Compose no Azure
O próximo passo será acessar a sua conta do Azure. Caso ainda não tenha uma, você pode criar através do seguinte link: Crie sua conta Azure Grátis.
Benefícios Visual Studio Dev Essentials
A seguir você tem o exemplo do arquivo Docker Compose que eu irei utilizar para publicar o meu projeto no Azure:
version: "3" services: api: image: tadrianonet/api-ts ports: - "80:3050" links: - link-db link-db: image: tutum/mongodb ports: - "27017:27017" - "28017:28017" environment: - AUTH=no
Deploy no Azure Web Apps for Containers
Testando aplicação na Nuvem
Bom galera, com isso liberamos mais um módulo sobre Docker do Curso “Criando API’s RESTful utilizando TypeScript, Node.js, mongoDB”.
Espero que gostem e até um próximo artigo pessoal 😉
Referências: https://programadriano.medium.com/publicando-projeto-docker-node-js-typescript-mongodb-no-azure-608d8fa54246
Trabalhando com Docker + Node.js + TypeScript + MongoDB
Veja nessa artigo alguns links sobre como trabalhar com Docker e o Docker Compose em um projeto desenvolvido com Node.js, TypeScript e MongoDB
Abaixo vocês tem os links do módulo como trabalhar com Docker do meu Curso Criando API’s RESTful utilizando TypeScript, Node.js, mongoDB
Criando uma imagem Docker
Subindo a API com o Docker compose
Publicando imagem no Docker hub
Baixando e testando a imagem do Docker Hub
Espero que tenham gostado e até um próximo artigo pessoal 🙂
Referência: https://medium.com/typescript/trabalhando-com-docker-node-js-typescript-mongodb-a341d42e1fc0
[TypeScript] no TDC São Paulo Online 2020
Na data do dia 26/08/2020 eu tive a oportunidade de palestrar no TDC são Paulo Online 2020.
Gostaria de agradecer ao Jackson Feijó, Adriano Rodrigues e à Talitha Barcellos que coordenaram as apresentações na Sala Microsoft pela oportunidade em participarmos como palestrantes nesta edição TDC.
A seguir vocês tem alguns links do material utilizado na minha apresentação:
Slides da minha apresentação:
Prints de tela retirado por amigos 😉
Curso: Criando API’s RESTful utilizando TypeScript, Node.js, mongoDB, Redis e Docker no Azure – Parte 2
2-Parte: Configurando o ambiente de banco de dados com Docker
Dando continuidade a liberação dos módulos do meu curso: Criando API’s RESTful utilizando TypeScript, Node e mongoDB, hoje eu irei demonstrar como subir um ambiente Docker com o MongoDB e como acessar essa base de dados.
Caso você seja iniciante em Docker, eu recomendo a leitura do seguinte artigo: Comando básicos docker.
Artigo contendo um passo a passo de como configurar um ambiente MongoDB com Docker: Docker: Criando servidor MongoDB
Configurando ambiente de banco de dados MongoDB com Docker
Acessando a base de dados mongoDB
Link para download do Robo 3T: Download
Espero que gostem e qualquer dúvida podem postar aqui ou no vídeo do Youtube.
Gostou deste artigo? Comente abaixo!
Curso: Criando API’s RESTful utilizando TypeScript, Node.js, mongoDB, Redis e Docker no Azure Parte 1
Para aqueles que colocaram como meta aprender algo novo na area de programação em 2020, eu estou disponibilizando alguns módulos do meu curso: Criando API’s RESTful utilizando TypeScript, Node e mongoDB.
Segue abaixo as primeiras video aulas liberadas 🙂
Introdução ao curso:
Ambiente de desenvolvimento:
Instalação do Node.js
Instalação do TypeScript
Aproveitando, segue link para download das ferramentas que nós iremos utilizar nesse curso abaixo:
- Instalação do Node.js
- Instalação do TypeScript
- Instalação do Docker
- Instalação do VS Code (Visual Studio Code)
Espero que gostem 🙂