Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
APLICACAO WEB DE ANOTACOES PARA AUXILIO NA
MEMORIZACAO DE VOCABULARIOS
Alan Carpilovsky
Projeto de Graduacao apresentado ao Curso
de Engenharia Eletronica e de Computacao
da Escola Politecnica, Universidade Federal
do Rio de Janeiro, como parte dos requisitos
necessarios a obtencao do tıtulo de Enge-
nheiro.
Orientador: Flavio Luis de Mello
Rio de Janeiro
Marco de 2019
UNIVERSIDADE FEDERAL DO RIO DE JANEIRO
Escola Politecnica - Departamento de Eletronica e de Computacao
Centro de Tecnologia, bloco H, sala H-217, Cidade Universitaria
Rio de Janeiro - RJ CEP 21949-900
Este exemplar e de propriedade da Universidade Federal do Rio de Janeiro, que
podera incluı-lo em base de dados, armazenar em computador, microfilmar ou adotar
qualquer forma de arquivamento.
E permitida a mencao, reproducao parcial ou integral e a transmissao entre bibli-
otecas deste trabalho, sem modificacao de seu texto, em qualquer meio que esteja
ou venha a ser fixado, para pesquisa academica, comentarios e citacoes, desde que
sem finalidade comercial e que seja feita a referencia bibliografica completa.
Os conceitos expressos neste trabalho sao de responsabilidade do(s) autor(es).
iv
AGRADECIMENTO
Apesar de estar me formando sozinho, nao seria possıvel ter concluıdo esta etapa
sem a ajuda de diversos grupos de pessoas; tento cita-los nesta secao, na talvez
ingenua esperanca de nao me esquecer de nenhum. Os agradecimentos se restringem
aqueles envolvidos especificamente na minha graduacao e/ou neste projeto, porem
tambem sou grato pelas demais pessoas presentes em minha vida.
Primeiramente, aos meus pais Adriane e Roberto, avo Lali e irma Alexia por
tudo; seria impraticavel listar a mirıade de motivos pelos quais os amo e acredito
ser extremamente afortunado por te-los por perto.
Ao meu tio Andre, pela companhia nos momentos difıceis do primeiro perıodo.
Aos meus tios Helena e Toni, por me providenciarem os livros-texto de diversas
materias. Ao restante da minha famılia, tambem, pelas palavras de apoio e pelo
constante interesse no andamento do curso.
Aos meus amigos que, independentemente do grau de proximidade, se importaram
com meu bem-estar e me ajudaram a superar as dificuldades que surgiram durante
a graduacao. Em especial, aos Bernardo Napoletti e Henrique Bejgel, por estarem
sempre ao meu lado, mesmo morando a centenas ou milhares de quilometros.
Aos meus colegas e amigos da VTEX, que foram — e continuam sendo — funda-
mentais na minha jornada como profissional e indivıduo. Em especial, aos Fernando
Coelho, Natalia Medina e Rafael Bezerra, por acompanharem este projeto de perto,
colaborando com opinioes e conselhos. Aos meus companheiros de equipe Bruno
Abreu e Thiago Murakami, tambem, pelo apoio.
Aos Mariza e Aloysio, por toda a ajuda.
A minha sensei Rika Hagino, um exemplo de dedicacao e didatica, cujos carinho
e atencao sao valiosos incentivos para meus estudos de lınguas. Aos meus demais
v
amigos e professores da Associacao Nikkei, tambem, por tornarem meu aprendizado
mais divertido e prazeroso.
Aos professores universitarios que iam alem das salas de aula. Em especial, ao
prof. Mauros Campello Queiroz, do qual tive o imenso prazer de ser aluno, e que
infelizmente nos deixou ha pouco mais de um ano.
Ao meu orientador, Flavio Luis de Mello, que, alem de ministrar a disciplina mais
interessante da minha graduacao, foi presente e solıcito na redacao deste trabalho.
Por ultimo, porem de forma alguma menos importante, aos meus amigos e co-
legas de curso, que me ajudaram a superar os momentos mais complicados; tenho
certeza de que nao estaria me formando agora se nao fosse por eles. Em especial, aos
Marina Torres, Antonio Resende, Luiz Renno, Tamine Verli, Camyla Romao, Adri-
ano Fonseca, Vitor Cossetti e Igor Nascimento pelos apoio e companhia nos ultimos
perıodos. Agradeco, tambem, aos Sebastiao, Haroldo e Vania, pais de alguns deles,
por me receberem em suas casas inumeras vezes para sessoes de estudos, sempre
com muita hospitalidade e carinho.
vi
RESUMO
Por varios anos, a area de desenvolvimento web esteve fortemente conectada as
distribuicoes de informacoes e de conteudos midiaticos, e o ofıcio de um desenvol-
vedor front-end, por exemplo, era comumente associado a tarefas de web design.
Com o advento de frameworks e bibliotecas que facilitam a administracao do fluxo
de dados, o controle de estado e a otimizacao da transferencia de recursos, o papel
do desenvolvedor web comecou a se aproximar mais da engenharia de computacao.
Este trabalho apresenta os componentes e decisoes por tras da construcao de uma
aplicacao web completa, assim como topicos que focam em melhorar a experiencia
oferecida ao usuario. Muitas das tecnologias introduzidas tambem sao empregadas
por diversas plataformas lıderes de mercado, pois tratam-se dos estados da arte de
seus respectivos nichos. Por fim, o tema da aplicacao e a memorizacao de voca-
bularios, buscando auxiliar estudantes de idiomas em suas trajetorias.
Palavras-chave: desenvolvimento, web, aplicacao, NoSQL, MongoDB, OAuth 2.0,
Node, Express, React, REST, GraphQL, webpack, JavaScript, TypeScript, apren-
dizado, lınguas, idiomas, memorizacao, vocabularios, revisao.
vii
ABSTRACT
For many years, web development was strongly related to information and media
distribution, and the job of a front-end developer, for example, was commonly as-
sociated with web design tasks. With the advent of frameworks and libraries that
make it easier to manage the data flow, control state and optimize resource transfers,
the role of a web developer began to get closer to computer engineering. This work
presents the components and decisions behind the construction of a complete web
application, as well as topics that focus on improving the user experience. Many of
the technologies introduced here are also employed by several leading platforms, as
they are the states of the art of their respective niches. Finally, the subject of the
application is vocabulary memorization, seeking to help language learners on their
paths.
Keywords: development, web, application, NoSQL, MongoDB, OAuth 2.0, Node,
Express, React, REST, GraphQL, webpack, JavaScript, TypeScript, learning, lan-
guages, memorization, vocabularies, review.
viii
SIGLAS
ACID - Atomicidade, consistencia, isolamento, durabilidade
AJAX - Asynchronous JavaScript and XML
API - Application programming interface
BD - Banco de dados
CI - Continuous integration
CRUD - Create, read, update, delete
CSS - Cascading Style Sheets
ES - ECMAScript
HTTP - Hypertext Transfer Protocol
I/O - Input/Output
ID - Identificador
JSON - JavaScript Object Notation
PWA - Progressive Web App
RAM - Random-access memory
REST - Representational State Transfer
RWD - Responsive Web Design
SEO - Search engine optimization
ix
SPA - Single-page application
SSR - Server-side rendering
TSC - TypeScript Compiler
UFRJ - Universidade Federal do Rio de Janeiro
UI - User interface
URI - Uniform Resource Identifier
URL - Uniform Resource Locator
VM - Virtual machine
XML - Extensible Markup Language
x
Sumario
1 Introducao 1
1.1 Tema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Delimitacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.3 Justificativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.5 Metodologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.6 Descricao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2 Principais tecnologias utilizadas 4
2.1 Banco de dados nao relacional . . . . . . . . . . . . . . . . . . . . . . 4
2.2 Node.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3 Express . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4 REST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.5 GraphQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.6 OAuth 2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.7 TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.8 React . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.9 Webpack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.9.1 Babel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.9.2 PostCSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3 Implementacao 13
3.1 Banco de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1.1 Modelagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1.2 Hospedagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
xi
3.2 Servidor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2.1 Conexao com o banco de dados . . . . . . . . . . . . . . . . . 16
3.2.2 Autenticacao . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.2.3 GraphQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2.4 Build e server-side rendering . . . . . . . . . . . . . . . . . . 21
3.2.5 Assets estaticos . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.2.6 Hospedagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.2.7 Fluxo de deploy . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.3 Cliente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.3.1 Rotas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.3.2 Internacionalizacao . . . . . . . . . . . . . . . . . . . . . . . . 31
3.3.3 GraphQL e caching . . . . . . . . . . . . . . . . . . . . . . . . 31
3.3.4 Design responsivo . . . . . . . . . . . . . . . . . . . . . . . . . 32
4 Consideracoes finais 35
4.1 Conclusao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.2 Trabalhos futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.2.1 Acessibilidade . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.2.2 Testes automatizados e continuous integration . . . . . . . . . 36
4.2.3 Code splitting, prefetching e preloading . . . . . . . . . . . . . 37
4.2.4 Progressive Web App . . . . . . . . . . . . . . . . . . . . . . . 38
Bibliografia 39
xii
Lista de Figuras
2.1 Elementos de um middleware do Express . . . . . . . . . . . . . . . . 6
2.2 Exemplo de requisicao GraphQL e resposta (em JSON) . . . . . . . . 7
2.3 Fluxo abstrato do protocolo OAuth 2.0 . . . . . . . . . . . . . . . . . 8
2.4 Exemplo de checagem de tipos do TSC . . . . . . . . . . . . . . . . . 9
2.5 Exemplo de componente React (em JSX) . . . . . . . . . . . . . . . . 10
2.6 Exemplo de traducao do Babel de ES2015 para ES5 . . . . . . . . . . 11
2.7 Exemplo de aplicacao de prefixos de vendor do Autoprefixer . . . . . 12
3.1 Diagrama do modelo do banco de dados . . . . . . . . . . . . . . . . 14
3.2 Exemplo de documento da colecao de entradas . . . . . . . . . . . . . 15
3.3 Diagrama representativo da conexao servidor-BD . . . . . . . . . . . 16
3.4 Conexao do servidor com o banco de dados . . . . . . . . . . . . . . . 17
3.5 Exemplo de acesso a instancia do banco de dados . . . . . . . . . . . 17
3.6 Diagrama de sequencia de uma autenticacao bem-sucedida . . . . . . 18
3.7 Exemplo de schema de uma mutacao . . . . . . . . . . . . . . . . . . 19
3.8 Exemplo de resolver de uma mutacao . . . . . . . . . . . . . . . . . . 20
3.9 Diagrama comparativo entre SPAs e aplicacoes tradicionais . . . . . . 21
3.10 Exemplo de requisicao a uma pagina com SSR . . . . . . . . . . . . . 22
3.11 Trecho da parte inicial do SSR . . . . . . . . . . . . . . . . . . . . . . 23
3.12 Trecho da parte final do SSR . . . . . . . . . . . . . . . . . . . . . . . 23
3.13 Arquivo heroku.yml . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.14 Arquivo Dockerfile . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.15 Pagina de login (/login) . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.16 Pagina inicial (/ ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.17 Pagina de detalhes de uma entrada (/entries/:id) . . . . . . . . . . . 29
3.18 Pagina de criacao de uma entrada (/entries/new) . . . . . . . . . . . 29
xiii
3.19 Pagina de edicao de uma entrada (/entries/:id/edit) . . . . . . . . . . 30
3.20 Pagina de revisao (/review) . . . . . . . . . . . . . . . . . . . . . . . 30
3.21 Comparacao de trechos dos arquivos en US.json e pt BR.json . . . . 31
3.22 Versao mobile da pagina de login . . . . . . . . . . . . . . . . . . . . 33
3.23 Versao mobile da pagina principal . . . . . . . . . . . . . . . . . . . . 34
3.24 Versao mobile da pagina de detalhes de uma entrada . . . . . . . . . 34
xiv
Capıtulo 1
Introducao
1.1 Tema
O tema do trabalho e a elaboracao de uma aplicacao na nuvem que permita
anotacoes de vocabularios e sua posterior revisao. Neste sentido, o projeto esta
diretamente ligado ao estudo de desenvolvimento web (servidor, cliente e banco de
dados) e boas praticas de codigo em geral.
1.2 Delimitacao
Apesar do proposito do programa ser a memorizacao e a facilitacao do aprendi-
zado de idiomas, nao serao estudados os processos cognitivos do ser humano. A
aplicacao sera desenvolvida utilizando certas tecnicas para que funcione em diver-
sos navegadores, porem alguns deles podem nao possuir funcionalidades essenciais
para que tudo rode normalmente. Os modelos de dados de entradas se limitarao
a algumas poucas lınguas. O sistema de autenticacao sera o login pela conta da
Google atraves de OAuth 2.0 [1]. Os planos de servico das duas plataformas na nu-
vem usadas (uma para o banco de dados e uma para o restante da aplicacao) serao
gratuitos e, portanto, podem apresentar restricoes, por exemplo, quanto as taxas de
transferencia de dados.
1
1.3 Justificativa
A habilidade de falar multiplos idiomas ja se tornou relativamente comum; escolas
vem agregando o estudo de lınguas nao nativas aos seus currıculos e criancas tem
ingressado cada vez mais novas em cursos particulares de idiomas.
Mesmo com o aperfeicoamento dos metodos de ensino e de incentivo a participacao
dos alunos nas aulas, grande parte do aprendizado pode ocorrer fora das salas. Com
o advento da Internet e dos smartphones, e possıvel estar em contato com outras
lınguas o tempo todo e de diversas formas; desde jogos e ebooks ate aplicativos
de conversa com nativos. A interacao frequente com novos conteudos forma um
contexto propıcio para aprendizados que, se nao forem devidamente registrados,
podem se perder em meio ao volume significativo de informacoes que sao processadas
ao longo do dia.
E desejavel, portanto, desenvolver ferramentas de anotacao e de administracao
de conhecimento, visando a posterior fixacao dos conceitos adquiridos. Este pro-
jeto propoe uma aplicacao que forneca ao usuario nao apenas essas funcionalidades,
mas tambem benefıcios como a praticidade do acesso aos seus dados em multiplos
dispositivos e a seguranca de um sistema de autenticacao moderno.
1.4 Objetivos
O objetivo geral e desenvolver uma aplicacao web completa, desde o servidor e
o banco de dados ate o cliente. Desta forma, tem-se como objetivos especıficos:
(1) arquitetar e implementar um banco de dados; (2) desenvolver um servidor para
interagir com o banco de dados, lidar com a autenticacao e servir a aplicacao para
o cliente, e; (3) desenhar e implementar um cliente que interaja com o servidor e
ofereca uma boa usabilidade ao usuario.
1.5 Metodologia
O modelo do banco de dados que sera utilizado e o nao relacional, permitindo o
agrupamento de entradas de diferentes formatos sem a necessidade de usar varias
2
colunas esparsas.
As APIs do servidor serao desenvolvidas usando duas tecnologias: REST [2] e
GraphQL [3]. A primeira sera usada para funcionalidades como, por exemplo, o
login por contas da Google atraves do protocolo de seguranca OAuth 2.0 e a entrega
de assets da aplicacao. A segunda, por sua vez, sera usada para a transferencia de
informacoes de entradas do usuario entre o cliente e o servidor, pois permite que
apenas os dados desejados sejam entregues, evitando possıveis desperdıcios.
Visando possibilitar o uso da aplicacao por pessoas com limitacoes de hardware
e, consequentemente, com navegadores mais antigos, serao utilizadas algumas fer-
ramentas para gerar codigo de cliente compatıvel com tais programas. Exemplos
delas sao o compilador Babel [4], que transforma JavaScript moderno em versoes
anteriores do mesmo, e o PostCSS [5] com o plugin Autoprefixer [6], que adaptam
atributos de CSS para engines que nao os suportam.
1.6 Descricao
No capıtulo 2 ha uma breve descricao de cada uma das principais tecnologias
envolvidas no projeto.
A implementacao em si e apresentada no capıtulo 3, o qual e divido em tres
escopos: o banco de dados, o servidor, e o cliente. Ele consiste em explicacoes das
tecnicas utilizadas e do funcionamento da solucao de forma geral.
O capıtulo 4 e composto pela conclusao do trabalho e pelos proximos passos para
evoluı-lo.
3
Capıtulo 2
Principais tecnologias utilizadas
2.1 Banco de dados nao relacional
Um banco de dados nao relacional e um banco de dados que nao usa as relacoes
tabulares do modelo relacional. Ambos os modelos apresentam caracterısticas que
podem ser consideradas vantajosas ou nao, dependendo das prioridades do projeto.
De acordo com Tore Risch [7], enquanto BDs relacionais geralmente submetem
todos os dados ao mesmo conjunto de restricoes ACID [8], os nao relacionais nao
costumam suporta-las; isto faz com que BDs nao relacionais sejam mais ageis, porem
menos precisos que os relacionais. Uma outra diferenca e que BDs nao relacionais
possuem esquemas flexıveis, sendo especialmente uteis para casos com entidades
polimorficas, por exemplo.
Apesar de existirem diversos BDs nao relacionais, a maioria se encaixa em uma
das tres principais categorias: o modelo de documentos, no qual cada documento
possui uma estrutura similar a do JSON, facilita o acesso e a manipulacao de dados,
alem de permitir esquemas diferentes; o modelo de grafos, que, por sua vez, usa
conceitos como “vertice” e “aresta” para representar melhor as relacoes entre suas
entidades; e, finalmente, os modelos chave-valor e de wide columns, que utilizam
apenas uma chave para consultas, portanto podem ter suas performance e escala-
bilidade otimizadas, ao custo de ter os valores completamente opacos ao sistema
[9].
4
2.2 Node.js
Node.js, ou simplesmente “Node”, e um runtime de JavaScript orientado a eventos
assıncronos [10]. A programacao orientada a eventos oferece uma alternativa mais
eficiente e escalavel a modelos que usam multithreading, e a possibilidade de reali-
zar operacoes de I/O de forma assıncrona previne que a aplicacao fique bloqueada
durante elas [11].
O Node permitiu que pessoas ja familiarizadas com JavaScript, como muitos de-
senvolvedores front-end, possam construir aplicacoes server-side sem a necessidade
de aprender uma nova linguagem. Alem de programas web, conseguir executar
codigo fora do browser tambem tornou JavaScript uma opcao viavel para scripting
na linha de comando.
2.3 Express
Express e um framework web feito em cima do Node, simplificando algumas de
suas funcionalidades principais [12]. O Express foca em ser: (1) rapido, ou seja,
ter um bom desempenho; (2) nao opinativo, que envolve nao impor metodos nem
ferramentas especıficas, e; (3) minimalista, por disponibilizar somente o essencial
[13].
Uma de suas pecas fundamentais e chamada “middleware”. Middlewares sao
funcoes que, entre uma chamada ao servidor e seu retorno, tem acesso aos objetos que
representam a requisicao e a resposta. Middlewares podem, portanto, modificar esses
objetos, definir o proximo passo no ciclo requisicao-resposta, e executar qualquer
codigo. A grande vantagem em usa-los e a capacidade de abstracao de uma aplicacao,
que se torna basicamente uma sequencia de chamadas a middlewares [14].
A Figura 2.1 apresenta um exemplo de servidor simples com uma rota (/ ) para
metodos GET de HTTP [16], indicado pelo emprego da funcao get. O middleware e
a funcao com tres argumentos (req, res e next), cujos dois primeiros sao os objetos
referentes a requisicao e a resposta, respectivamente. O argumento next e uma
funcao que impede a execucao do restante do codigo do middleware atual e inicia uma
5
Figura 2.1: Elementos de um middleware do Express. Fonte: [15].
busca pelo proximo, seguindo a regra de formacao de rotas definida pelo primeiro
parametro do get — ou post, put, etc.
2.4 REST
REST e um estilo de arquitetura para o desenvolvimento de servicos web que
focam nos recursos de um sistema, oferecendo um modo flexıvel de servir diferentes
tipos de aplicacoes e ainda manter um padrao de formatacao de dados [17]. Ele
consiste em servidores e clientes, que transferem representacoes de recursos entre si
[18]. Estas transferencias sao iniciadas por requisicoes de um cliente a um servidor
atraves de endpoints, i.e., URLs — ou, mais genericamente, URIs — que disponibi-
lizam APIs.
Segundo Roy Fielding [2], “REST providencia um conjunto de restricoes arquite-
turais que, quando aplicado como um todo, enfatiza a escalabilidade de interacoes
de componentes, a generalidade de interfaces, a implantacao independente de com-
ponentes, e componentes intermediarios para reduzir a latencia de interacao, impor
seguranca, e encapsular sistemas legado.”
2.5 GraphQL
GraphQL e, conforme descrito em sua especificacao [19], “uma linguagem de con-
sulta projetada para construir aplicacoes cliente atraves de uma sintaxe e um sistema
intuitivos e flexıveis para descrever seus requisitos de dados e interacoes”. Enquanto
6
APIs REST costumam disponibilizar um tipo especıfico de recurso em cada end-
point, e comum requisicoes GraphQL fazerem multiplas chamadas HTTP para re-
tornar dados de diferentes recursos. Nao e necessario, no entanto, implementar um
servidor com apenas APIs REST ou GraphQL; ambas podem ser usadas na mesma
aplicacao, permitindo o aproveitamento dos benefıcios de cada uma.
Figura 2.2: Exemplo de requisicao GraphQL e resposta (em JSON)
Por se tratar de uma linguagem de consulta e nao obrigar o uso de nenhuma
linguagem de programacao especıfica, o GraphQL deixa a responsabilidade de pro-
cessar e preparar os dados para o servidor, e, portanto, consegue ser mais declarativa,
como e mostrado na Figura 2.2. Alem disto, a possibilidade de escolher somente os
campos desejados de uma entidade — ao inves de sempre recebe-la por inteiro —
gera economias na transferencia de dados, diminuindo os tamanhos dos pacotes e as
quantidades de informacoes desnecessarias.
2.6 OAuth 2.0
OAuth 2.0 e um protocolo de autorizacao que permite que uma aplicacao obtenha
acesso limitado a um servico HTTP. O OAuth 2.0 define quatro roles : (1) resource
owner, “uma entidade capaz de conceder acesso a um recurso protegido”; (2) resource
server, “o servidor que hospeda os recursos protegidos”; (3) client, “uma aplicacao
fazendo requisicoes de recursos protegidos em nome do resource owner e com sua
autorizacao”, e; (4) authorization server, “o servidor que emite access tokens ao
cliente apos autenticar com sucesso o resource owner e obter autorizacao” [1].
7
Figura 2.3: Fluxo abstrato do protocolo OAuth 2.0. Fonte: [1].
O esquema da Figura 2.3 representa o fluxo de requisicoes e respostas do protocolo.
O processo comeca com a requisicao de autorizacao do client para o resource owner
(A); ela pode ser feita diretamente ou, de preferencia, indiretamente, usando o
authorization server como intermediario. Caso a autorizacao seja concedida o client
recebe uma credencial (B), que esta associada a determinados privilegios. O client,
entao, pede um access token ao authorization server (C), apresentando a credencial
recebida na etapa anterior. Se a credencial for aceita, o authorization server emite
um access token (D), que e necessario para que o client possa solicitar um recurso
protegido ao resource server (E). Finalmente, apos validar o token, o resource server
concede ao client acesso ao recurso escolhido (F).
2.7 TypeScript
De acordo com a especificacao da linguagem [20], TypeScript e um syntactic
sugar para JavaScript. Sua sintaxe e um superconjunto de ECMAScript 2015 [21]
e, portanto, todo programa em JavaScript tambem e um programa em TypeScript.
O compilador de TypeScript gera codigo em JavaScript que se assemelha ao de
entrada, e permite o uso de source maps, os quais facilitam o debugging.
8
Dentre os benefıcios do uso desta linguagem, deve-se destacar seu sistema de tipos.
“Tipos sao essenciais para a evolucao ordenada de sistemas de software grandes.
[...] Tipos providenciam uma forma de controlar a evolucao, atraves da verificacao
parcial de programas em cada etapa. Como a checagem de tipos e mecanica, pode-
se garantir, para uma linguagem bem projetada, que certas classes de erros nao
podem surgir durante a execucao, consequentemente provendo um grau mınimo de
confianca apos cada mudanca. [...] Em conclusao, tipos (e a checagem de tipos)
aumentam a confiabilidade de sistemas de software em evolucao.” [22].
Figura 2.4: Exemplo de checagem de tipos do TSC
2.8 React
React e uma biblioteca de JavaScript voltada para a construcao de UIs [23]. Cada
interface em React e composta por um grupo de pecas, chamadas “componentes”,
com um determinado proposito na pagina.
Componentes podem receber parametros — ou, em React, “props” — que indicam
como eles devem ser exibidos e/ou se comportar, tornando-os altamente adaptaveis
[25]. A semelhanca da pattern de componentes e props com a definicao de uma
“funcao” traz conceitos poderosos ao desenvolvimento front-end, tais como abs-
tracao, composicao e modularidade.
9
Figura 2.5: Exemplo de componente React (em JSX [24])
2.9 Webpack
Webpack e uma ferramenta que analisa uma aplicacao e, a partir do seu grafo
de dependencias, gera uma ou mais bundles com os modulos necessarios [26]. Esta
tecnica traz vantagens como a realizacao de tree shaking, tambem conhecido como
“eliminacao de codigo morto” [27], e a reducao do numero de requisicoes que preci-
sam ser feitas ao servidor — ou a otimizacao da forma como elas acontecem.
Por padrao, o webpack so lida com arquivos JavaScript e JSON. E possıvel,
porem, fazer com que ele consiga processar outros tipos de arquivo atraves de uti-
litarios chamados “loaders”. Alem de carregar os arquivos e adiciona-los ao grafo
de dependencias, o webpack tambem aceita o uso de “plugins”, que modificam seus
conteudos; dois deles sao introduzidos nas subsecoes seguintes.
2.9.1 Babel
Babel e um compilador de JavaScript capaz de converter codigos com funcio-
nalidades mais recentes de ECMAScript em codigos compatıveis com suas versoes
anteriores. Existem alguns metodos por tras destas adaptacoes, como, por exem-
plo, a transformacao da sintaxe e o emprego de polyfills — funcoes que replicam o
10
comportamento de outras funcoes sem o uso de recursos novos da linguagem [28].
Figura 2.6: Exemplo de traducao do Babel de ES2015 para ES5
Desde 2015, novas versoes de ECMAScript vem sido lancadas anualmente [29], in-
troduzindo caracterısticas ineditas e, consequentemente, expandindo o vocabulario
de seus programadores. No entanto, uma parcela consideravel de usuarios da In-
ternet usa versoes de navegadores web cujas engines nao conseguem dar suporte as
ultimas features de JavaScript, justificando a necessidade de ferramentas como o
Babel.
2.9.2 PostCSS
PostCSS e uma biblioteca de JavaScript para manipular CSS programaticamente
[5], i.e., de forma automatizada com programacao. Apesar de oferecer uma API
extensa para a criacao de scripts customizados [30], ja existem diversos plugins
prontos e mantidos pela comunidade para realizar tarefas comuns [31].
Um plugin popular e o Autoprefixer [6], que analisa as propriedades dos arquivos
CSS e aplica prefixos de (browser) vendors [32] aquelas que ainda nao foram estan-
dardizadas ou que nao sao suportadas por certos navegadores. Assim como no caso
11
do Babel, este tipo de processo e importante para aumentar a quantidade de pessoas
que conseguem usufruir de todos os recursos de uma aplicacao, contribuindo para a
construcao de uma Internet mais inclusiva.
Figura 2.7: Exemplo de aplicacao de prefixos de vendor do Autoprefixer. Fonte: [5].
12
Capıtulo 3
Implementacao
3.1 Banco de dados
3.1.1 Modelagem
O banco de dados utilizado e o MongoDB, cujo modelo de documentos flexıveis e
com um formato similar ao JSON facilita suas manipulacao e modelagem [33]. Os
documentos sao organizados em conjuntos chamados “colecoes”.
A modelagem inicial usava apenas uma colecao com um documento por usuario, no
qual seriam reunidas as entradas de suas respectivas autorias em um vetor ordenado
pela data de ultima modificacao. Desta forma, as buscas poderiam ser mais rapidas,
pois todas as entradas referentes a um usuario ja estariam localizadas em um unico
lugar.
O MongoDB, no entanto, limita o tamanho maximo de documentos em 16 megaby-
tes para garantir que um documento nao use quantidades excessivas de RAM ou,
durante a transmissao, de largura de banda [34]. E possıvel criar itens que ultrapas-
sam o tamanho maximo usando a especificacao GridFS [35], mas faze-lo introduziria
a manipulacao de dados uma complexidade desnecessaria, visto que os motivos da
restricao de tamanho envolvem aspectos importantes para esta aplicacao.
Sendo assim, o modelo inicial foi descartado, e a abordagem de agrupar entradas
por usuarios nao foi utilizada. Na versao final, existem duas colecoes para repre-
13
sentar suas principais entidades, e os campos usados como criterios de busca sao
indexados em background para otimizar as consultas.
Figura 3.1: Diagrama do modelo do banco de dados
A primeira colecao e referente aos usuarios da aplicacao. Cada documento tem
dois campos: id, um ObjectId [36] contendo o identificador unico do documento na
colecao, e auth, um objeto com identificadores de um usuario em outros servicos.
Conforme especificado no escopo do projeto, o unico metodo de autenticacao e o
login pela conta da Google e, portanto, google e o atributo que aparece no exemplo.
A segunda colecao, por sua vez, armazena todas as entradas de todos os usuarios.
A Figura 3.2 mostra um objeto que representa uma entrada e suas informacoes. Sao
estas:
• id : o identificador unico do documento na colecao;
• dateTime: uma instancia da classe Date do JavaScript [37] com a data e o
horario da ultima modificacao, cuja representacao em string segue a norma
ISO 8601 [38];
• description : a descricao da entrada, como seu significado, por exemplo;
14
Figura 3.2: Exemplo de documento da colecao de entradas
• language: o idioma da entrada, representado por uma string de dois carac-
teres;
• tags: um vetor com rotulos que, para o usuario, definem e classificam a
entrada;
• title: o tıtulo da entrada, geralmente uma palavra ou expressao;
• Hiragana : um exemplo de campo extra, cujos valor e chave sao escolhidos
pelo usuario para cada entrada, contanto que a chave nao seja igual a uma das
fixas;
• userId : o identificador unico do documento correspondente ao usuario na
colecao de usuarios.
3.1.2 Hospedagem
A hospedagem do banco de dados e feita no mLab [39], um servico na nuvem que
foi recentemente adquirido pela MongoDB Inc. [40]. A plataforma oferece um plano
sandbox [41] gratuito com 500 megabytes de armazenamento, alem de permitir a
escolha do provedor de nuvem entre a Amazon, a Google e a Microsoft Azure; este
projeto usa a Amazon.
15
3.2 Servidor
3.2.1 Conexao com o banco de dados
A MongoDB disponibiliza um driver para Node [42], o qual e utilizado para
estabelecer conexoes entre o servidor e o banco de dados, realizar operacoes de
CRUD, etc. O driver simplifica o processo de conexao, sendo apenas necessario
informar o nome e a URI do BD.
Figura 3.3: Diagrama representativo da conexao servidor-BD. Fonte: [43].
O cliente presente no driver usa “connection pooling”, uma tecnica de caching
de conexoes ao banco de dados que reaproveita conexoes existentes quando novas
precisam ser feitas [44]. Buscando reduzir o numero de pools criadas pela aplicacao, o
metodo assıncrono connect do cliente e chamado uma vez e, a partir da sua resposta,
e gerada uma instancia do BD, que e reutilizada durante todo o ciclo de vida do
servidor.
Para que a instancia do BD esteja disponıvel dentro dos middlewares, e usado o
objeto app.locals, cujas propriedades persistem ate o termino da aplicacao [45]. As
Figuras 3.4 e 3.5 apresentam, respectivamente, a atribuicao do BD a propriedade db
do objeto app.locals e um exemplo de middleware que a acessa.
16
Figura 3.4: Conexao do servidor com o banco de dados
Figura 3.5: Exemplo de acesso a instancia do banco de dados
17
3.2.2 Autenticacao
A autenticacao e feita com contas da Google na rota /auth/google, atraves do pro-
tocolo OAuth 2.0. A biblioteca Passport.js [46] e usada para orquestrar e simplificar
o fluxo de login por meio de um mecanismo chamado “estrategia”.
Apos o usuario passar pela autenticacao da Google, o servidor procura na colecao
de usuarios do BD por um documento que possua o ID associado a sua conta da
Google; caso nao exista, um novo documento e criado. O Passport.js, entao, insere
o ID do documento no campo user do objeto referente a requisicao, podendo ser
consultado por outros middlewares.
A sessao e armazenada no cliente em um cookie criptografado com a validade de 30
dias, e pode ser encerrada pela rota de logout (/auth/logout). Se o cookie nao existir,
estiver expirado ou for invalido, o acesso a qualquer rota privada e redirecionado
para a de autenticacao.
Figura 3.6: Diagrama de sequencia de uma autenticacao bem-sucedida
18
3.2.3 GraphQL
O servidor GraphQL e construıdo com o Apollo Server [47], uma ferramenta
para implementar servidores que seguem essa especificacao e conseguem responder
a consultas de qualquer cliente GraphQL. A interacao e feita atraves do endpoint
/graphql, que aceita requisicoes com o metodo POST de HTTP.
Figura 3.7: Exemplo de schema de uma mutacao
Um exemplo de operacao que altera dados, chamada “mutacao”, e representada
na Figura 3.7. Esse trecho do codigo faz parte de um schema, i.e., uma descricao dos
tipos e das operacoes oferecidas por um servico GraphQL, escrita em uma linguagem
propria para mante-lo agnostico quanto a linguagem de programacao usada [48].
Para que uma mutacao cause os efeitos desejados, no entanto, e preciso que alguma
funcao do servidor execute as devidas etapas; este tipo de funcao e conhecido como
“resolver”.
19
Figura 3.8: Exemplo de resolver de uma mutacao
A Figura 3.8 mostra o resolver responsavel pela mutacao createEntry. Seu pri-
meiro passo e checar se o usuario foi autenticado e, se nao tiver sido, retornar um
erro. Apos isto, os dados sao validados e formatados, e a nova entrada e armazenada
no banco de dados. Se algo de errado acontecer neste processo, e enviado um erro
ao cliente. Caso contrario, a entrada criada e entregue.
20
3.2.4 Build e server-side rendering
Single-page applications (SPAs) sao aplicacoes web que, em vez de solicitar no-
vos documentos HTML ao servidor a cada navegacao, realizam chamadas AJAX e
manipulam a pagina no lado do cliente para renderizar o conteudo adequado. As
vantagens mais perceptıveis de SPAs para os usuarios sao a velocidade e a fluidez
das respostas as suas acoes.
Figura 3.9: Diagrama comparativo entre SPAs e aplicacoes tradicionais. Fonte: [49].
Para que o servidor possa entregar ao cliente uma bundle com o codigo necessario
para rodar a SPA, e preciso percorrer e preparar antecipadamente a pagina acessada
e, possivelmente, o restante da aplicacao. Este processo e conhecido como “server-
side rendering” (SSR), e traz benefıcios como SEO e reducao do tempo para o first
meaningful paint [50].
O codigo do cliente, no entanto, deve passar por algumas etapas durante o build
para que esteja suficientemente otimizado e pronto para o SSR. O responsavel por
isto e o webpack, cujas etapas envolvem o TSC, o Babel, o PostCSS com Autoprefi-
xer, e o carregamento dos demais arquivos, tais como operacoes GraphQL, imagens,
fontes, etc.
A sequencia de passos do SSR e apresentada nas Figuras 3.11 e 3.12. A primeira
comeca com a criacao de uma instancia do Apollo Client e a importacao do codigo
do cliente apos o build. A aplicacao cliente e, entao, colocada dentro de dois ou-
tro componentes: o ApolloProvider, que injeta o Apollo Client no contexto React
[52], e o StaticRouter, que e basicamente um roteador cuja URL nunca muda [53].
Alem disto, o valor do header HTTP “Accept-Language” [54] e passado a aplicacao
21
Figura 3.10: Exemplo de requisicao a uma pagina com SSR. Fonte: [51].
cliente, que o utilizara para definir o idioma da renderizacao inicial; a estrutura de
internacionalizacao e discutida com mais detalhes na Subsecao 3.3.2.
No final desta primeira parte do SSR, a aplicacao encapsulada e percorrida e
todos os seus dados sao transformados em uma unica string. Se a pagina requisitada
possuir dados dinamicos que seriam entregues por GraphQL, estes sao carregados
sincronicamente e tambem adicionados a essa string.
A segunda parte consiste na geracao da resposta que sera enviada ao cliente.
Antes da preparacao do arquivo HTML com a pagina, e checada a propriedade url
do contexto do roteador, que indica se a requisicao deve ser redirecionada para outra
rota [53]. Se nao for este o caso, o proximo passo e coletar o tıtulo desejado para
o documento com o metodo rewind do React Document Title [55], um componente
React que auxilia na administracao desse valor no cliente e sua leitura no servidor.
Em seguida, e extraıdo o estado inicial do Apollo Client, ou seja, o conjunto
de dados dinamicos servidos por GraphQL da pagina sendo renderizada. Todas
22
Figura 3.11: Trecho da parte inicial do SSR
Figura 3.12: Trecho da parte final do SSR
23
as informacoes adquiridas sao passadas ao componente React Html, que representa
o HTML da pagina. Internamente, este componente tambem injeta um script no
HTML, cuja funcao e carregar um objeto JavaScript com os dados dinamicos na
variavel global window do navegador. Este objeto e posteriormente usado para
inicializar o cache do Apollo Client, um processo importante chamado “store rehy-
dration” [56]; o caching no cliente e abordado na Subsecao 3.3.3. Desta forma, e
possıvel evitar que sejam feitas consultas GraphQL desnecessarias, pois os dados
renderizados no HTML como texto puro tambem estao armazenados em objetos.
Para transformar a representacao retornada pelo Html em algo que possa ser
interpretado pelo navegador, a funcao renderToStaticMarkup do ReactDOMServer
e usada, cuja saıda e uma string com o conteudo do componente [57]. Com o HTML
pronto, a resposta e despachada ao cliente com o status code HTTP apropriado, que
e determinado pelo contexto do roteador.
Quanto ao codigo do servidor, tambem e preciso um processo de build, pois o
Node nao consegue executar codigo TypeScript nem certas funcoes mais recentes
de JavaScript. Sendo assim, o TSC e o Babel sao usados para gerar ECMAScript
compatıvel com o Node.
3.2.5 Assets estaticos
Os assets estaticos sao servidos na rota /static, que atende a requisicoes GET.
Em sites e aplicacoes que nao sao single-page, o cliente costuma fazer requisicoes ao
servidor para cada asset, como imagens, style sheets, fontes, etc.
Por se tratar de uma SPA, e interessante que os assets da pagina sejam inseridos na
bundle entregue ao cliente na primeira resposta. Portanto, os unicos assets estaticos
disponıveis na rota /static sao style sheets para normalizar os estilos padroes dos
navegadores, e o favicon da aplicacao.
24
3.2.6 Hospedagem
A hospedagem do servidor e feita no Heroku, uma plataforma na nuvem para fazer
deploy, gerenciar e escalar aplicacoes [58]. O plano gratuito oferece 512 megabytes
de RAM para cada instancia e 1000 horas de computacao por conta por mes. Para
evitar o desperdıcio de recursos, aplicacoes hospedadas no plano gratuito hibernam
apos 30 minutos de inatividade e, portanto, o primeiro acesso depois desse perıodo
leva mais tempo que o normal.
3.2.7 Fluxo de deploy
A forma de fazer deploy de versoes da aplicacao no Heroku e atraves da ferramenta
de versionamento Git [59]. Ao realizar o comando de push na branch master, o build
e inicializado e, com seu termino, a nova versao e lancada. As configuracoes e etapas
do build sao determinadas a partir de dois arquivos: heroku.yml e Dockerfile.
O primeiro e um arquivo YAML [60] que permite a especificacao de detalhes
para cada subprocesso do deploy : setup, build, release e run [61]. Neste projeto, o
heroku.yml serve apenas para indicar que o processo e do tipo “web” e que as etapas
de build estao descritas no arquivo Dockerfile, como pode ser visto na Figura 3.13.
Figura 3.13: Arquivo heroku.yml
O segundo arquivo, Dockerfile, e um documento de texto usado pelo Docker [62]
no Heroku. O Docker e uma plataforma que usa instancias runtime da imagem de
uma aplicacao, chamadas “containers”, para automatizar e facilitar o deploy [63].
Containers sao comparaveis a maquinas virtuais (VMs), porem rodam nativamente
no Linux e compartilham o kernel da maquina host com outros containers, poupando
recursos que seriam desnecessariamente gastos em VMs.
25
Figura 3.14: Arquivo Dockerfile
A Figura 3.14 mostra o Dockerfile deste projeto. O primeiro comando indica que
a imagem base e a “node:10 ”, uma imagem com a versao 10 do Node. O penultimo
comando executa uma serie de scripts que realizam os passos de build explicados
na Subsecao 3.2.4. Por fim, o ultimo comando usa o PM2 [64], uma ferramenta de
monitoramento e gerenciamento de processos do Node, para inicializar a aplicacao.
Alem disto, sao passados argumentos para fazer com que o garbage collector seja
executado com mais frequencia e limitar o uso de memoria, tendo em mente os 512
megabytes de RAM do container [65].
3.3 Cliente
3.3.1 Rotas
O roteamento no cliente e configurado com o React Router, um framework com
componentes React de navegacao [66]. De acordo com sua documentacao [67], o
React Router nao usa o roteamento estatico empregado em grande parte dos fra-
26
meworks, no qual as rotas sao declaradas antes de qualquer renderizacao. O mo-
delo utilizado e o de roteamento dinamico, que ocorre durante a renderizacao da
aplicacao, oferecendo mais flexibilidade e incentivando a componentizacao.
Figura 3.15: Pagina de login (/login)
Enquanto o login nao for efetuado, a unica rota disponıvel e /login, cuja pagina
esta representada na Figura 3.15. Usuarios nao autenticados nao podem acessar
nenhuma outra pagina e, se tentarem faze-lo, serao redirecionados para a de login.
As demais rotas sao:
• / : Pagina inicial. Visto que as anotacoes sao o foco principal da aplicacao, a
pagina inicial contem a listagem de entradas ou, no caso de nao haver nenhuma,
uma mensagem convidando o usuario a criar sua primeira. Cada anotacao e,
na verdade, um link para a pagina de detalhes correspondente.
• /entries/:id : Pagina de detalhes ou de criacao de uma entrada. O compo-
nente “:id” da rota e uma variavel, indicando que sua regra de formacao inclui
um certo identificador; e a mesma notacao usada pelo React Router. Se :id for
o ID de uma anotacao, o usuario pode ver todos seus dados, alem de excluı-la
27
ou edita-la. No entanto, se o valor de :id for “new”, o formulario de criacao
de entrada e renderizado.
• /entries/:id/edit : Pagina de edicao de uma entrada. O formulario de
criacao de entrada tambem e usado nessa pagina, porem com os dados existen-
tes ja preenchidos. O usuario pode altera-los e/ou inserir novas informacoes,
atualizando a anotacao no banco de dados.
• /review : Pagina de revisao. O objetivo deste modo e exercitar a memoria do
usuario e permitir a checagem do aprendizado dos conceitos anotados. Apesar
de conter a mesma lista de anotacoes que a pagina inicial, seus dados ficam
ocultos, com excecao do tıtulo, e o botao de criacao nao e renderizado. Ao cli-
car em uma anotacao, as informacoes ocultas sao reveladas para que o usuario
possa conferir se suas suposicoes estao corretas.
As paginas correspondentes as rotas listadas acima sao mostradas, seguindo a
mesma ordem, nas Figuras 3.16, 3.17, 3.18, 3.19 e 3.20.
Figura 3.16: Pagina inicial (/ )
28
Figura 3.17: Pagina de detalhes de uma entrada (/entries/:id)
Figura 3.18: Pagina de criacao de uma entrada (/entries/new)
29
Figura 3.19: Pagina de edicao de uma entrada (/entries/:id/edit)
Figura 3.20: Pagina de revisao (/review)
30
3.3.2 Internacionalizacao
A internacionalizacao desta aplicacao e gerenciada atraves da biblioteca React
Intl, que fornece componentes e APIs para formatar datas, numeros, e textos [68]. O
React Intl possui um componente React chamado “IntlProvider”, que pode receber
um objeto de mensagens e o idioma escolhido, entre outros parametros [69].
O IntlProvider costuma ser colocado em um nıvel alto da arvore de componentes,
pois apenas os componentes abaixo dele tem acesso a certos utilitarios e aos textos
da aplicacao. Para usufruir de todas as funcionalidades da biblioteca, e preciso
carregar os modulos que ditam as regras de formatacao de texto e de tempo relativo
para os idiomas disponıveis [70].
As mensagens deste projeto estao disponibilizadas em tres lınguas: portugues,
ingles e espanhol. Conforme mencionado na Subsecao 3.2.4, o idioma e definido a
partir das configuracoes do browser do usuario, que sao enviadas ao servidor pelo
header Accept-Language. Os textos sao armazenados em tres arquivos JSON (en -
US.json, es AR.json e pt BR.json), cujas chaves devem ser iguais; a comparacao do
mesmo trecho de dois desses arquivos, en US.json e pt BR.json, pode ser vista na
Figura 3.21.
Figura 3.21: Comparacao de trechos dos arquivos en US.json e pt BR.json
3.3.3 GraphQL e caching
O Apollo Client [71], um cliente GraphQL integravel com React, e responsavel
pela conexao com o endpoint GraphQL do servidor e viabiliza a administracao dos
31
dados recebidos, que sao guardados em um objeto chamado “store”. Um dos maiores
benefıcios do Apollo e a facilidade de configurar e manipular esse cache local [72].
Uma forma simples de manipulacao e a mudanca da fetch policy de uma operacao,
i.e., a polıtica seguida pelo Apollo ao buscar dados [73]. A fetch policy padrao e
“cache first”, na qual o cache e sempre consultado antes de ser feita uma requisicao
ao servidor, reduzindo o numero de chamadas durante a renderizacao.
Outro metodo de modificar o cache e o acesso direto, que consiste, como o nome
indica, em acessar e alterar manualmente o store; esta tecnica e especialmente util
para lidar com vetores e paginacao. As mutacoes de criacao e de exclusao de entra-
das, por exemplo, alteram a quantidade de elementos da pagina principal. Nestes
processos, e inevitavel a comunicacao com o servidor, visto que informacoes do
banco de dados precisam ser atualizadas. No entanto, ao voltar a pagina principal,
as entradas presentes no store nao refletem mais o estado atual do BD.
Uma maneira de manter a aplicacao consistente seria solicitar novamente ao ser-
vidor todas as entradas, que e chamado “refetch”. Esta forma de atualizacao pode
se tornar lenta e gerar gastos relativamente altos de recursos conforme o numero de
anotacoes aumenta.
A solucao usada nesta aplicacao, por sua vez, e a de receber os dados da entrada
adicionada ou deletada na resposta da operacao GraphQL, e editar o vetor de entra-
das do store para refletir o novo estado. Desta maneira, apenas a chamada referente
a mutacao e feita ao servidor, poupando recursos e oferecendo uma experiencia mais
rapida e fluida ao usuario.
3.3.4 Design responsivo
O Responsive Web Design (RWD) e uma metodologia de web design na qual
paginas devem ser planejadas para se adaptar e mudar sua apresentacao de acordo
com o dispositivo usado para acessa-las. Dentre as vantagens de seu emprego,
destacam-se as possibilidades de ocultar ou exibir certos conteudos em dispositi-
vos mobile, e de permitir que o usuario navegue pela aplicacao com mais facilidade
32
[74].
O artifıcio utilizado para tornar as paginas responsivas e a “media query”, uma
forma de avaliar um ou mais parametros de um dispositivo e aplicar as devidas classes
CSS [75]. As adaptacoes usadas neste projeto incluem transformacoes de textos de
botoes em ıcones, redimensionamento de elementos, e diminuicao de fontes.
A versao mobile de algumas das paginas apresentadas na Subsecao 3.3.1 sao exi-
bidas nas Figuras 3.22, 3.23 e 3.24.
Figura 3.22: Versao mobile da pagina de login
33
Figura 3.23: Versao mobile da pagina principal
Figura 3.24: Versao mobile da pagina de detalhes de uma entrada
34
Capıtulo 4
Consideracoes finais
4.1 Conclusao
Este trabalho buscou explorar ferramentas e tecnicas modernas de desenvolvi-
mento web, enquanto resolvia problemas comuns deste tipo de software e propunha
metodos de otimizacao dos processos envolvidos. A solucao final utiliza, em sua
maioria, tecnologias de ponta, que tambem sao empregadas por diversos produtos
de grandes empresas.
Sob um olhar objetivo, a Secao 1.4 definiu como meta do projeto a elaboracao
das tres partes principais de uma aplicacao web: o banco de dados, o servidor, e o
cliente. A primeira tinha um carater mais teorico, devido ao foco em modelagem, e
a relativa facilidade de hospedar o BD e configurar a plataforma.
As demais partes requereram, alem de decisoes arquiteturais, abordagens praticas
para lidar com os desafios surgidos. No lado do servidor, a interacao com o banco
de dados e a construcao da API GraphQL foram passos que demandaram um bom
entendimento do instrumental disponıvel, pois atingem diretamente os tempos das
respostas e, consequentemente, o desempenho da aplicacao.
A organizacao dos componentes e das rotas do cliente foram especialmente impac-
tadas pela estruturacao planejada do projeto e pela aplicacao de boas praticas de
programacao, que contribuıram para a estabilidade dos fluxos e evitaram a necessi-
dade de refatorar o codigo com frequencia. Porem, diferente do servidor, o cliente
35
tambem precisou de solucoes inteligentes de administracao de cache local e de nocoes
de design para oferecer uma experiencia fluida, consistente e agradavel ao usuario.
Quanto as motivacoes descritas na Secao 1.3, sao disponibilizados os recursos ne-
cessarios para estudantes de lınguas fazerem anotacoes, revisa-las, e acessa-las na
nuvem com seguranca. No entanto, o modo de revisao trata-se apenas de uma
prova de conceito e, por este motivo, provavelmente nao oferece o melhor auxılio
possıvel no processo de aprendizado. Para aumentar o potencial desta aplicacao
como ferramenta de apoio ao estudo de idiomas, seria necessaria a ajuda de profis-
sionais especializados em assuntos que estao fora do escopo deste trabalho, como a
psicologia cognitiva.
4.2 Trabalhos futuros
4.2.1 Acessibilidade
Acessibilidade e a pratica de fazer com que sites possam ser usados pela maior
quantidade de pessoas possıvel; nao e apenas focada em grupos com deficiencias,
mas tambem, por exemplo, em usuarios de dispositivos moveis ou com conexoes de
rede lentas [76]. “Da mesma forma que nao e certo excluir alguem de um predio por
estar em uma cadeira de rodas [...], tambem nao e certo excluir alguem de um site
por ter uma deficiencia visual”.
Conforme apresentado ao longo do Capıtulo 3, este projeto ja aplica tecnicas para
reduzir gastos de largura de banda e oferecer uma experiencia personalizada para
dispositivos moveis. Porem, ha diversos pontos a serem aprimorados, tais como
permitir que usuarios que nao conseguem utilizar mouses possam usufruir de todas
as funcionalidades somente com o teclado, e adaptar melhor os elementos das paginas
para leitores de tela [77].
4.2.2 Testes automatizados e continuous integration
O processo de testar software e, de uma forma geral, a aplicacao de dados, ou
“estımulos”, na entrada de uma porcao de codigo, e a posterior checagem se seu
36
comportamento e/ou resultado estao de acordo com determinados requisitos e es-
pecificacoes [78]. Existem diversos tipos de testes, como os unitarios, de regressao,
de integracao, de interface, etc. Cada teste possui um proposito especıfico diferente,
mas todos tem um objetivo maior em comum: evitar que erros ocorram em uma
aplicacao.
Durante o desenvolvimento, costuma-se executar localmente os testes para ter
certeza de que as mudancas feitas nao introduzem novos bugs. No entanto, nao e
seguro confiar que todos os desenvolvedores do projeto terao a disciplina de verificar
se seus codigos foram devidamente testados, visto que, por exemplo, testes locais
podem ser desativados.
Existem algumas tecnicas para prevenir que alteracoes causem problemas que te-
riam sido detectados por testes automatizados; dentre elas, o continuous integration
(CI). “Continuous integration e uma pratica de engenharia de software na qual in-
sercoes e modificacoes no codigo sao imediatamente testadas e avaliadas antes de
serem integradas ao repositorio.” [79]. Desta forma, erros podem ser mais facilmente
evitados e, consequentemente, os desenvolvedores conseguem evoluir a aplicacao com
mais confianca.
4.2.3 Code splitting, prefetching e preloading
Segundo a documentacao do webpack [80], code splitting e uma funcionalidade que
permite a separacao do codigo em varias bundles, cuja transferencia pode ser feita
sob demanda ou em paralelo. Com o code splitting, e possıvel a geracao de bundles
menores e um maior controle sobre a priorizacao no carregamento de recursos.
Alem disto, o webpack disponibiliza as diretivas webpackPrefetch e webpackPre-
load, que podem ser usadas em importacoes de modulos para inserir elementos link
[81] no Head da pagina. A webpackPrefetch esta relacionada com o prefetch [82],
um resource hint de links que indica que um recurso e provavelmente necessario
para uma navegacao futura, fazendo com que o navegador o carregue quando estiver
ocioso.
37
A webpackPreload, por sua vez, tem ligacao com a palavra-chave preload [83],
usada para declarar preload links. Este tipo de link aponta para um recurso que
sera necessario durante a navegacao atual, fazendo com que ele seja transferido
paralelamente ao restante dos scripts da pagina.
O emprego da webpackPreload deve ser feito com cuidado, pois pode introduzir
certos problemas, como o desperdıcio de largura de banda. Porem, se aplicadas
corretamente, ambas as diretivas sao capazes de causar um grande impacto nos
tempos de carregamento.
4.2.4 Progressive Web App
Progressive Web Apps (PWAs) sao aplicacoes web que se comportam como apps
nativas. De acordo com o Google Developers [84], “sao experiencias de usuario que
tem o alcance da web e sao confiaveis, rapidas e cativantes”.
A confiabilidade diz respeito ao carregamento instantaneo e ao funcionamento
independente das condicoes da conexao de rede, que sao possıveis gracas a scripts
chamados “service workers”. Os service workers sao executados em segundo plano
pelo navegador, separadamente de paginas web e com um ciclo de vida proprio [85].
A rapidez e justificada pelo curto tempo de resposta as interacoes do usuario e
pelas animacoes fluidas. E, por ultimo, comportar-se como apps nativas e oferecer
experiencias imersivas tornam PWAs cativantes.
Para que uma aplicacao web seja uma PWA, e preciso que ela cumpra uma serie
de requisitos, tais como ser servida por HTTPS, possuir paginas responsivas em
dispositivos moveis, etc [86]. Dentre seus benefıcios estao as possibilidades de enviar
push notifications e de adicionar um ıcone a tela inicial, alem de rodar em tela cheia
[87].
38
Referencias Bibliograficas
[1] HARDT, D., The OAuth 2.0 authorization framework, Report, 2012.
[2] FIELDING, R. T., TAYLOR, R. N., Architectural styles and the design of
network-based software architectures, v. 7. University of California, Irvine Irvine,
USA, 2000.
[3] “GraphQL — A query language for your API”, https://graphql.org/, acesso
em 13 de Janeiro de 2019.
[4] “Babel · The compiler for next generation JavaScript”, https://babeljs.io/,
acesso em 13 de Janeiro de 2019.
[5] “PostCSS - a tool for transforming CSS with JavaScript”, https://postcss.
org/, acesso em 13 de Janeiro de 2019.
[6] “postcss/autoprefixer: Parse CSS and add vendor prefixes to rules by Can I
Use”, https://github.com/postcss/autoprefixer, acesso em 13 de Janeiro
de 2019.
[7] LEAVITT, N., “Will NoSQL databases live up to their promise?”, Computer,
v. 43, n. 2, 2010.
[8] HAERDER, T., REUTER, A., “Principles of transaction-oriented database
recovery”, ACM Computing Surveys (CSUR), v. 15, n. 4, pp. 287–317, 1983.
[9] MongoDB, Inc., Top 5 Considerations When Evaluating NoSQL Databases,
Report, jun 2018.
[10] “About — Node.js”, https://nodejs.org/en/about/, acesso em 19 de Janeiro
de 2019.
39
[11] TILKOV, S., VINOSKI, S., “Node.js: Using JavaScript to build high-
performance network programs”, IEEE Internet Computing, v. 14, n. 6, pp. 80–
83, 2010.
[12] PETERS, C., “Building Rich Internet Applications with Node.js and Ex-
press.js”, Rich Internet Applications w/HTML and Javascript, p. 15, 2017.
[13] “Express - Node.js web application framework”, https://expressjs.com/,
acesso em 19 de Janeiro de 2019.
[14] “Using Express middleware”, https://expressjs.com/en/guide/using-
middleware.html, acesso em 19 de Janeiro de 2019.
[15] “Writing middleware for use in Express apps”, https://expressjs.com/en/
guide/writing-middleware.html, acesso em 19 de Janeiro de 2019.
[16] FIELDING, R., GETTYS, J., MOGUL, J., et al., Hypertext transfer protocol–
HTTP/1.1, Report, 1999.
[17] RODRIGUEZ, A., “Restful web services: The basics”, IBM developerWorks,
v. 33, 2008.
[18] CASTILLO, P. A., BERNIER, J. L., ARENAS, M. G., et al., “SOAP vs
REST: Comparing a master-slave GA implementation”, arXiv preprint ar-
Xiv:1105.4978, , 2011.
[19] “GraphQL”, https://facebook.github.io/graphql/June2018/, jun 2018,
acesso em 13 de Janeiro de 2019.
[20] “TypeScript/spec.md at master · Microsoft/TypeScript”, https://github.
com/Microsoft/TypeScript/blob/master/doc/spec.md, 2016, acesso em 13
de Janeiro de 2019.
[21] “ECMAScript 2015 Language Specification – ECMA-262 6th Edition”, https:
//www.ecma-international.org/ecma-262/6.0/index.html, 2015, acesso
em 15 de Janeiro de 2019.
[22] CARDELLI, L., Typeful programming. Springer-Verlag, 1991.
40
[23] “React – A JavaScript library for building user interfaces”, https://reactjs.
org/, acesso em 22 de Janeiro de 2019.
[24] “Introducing JSX – React”, https://reactjs.org/docs/introducing-jsx.
html, acesso em 19 de Janeiro de 2019.
[25] “Components and Props – React”, https://reactjs.org/docs/components-
and-props.html, acesso em 19 de Janeiro de 2019.
[26] “Concepts — webpack”, https://webpack.js.org/concepts/, acesso em 19
de Janeiro de 2019.
[27] “Tree shaking — MDN”, https://developer.mozilla.org/en-US/docs/
Glossary/Tree_shaking, acesso em 19 de Janeiro de 2019.
[28] “What is Babel? · Babel”, https://babeljs.io/docs/en/, acesso em 18 de
Janeiro de 2019.
[29] “JavaScript language resources — MDN”, https://developer.mozilla.org/
en-US/docs/Web/JavaScript/Language_Resources, acesso em 18 de Janeiro
de 2019.
[30] “Home - Documentation”, http://api.postcss.org/, acesso em 19 de Janeiro
de 2019.
[31] “postcss/plugins.md at master · postcss/postcss”, https://github.com/
postcss/postcss/blob/master/docs/plugins.md, acesso em 19 de Janeiro
de 2019.
[32] “Vendor Prefix — MDN”, https://developer.mozilla.org/en-US/docs/
Glossary/Vendor_Prefix, acesso em 19 de Janeiro de 2019.
[33] “MongoDB”, https://www.mongodb.com/what-is-mongodb, acesso em 13 de
Fevereiro de 2019.
[34] “MongoDB Limits and Thresholds – MongoDB Manual”, https://docs.
mongodb.com/manual/reference/limits/, acesso em 12 de Fevereiro de 2019.
41
[35] “GridFS – MongoDB Manual”, https://docs.mongodb.com/manual/core/
gridfs/, acesso em 12 de Fevereiro de 2019.
[36] “ObjectId – MongoDB Manual”, https://docs.mongodb.com/manual/
reference/method/ObjectId/, acesso em 12 de Fevereiro de 2019.
[37] “Date - JavaScript — MDN”, https://developer.mozilla.org/en-US/
docs/Web/JavaScript/Reference/Global_Objects/Date, acesso em 12 de
Fevereiro de 2019.
[38] “ISO 8601 Date and time format”, https://www.iso.org/iso-8601-date-
and-time-format.html, acesso em 12 de Fevereiro de 2019.
[39] “mLab: Cloud-hosted MongoDB”, https://mlab.com/, acesso em 13 de Feve-
reiro de 2019.
[40] “mLab is becoming a part of MongoDB, Inc.”, https://blog.mlab.com/2018/
10/mlab-is-becoming-a-part-of-mongodb-inc/, acesso em 13 de Fevereiro
de 2019.
[41] “Pricing — mLab Cloud MongoDB Hosting”, https://mlab.com/plans/
pricing, acesso em 13 de Fevereiro de 2019.
[42] “MongoDB Node.js Driver”, https://mongodb.github.io/node-mongodb-
native/3.1/, acesso em 17 de Fevereiro de 2019.
[43] “Using MongoDB With Node.js — MongoDB”, https://www.mongodb.
com/blog/post/the-modern-application-stack-part-2-using-mongodb-
with-nodejs, acesso em 23 de Marco de 2019.
[44] “MongoClient or how to connect in a new and better way – MongoDB Node.JS
Driver 1.4.9 documentation”, https://mongodb.github.io/node-mongodb-
native/driver-articles/mongoclient.html#mongoclient-connection-
pooling, acesso em 17 de Fevereiro de 2019.
[45] “Express 4.x - API Reference”, https://expressjs.com/en/api.html#app.
locals, acesso em 23 de Fevereiro de 2019.
42
[46] “Passport.js”, http://www.passportjs.org/, acesso em 14 de Fevereiro de
2019.
[47] “Introduction — Apollo Server”, https://www.apollographql.com/docs/
apollo-server/, acesso em 17 de Fevereiro de 2019.
[48] “Schemas and Types — GraphQL”, https://graphql.org/learn/schema/,
acesso em 17 de Fevereiro de 2019.
[49] “Optimization of AngularJS Single-Page Applications for Web Crawlers —
TO THE NEW Blog”, http://www.tothenew.com/blog/optimization-of-
angularjs-single-page-applications-for-web-crawlers/, acesso em 23
de Marco de 2019.
[50] “First Meaningful Paint — Tools for Web Developers — Google Deve-
lopers”, https://developers.google.com/web/tools/lighthouse/audits/
first-meaningful-paint, acesso em 17 de Fevereiro de 2019.
[51] “The Benefits of Server Side Rendering Over Client Side Rende-
ring”, https://medium.com/walmartlabs/the-benefits-of-server-side-
rendering-over-client-side-rendering-5d07ff2cefe8, acesso em 23 de
Marco de 2019.
[52] “Get started — Apollo Client”, https://www.apollographql.com/docs/
react/essentials/get-started.html#creating-provider, acesso em 23 de
Fevereiro de 2019.
[53] “React Router: Declarative Routing for React.js”, https://reacttraining.
com/react-router/web/api/StaticRouter, acesso em 23 de Fevereiro de
2019.
[54] “Accept-Language - HTTP — MDN”, https://developer.mozilla.org/en-
US/docs/Web/HTTP/Headers/Accept-Language, acesso em 19 de Fevereiro de
2019.
[55] “gaearon/react-document-title: Declarative, nested, stateful, isomorphic do-
cument.title for React”, https://github.com/gaearon/react-document-
title, acesso em 24 de Fevereiro de 2019.
43
[56] “Server-side rendering — Apollo Client”, https://www.apollographql.com/
docs/react/features/server-side-rendering.html#store-rehydration,
acesso em 20 de Fevereiro de 2019.
[57] “ReactDOMServer – React”, https://reactjs.org/docs/react-dom-
server.html#rendertostaticmarkup, acesso em 23 de Fevereiro de 2019.
[58] “About Heroku — Heroku”, https://www.heroku.com/about, acesso em 17
de Fevereiro de 2019.
[59] “Git”, https://git-scm.com/, acesso em 17 de Fevereiro de 2019.
[60] “The Official YAML Web Site”, https://yaml.org/, acesso em 17 de Fevereiro
de 2019.
[61] “Building Docker Images with heroku.yml — Heroku Dev Center”,
https://devcenter.heroku.com/articles/build-docker-images-
heroku-yml#heroku-yml-overview, acesso em 17 de Fevereiro de 2019.
[62] “Enterprise Container Platform — Docker”, https://www.docker.com/,
acesso em 17 de Fevereiro de 2019.
[63] “Get Started, Part 1: Orientation and setup — Docker Documentation”,
https://docs.docker.com/get-started/, acesso em 17 de Fevereiro de 2019.
[64] “PM2 - Advanced Node.js process manager”, http://pm2.keymetrics.io/,
acesso em 17 de Fevereiro de 2019.
[65] “Best Practices for Node.js Development — Heroku Dev Center”,
https://devcenter.heroku.com/articles/node-best-practices#avoid-
garbage, acesso em 17 de Fevereiro de 2019.
[66] “React Router: Declarative Routing for React.js”, https://reacttraining.
com/react-router/, acesso em 18 de Fevereiro de 2019.
[67] “React Router: Declarative Routing for React.js”, https://reacttraining.
com/react-router/core/guides/philosophy, acesso em 18 de Fevereiro de
2019.
44
[68] “yahoo/react-intl: Internationalize React apps. This library provides React
components and an API to format dates, numbers, and strings, including plu-
ralization and handling translations.”, https://github.com/yahoo/react-
intl, acesso em 19 de Fevereiro de 2019.
[69] “Components · yahoo/react-intl Wiki”, https://github.com/yahoo/react-
intl/wiki/Components#intl-provider-component, acesso em 19 de Feve-
reiro de 2019.
[70] “Home · yahoo/react-intl Wiki”, https://github.com/yahoo/react-intl/
wiki#loading-locale-data, acesso em 19 de Fevereiro de 2019.
[71] “Introduction — Apollo Client”, https://www.apollographql.com/docs/
react/, acesso em 20 de Fevereiro de 2019.
[72] “Why Apollo Client? — Apollo Client”, https://www.apollographql.com/
docs/react/why-apollo.html#caching, acesso em 20 de Fevereiro de 2019.
[73] “React Apollo — Apollo Client”, https://www.apollographql.com/docs/
react/api/react-apollo.html#graphql-config-options-fetchPolicy,
acesso em 20 de Fevereiro de 2019.
[74] BATURAY, M. H., BIRTANE, M., “Responsive web design: a new type of de-
sign for web-based instructional content”, Procedia-Social and Behavioral Sci-
ences, v. 106, pp. 2275–2279, 2013.
[75] “Using media queries - CSS: Cascading Style Sheets — MDN”,
https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/
Using_media_queries, acesso em 20 de Fevereiro de 2019.
[76] “What is accessibility? - Learn web development — MDN”, https:
//developer.mozilla.org/en-US/docs/Learn/Accessibility/What_is_
accessibility#So_what_is_accessibility, acesso em 24 de Fevereiro de
2019.
[77] “Accessibility - W3C”, https://www.w3.org/standards/webdesign/
accessibility, acesso em 24 de Fevereiro de 2019.
45
[78] TESTARDI, R. P., “Methods and systems for automated software testing”, jun
2001, US Patent 6,249,882.
[79] LAI, S.-T., “Applying Continuous Integration for Increasing the Maintenance
Quality and Efficiency of Web App”, International Journal of Software Engi-
neering & Applications, v. 10, pp. 37–50, 2019.
[80] “Code Splitting — webpack”, https://webpack.js.org/guides/code-
splitting/, acesso em 24 de Fevereiro de 2019.
[81] “<link>: The External Resource Link element - HTML: HyperText Mar-
kup Language — MDN”, https://developer.mozilla.org/en-US/docs/
Web/HTML/Element/link, acesso em 24 de Fevereiro de 2019.
[82] GRIGORIK, I., Resource Hints, Working Draft, W3C, jan 2018. https://www.
w3.org/TR/2018/WD-resource-hints-20180115/.
[83] GRIGORIK, I., WEISS, Y., Preload, Candidate Recommendation, W3C, oct
2017. https://www.w3.org/TR/2017/CR-preload-20171026/.
[84] “Progressive Web Apps — Web — Google Developers”, https://developers.
google.com/web/progressive-web-apps/, acesso em 25 de Fevereiro de 2019.
[85] “Service Workers: an Introduction — Web Fundamentals — Google De-
velopers”, https://developers.google.com/web/fundamentals/primers/
service-workers/, acesso em 26 de Fevereiro de 2019.
[86] “Progressive Web App Checklist — Web — Google Developers”, https://
developers.google.com/web/progressive-web-apps/checklist, acesso em
26 de Fevereiro de 2019.
[87] “Why Build Progressive Web Apps — Web — Google Developers”, https:
//developers.google.com/web/ilt/pwa/why-build-pwa, acesso em 26 de
Fevereiro de 2019.
46