|
| 1 | +# Arquitetura de Referência Serverless: Aplicação Web |
| 2 | + |
| 3 | +A arquitetura de referência para aplicação web é de proposta geral, orientada a eventos, a camada de API's utiliza [Amazon API Gateway](https://aws.amazon.com/apigateway) e usa [AWS Lambda](https://aws.amazon.com/lambda), para a lógica de negócio. Utiliza também [Amazon DynamoDB](https://aws.amazon.com/dynamodb) como banco de dados e [Amazon Cognito](https://aws.amazon.com/cognito) para gestão de usuários. Todo o conteúdo estático é provido pelo [AWS Amplify Console](https://aws.amazon.com/amplify/console). |
| 4 | + |
| 5 | +Essa aplicação implementa um aplicativo simples de To Do List, no qual um usuário registrado pode criar, atualizar, visualizar e eventualmente apagar os itens existentes. |
| 6 | + |
| 7 | +## Diagrama de Arquitetura |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | +## Componentes da Aplicação |
| 12 | + |
| 13 | +A aplicação web foi constrúida com 3 componentes diferentes. |
| 14 | + |
| 15 | +### Front End |
| 16 | + |
| 17 | +A aplicação de The front-end é composta apenas por conteúdo estático (HTML, CSS, JavaScript e imagens) que são gerados pelo `create-react-app`. Todos esses objetos são armazenados no AWS Amplify Console. |
| 18 | + |
| 19 | +Quando o usuário conecta ao website, os recursos necessários são carregados para o navegador e executados a partir dele. Quando a aplicação precisa comunicar com o backend, o frontend cria uma requisição REST para o backend. |
| 20 | + |
| 21 | +### Back End (Lógica de Negócio) |
| 22 | + |
| 23 | +O backend da aplicação é onde a lógica de negócio está implementada. O código é implementado usando funções Lambda que são acessadas através do API Gateway - REST API. No nosso caso, temos diferentes funções, cada uma lidando com diferentes aspectos da aplicação: lista de itens a fazer, detalhes sobre um item , atualizar um item, criar um item, marcar um item como completo e apagar um item existente. A aplicação salva todos os itens em uma tabela do DynamoDB. |
| 24 | + |
| 25 | +### Registro de Usuário e Autenticação |
| 26 | + |
| 27 | +Como uma aplicação de To Do contêm informações pessoas, o acesso é restrito a usuário autenticados. Cada usuário pode acessar apenans seus próprios itens. |
| 28 | + |
| 29 | +Para isso está sendo usado o Cognito User Pools, que permite o registro de usuários da aplicação e sua autenticação. Apenas depois de autenticado, o usuário irá receber um token JWT que será usado para realizar as requisições REST API. |
| 30 | + |
| 31 | +--- |
| 32 | +## Executando o exemplo |
| 33 | + |
| 34 | +Fork esse repositório na sua conta do GitHub, você irá precisar criar um Personal Access Token no Github para a console do Amplify e usar a URL do seu repositório GitHub durante a instalação. |
| 35 | + |
| 36 | +Você pode usar o template [AWS SAM template](../template.yml) para criar a stack que é mostrada nessa arquitetura de referência. Detalhes sobre os recursos criados estão descritos na seção *SAM Template Resources* neste documento. |
| 37 | + |
| 38 | +## Gerando seu token de acesso ao GitHub |
| 39 | + |
| 40 | +Para utilizar a console do Amplify, é necessário gerar o token de acesso pessoal. |
| 41 | +Uma vez criato, o token de acesso deve ser guardado de maneira segura, caso seja perdido um novo token precisa ser gerado. |
| 42 | +Para configurar o seu token de acesso, use [New personal access page](https://github.com/settings/tokens/new) no GitHub. |
| 43 | + |
| 44 | +Será necessário sua senha do GitHub para gerar o token de acesso. |
| 45 | + |
| 46 | +### Utilizando SAM e o Amplify Console para criar e instalar os recursos da aplicação |
| 47 | + |
| 48 | +Você pode instalar todos os componentes da aplicação usando o script: |
| 49 | + |
| 50 | +```bash |
| 51 | +export AWS_DEFAULT_REGION=<escolha uma regiao, ex: us-east-1> |
| 52 | +export STACK_NAME=<nome para a sua Stack de CloudFormation> |
| 53 | +./deploy.sh |
| 54 | +``` |
| 55 | + |
| 56 | +O script irá usar o SAM CLI para compilar as funções do backend, e guiará a instalação. O script irá pedir um conjunto de parâmetros ou aceitar os valores padrões, apenas a URL do repositório no GitHub e o token do GitHub OAuth são obrigatórios. |
| 57 | + |
| 58 | +### Construindo a aplicação - Passo a Passo |
| 59 | + |
| 60 | +Alternativamente, você pode executar os passos para a compilação usando a linha de comando: |
| 61 | + |
| 62 | +#### Compilando as função do backend |
| 63 | + |
| 64 | +O AWS SAM CLI simplifica o processo de compilação para vários ambientes de execução e copia o código fonte para a pasta de *staging* deixando as funções prontas para serem empacotadas e instaladas. O comando `sam build` compila usando qualquer dependência que a aplicação tenha e copia o código fonto para pastas abaixo de aws-sam/build para ser compactados e carregado para o serviço AWS Lambda. |
| 65 | + |
| 66 | +```bash |
| 67 | +sam build --use-container |
| 68 | +``` |
| 69 | + |
| 70 | +#### Empacotando o backend |
| 71 | + |
| 72 | +Execute `sam package` para empacotar a função Lambda e suas dependências em um zip e salvar em um *bucket* no Amazon S3. Será gerado o arquivo packaged.yml com o endereço do *bucket* e a localização do arquivo. Para empacotar a execute o comando abaixo: |
| 73 | + |
| 74 | +```bash |
| 75 | +sam package \ |
| 76 | + --output-template-file packaged.yml \ |
| 77 | + --s3-bucket $DEPLOYMENT_BUCKET |
| 78 | +``` |
| 79 | + |
| 80 | +#### Instalação do backend |
| 81 | + |
| 82 | +O comando `sam deploy` instala a aplicação no ambiente AWS. Esse comando explicitamente inclui os parâmetros: |
| 83 | + |
| 84 | +* A AWS Region na qual será instalado o pacote da aplicação. Deve ser a mesma região onde está o *bucket* do Amazon S3 que contém o pacote. |
| 85 | + |
| 86 | +* O parâmetro CAPABILITY_IAM, é para permitir que sejam criadas novas IAM roles para as funções Lambda. |
| 87 | + |
| 88 | +```bash |
| 89 | +sam deploy \ |
| 90 | + --template-file packaged.yml \ |
| 91 | + --stack-name $STACK_NAME \ |
| 92 | + --capabilities CAPABILITY_IAM |
| 93 | +``` |
| 94 | + |
| 95 | +#### Teste local (Opcional) |
| 96 | + |
| 97 | +Para executar a função Lambda, API Gateway e o DynamoDB localmente, siga os passos abaixo: |
| 98 | + |
| 99 | +Para executar o DynamoDB localmente |
| 100 | + |
| 101 | +```bash |
| 102 | +docker run -p 8000:8000 amazon/dynamodb-local |
| 103 | +``` |
| 104 | + |
| 105 | +Crie uma tabela DynamoDB em sua instância local |
| 106 | + |
| 107 | +```bash |
| 108 | +aws dynamodb create-table --table-name TodoTable --attribute-definitions AttributeName=id,AttributeType=S --key-schema AttributeName=id,KeyType=HASH --billing-mode PAY_PER_REQUEST --endpoint-url http://127.0.0.1:8000 |
| 109 | +``` |
| 110 | + |
| 111 | +Execute o SAM Local Module para testar a aplicação localmente |
| 112 | + |
| 113 | +```bash |
| 114 | +sam local start-api --env-vars todo-src/test/environment/mac.json |
| 115 | +``` |
| 116 | + |
| 117 | +Arquivo de exemplo para MAC OS: `todo-src/test/environment/mac.json` |
| 118 | + |
| 119 | +#### Atualizando o Frontend |
| 120 | + |
| 121 | +Uma vez com a infraestrutura instalada usando o SAM será necessário criar o arquivo de configuração para o frontend da aplicação web. Você pode obter os valores necessários pela descrição do Stack do CloudFormation: |
| 122 | + |
| 123 | +```bash |
| 124 | +aws cloudformation describe-stacks --stack-name $STACK_NAME --query "Stacks[0].Outputs[]" |
| 125 | +``` |
| 126 | + |
| 127 | +Copie o arquivo de configuração padrão e atualize com os valores abaixo: |
| 128 | + |
| 129 | +```bash |
| 130 | +cp www/src/config.default.js www/src/config.js |
| 131 | +``` |
| 132 | + |
| 133 | +Execute o frontend localmente para testes alterando o parâmetro `redirect_url` e `api_base_url` para o endereço `https://localhost:8080` e execute o comando abaixo: |
| 134 | + |
| 135 | +```bash |
| 136 | +cd www/src |
| 137 | +npm start |
| 138 | +``` |
| 139 | + |
| 140 | +#### Instalação do Frontend |
| 141 | + |
| 142 | +Deploy your application by checking in your update to the `config.js` file and pushing that commit to your repo. Amplify Console will automatically deploy the update from there. |
| 143 | + |
| 144 | +```bash |
| 145 | +git add www/src/config.js |
| 146 | +git commit -m 'Update frontend config' |
| 147 | +git push |
| 148 | +``` |
| 149 | + |
| 150 | +Você pode visualizar o processo de instalação pelo Amplify Console. |
| 151 | + |
| 152 | +## Limpeza dos Recusos |
| 153 | + |
| 154 | +### Apagar a Stack do CloudFormation |
| 155 | + |
| 156 | +```bash |
| 157 | +aws cloudformation delete-stack \ |
| 158 | +--stack-name $STACK_NAME |
| 159 | +``` |
| 160 | + |
| 161 | +### Apagar o CloudWatch Log Groups |
| 162 | + |
| 163 | +```bash |
| 164 | +for log_group in $(aws logs describe-log-groups --log-group-name-prefix '/aws/lambda/'$STACK_NAME --query "logGroups[*].logGroupName" --output text); do |
| 165 | + echo "Removing log group ${log_group}..." |
| 166 | + aws logs delete-log-group --log-group-name ${log_group} |
| 167 | + echo |
| 168 | +done |
| 169 | +``` |
| 170 | +--- |
| 171 | +## SAM Template Resources |
| 172 | + |
| 173 | +### Recursos |
| 174 | + |
| 175 | +O [template](../template.yaml) cria os recursos abaixo: |
| 176 | + |
| 177 | +* **TodoUserPool** - Cognito UserPool que gerencia os usuários da aplicaçào |
| 178 | + |
| 179 | +* **TodoUserPoolTokenClient** - Cognito UserPool Client que é usado pela aplicação web |
| 180 | + |
| 181 | +* **TodoDomain** - Cognito UserPool Domain Name, para identificar o UserPool |
| 182 | + |
| 183 | +* **TodoTable** - Tabela no DynamoDB usada para registrar os itens da lista de ToDo de cada usuário |
| 184 | + |
| 185 | +* **TodoApi** - REST API usada para publicar as funcionalidades da aplicação |
| 186 | + |
| 187 | +* **GetTodoFunction** - Função Lambda usada para recuperar um item |
| 188 | + |
| 189 | +* **GetAllTodoFunction** - Função Lambda usada para recuperar todos os itens do usuário |
| 190 | + |
| 191 | +* **CompleteTodoFunction** - Função Lambda usada marcar um item como completo |
| 192 | + |
| 193 | +* **AddTodoFunction** - Função Lambda usada para criar uma novo item |
| 194 | + |
| 195 | +* **UpdateTodoFunction** - Função Lambda usada para atualizar o conteúdo de um item |
| 196 | + |
| 197 | +* **DeleteTodoFunction** - Função Lambda usada para apagar um item |
| 198 | + |
| 199 | +* **ApiGatewayPushToCloudWatchRole** - An IAM role that allows API Gateway to send log events to CloudWatch Logs |
| 200 | + |
| 201 | +* **ApiAccessLogGroup** - loudWatch Logs Log Group usado pelo API Gateway para o log de mensagens |
| 202 | + |
| 203 | +* **AmplifyApp** - Amplify Console application para gerenciar as atualizações do frontend executada pelos gatilhos do GitHub. |
| 204 | +* |
| 205 | +* **AmplifyBranch** - Configuração da integração da branch no GitHub com o Amplify |
| 206 | + |
| 207 | +* **AmplifyRole** - IAM role que permite o Amplify executar as ações necessárias para atualização de conteúdo |
| 208 | +<br><br> |
| 209 | + |
| 210 | +### Notas |
| 211 | + |
| 212 | +Por padrão, o Node.js HTTP/HTTPS cria uma nova conexão TCP a cada nova requisição. Para evitar o custo de estabelecer uma nova conexão, você pode reutilizar uma conexão existente. |
| 213 | + |
| 214 | +Para operações de curta duração, como consultas ao DynamoDB, a latência para estabelecer a conexão TCP pode ser maior que da operação em si. Adicionalmente, o DynamoDB [encryption at rest](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/encryption.howitworks.html) é integrado ao [AWS KMS](https://aws.amazon.com/kms), podem ocorrer atrasos porque o banco de dados tem que reestabelecer novas entradas no cache do KMS para cada operação. |
| 215 | + |
| 216 | +A forma mais simples para configurar o SDK para JavaScript para o reuso de conexões TCP é configurar a variável de ambiente `AWS_NODEJS_CONNECTION_REUSE_ENABLED` para 1. Esse recurso foi adicionado na versão [2.463.0](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md#24630) . |
| 217 | + |
| 218 | +Para mais detalhes sobre o reuso de conexões, veja o [Developer Guide](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/node-reusing-connections.html). |
| 219 | + |
| 220 | +--- |
| 221 | + |
| 222 | +## Well-Architected Review |
| 223 | + |
| 224 | +Foi realizada uma revisão do [Well-Architected](https://aws.amazon.com/architecture/well-architected/) para essa aplicação, usando o [Serverless Application Lens](https://d1.awsstatic.com/whitepapers/architecture/AWS-Serverless-Applications-Lens.pdf). Os resultados podem ser encontrados [aqui](../well-architected.md). |
| 225 | + |
| 226 | +## Licenciamento |
| 227 | + |
| 228 | +Essa arquitetura de referência está licenciada sob os termos [Apache 2.0](../LICENSE). |
0 commit comments