Você está na página 1de 66

Miguel Silva da Rocha Junior

Desenvolvimento de plataforma para


e-commerce: da API à aplicação móvel

Natal – RN
Dezembro de 2019
Miguel Silva da Rocha Junior

Desenvolvimento de plataforma para e-commerce: da


API à aplicação móvel

Trabalho de Conclusão de Curso de Engenha-


ria de Computação da Universidade Federal
do Rio Grande do Norte, apresentado como
requisito parcial para a obtenção do grau de
Bacharel em Engenharia de Computação

Orientador: Ivanovitch Medeiros Dantas da


Silva

Universidade Federal do Rio Grande do Norte – UFRN


Departamento de Engenharia de Computação e Automação - DCA
Curso de Engenharia de Computação

Natal – RN
Dezembro de 2019
Miguel Silva da Rocha Junior

Desenvolvimento de plataforma para e-commerce: da


API à aplicação móvel

Trabalho de Conclusão de Curso de Engenha-


ria de Computação da Universidade Federal
do Rio Grande do Norte, apresentado como
requisito parcial para a obtenção do grau de
Bacharel em Engenharia de Computação

Orientador: Ivanovitch Medeiros Dantas da


Silva

Trabalho aprovado. Natal – RN, 29 de Novembro de 2019:

Prof. Dr. Ivanovitch Medeiros Dantas da Silva - Orientador


UFRN

Prof. Dr. Gustavo Bezerra Paz Leitão - Membro Externo


UFRN

MSc. Breno Santana Santos - Membro Externo


UFRN

Natal – RN
Dezembro de 2019
AGRADECIMENTOS

A minha família, por todo apoio e incentivo que me deram durante toda a minha
vida, incluindo a minha jornada acadêmica. Em especial aos meus pais que tanto me
incentivaram e ainda incentivam o meu crescimento profissional e pessoal. E mais ainda
por serem estes seres humanos tão verdadeiros e batalhadores que são. Sempre foram, são
e sempre serão um grande exemplo para mim.
Ao meu amor, Maria Clara, que tanto me apoia e me inspira pelo seu jeito batalhador
e decidido, o meu porto seguro. Obrigado por todas as horas que esteve me apoiando, pelo
companheirismo e paciência, compreensão e carinho. Sem você tudo isso teria sido muito
mais difícil.
Ao meu orientador Prof. Dr. Ivanovitch Dantas da Silva pela oportunidade de
trabalho, toda a orientação e estímulo que tornaram possível a realização deste trabalho.
Aos meus professores da graduação que me mostraram o valor da ciência e do
empreendedorismo para a sociedade em que vivemos. Aos professores Bruno Marques
Ferreira Da Silva e Luiz Marcos Garcia Gonçalves que orientaram por todo o meu período
como bolsista de iniciação científica. Aos professores Aquiles Burlamaqui, Luiz Eduardo
Cunha Leite, Júlio Melo, Agostinho de Medeiros Brito Junior, Marcelo Augusto Costa
Fernandes que tanto falavam e mostravam o impacto da ciência na sociedade através do
empreendedorismo, da geração de empregos.
Aos meus sócios e amigos Álvaro e Gabriel por todo o suporte, paciência, incentivo
e ajuda que recebi de vocês para este trabalho. O nosso dia-a-dia me faz crescer, buscar
sempre aquela melhoria a mais, buscar sempre crescer. Buscar sair da zona de conforto
porque não existe conforto na zona de crescimento.
A todos os demais que constroem a minha vida acadêmica: colegas, amigos, profes-
sores, funcionários da universidade e família. A todos vocês o meu obrigado.
“Everything you want is a dream away”
(Adventyre of a Lifetime - Coldplay)
RESUMO
Entregas à domicílio são uma tendência de mercado. De acordo com a McKinsey &
Company (uma das maiores empresas de consultorias do mundo), em 2020, 58% das
compras feitas neste mercado serão através da internet. E com este crescimento, vem
também a grande necessidade de soluções digitais para atender toda esta demanda. Uma
solução que vem se mostrado muito eficaz é a combinação de aplicativos para dispositivos
móveis, aplicações de PDV (Ponto De Venda) e uma aplicação Web para conecta-las.
Estas aplicações se comunicam através da API (Application Programmable Interface)
disponibilizada pela aplicação Web para realizar as transações necessárias à realização de
uma compra. Estas comunicações ocorrem de forma distribuída, com cada uma disponível
em uma diferente parte do globo. E a arquitetura de Representação de Transferência de
Estado (REST), introduzida no ano 2000 por Roy Thomas Fielding em sua dissertação
de doutorado, é uma ótima forma realizar estas conexões. Além disso, esta arquitetura
permite separamos o software em serviços com baixíssimo acoplamento, muitas vezes até
independentes. Como, por exemplo: serviços de notificações push, de caching, banco de
dados e armazenamento de arquivos estáticos. Desta forma, podendo até evoluir para um
sistema horizontalmente escalável.

Palavras-chaves: REST, Desenvolvimento de Software, Delivery, E-commerce, Compu-


tação em Nuvem, Aplicativos Móveis, Desenvolvimento Híbrido.
ABSTRACT
Delivery services are a worldwide market trend. According to McKinsey & Company (one
of the world’s largest consulting firms on the planet), in 2020, 50% of all the orders made
in this market are going to be placed online. And with all this growth, comes the high
necessity of digital solutions to fulfill all this online orders. A solution which is showing
itself as a highly efficient one is the combination of three applications: mobile, POS (Point
of Sales) and a Web. The first one is a native mobile app for the customers to choose
and place their orders. The second one is the application where the store receives the
orders. And the latter one is the Web application to connect them all. These applications
communicate themselves through an API (Application Programmable Interface) made
available by the Web app so that they can perform all the necessary transactions for an
order to be placed. These communications happen in a distributed way. Each application
may be available in a different part of the globe. And the Representational state transfer,
introduced in 2000 by Roy Thomas Fielding in his doctoral dissertation is a great way
to do this. Besides that, this architecture allows us to divide the software in services
loosely coupled, mostly even independent of each other. For example, services like push
notifications, caching, database and static file storage. Thus, this leaves the option to
evolve the system to one that takes advantage of a horizontal scalability.

Keywords: REST, Software Development, Delivery, E-commerce, Cloud Computing,


Mobile Applications, Hibrid Development.
LISTA DE ILUSTRAÇÕES

Figura 1 – Exemplo de banco relacional . . . . . . . . . . . . . . . . . . . . . . . . 15


Figura 2 – Arquitetura desta implementação . . . . . . . . . . . . . . . . . . . . . 22
Figura 3 – Modelagem relacional dos usuários da aplicação . . . . . . . . . . . . . 24
Figura 4 – Modelagem relacional do token de autenticação . . . . . . . . . . . . . 25
Figura 5 – Modelagem relacional dos produtos . . . . . . . . . . . . . . . . . . . . 26
Figura 6 – Modelagem relacional do endereço . . . . . . . . . . . . . . . . . . . . 27
Figura 7 – Modelagem relacional da Zona de Entrega . . . . . . . . . . . . . . . . 28
Figura 8 – Modelagem relacional do pedido . . . . . . . . . . . . . . . . . . . . . . 29
Figura 9 – Modelagem relacional da forma de pagamento . . . . . . . . . . . . . . 29
Figura 10 – Modelagem relacional entre forma de pagamento e o pedido . . . . . . 30
Figura 11 – Modelagem relacional entre pedido e endereço de pedido . . . . . . . . 31
Figura 12 – Padrão MVC: Model view controller . . . . . . . . . . . . . . . . . . . 34
Figura 13 – Django ORM: Busca por usuário to tipo 0 . . . . . . . . . . . . . . . . 35
Figura 14 – Logos do ElastiCache, Firebase e Amazon S3, respectivamente. . . . . 36
Figura 15 – Comparativo de quantidade de perguntas feitas no StackOverflow: React
Native versus Ionic. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Figura 16 – Estrutura de navegação da aplicação móvel . . . . . . . . . . . . . . . . 41
Figura 17 – Pilha de navegação, lojas, seleção de produtos e endereço . . . . . . . . 42
Figura 18 – Pilha de navegação de realização do pedido: carrinho e seleção de
pagamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Figura 19 – Pilha de navegação do acompanhamento de pedidos . . . . . . . . . . . 44
Figura 20 – Pilha de navegação do perfil do usuário . . . . . . . . . . . . . . . . . . 46
Figura 21 – BottomTabNavigator destacado em vermelho . . . . . . . . . . . . . . . 48
Figura 22 – Pilhas de navegação filhas do componente BottomTabNavigator . . . . 49
Figura 23 – Pilha de navegação de lojas . . . . . . . . . . . . . . . . . . . . . . . . 50
Figura 24 – Caso de uso: selecionar um endereço . . . . . . . . . . . . . . . . . . . 51
Figura 25 – Caso de uso: adicionar produto ao carrinho . . . . . . . . . . . . . . . . 51
Figura 26 – Caso de uso: adicionar produto ao carrinho . . . . . . . . . . . . . . . . 52
Figura 27 – 1: usuário toca no botão "FINALIZAR PEDIDO"; 2: o usuário toca no
botão para ver o andamento do pedido recém criado . . . . . . . . . . 54
Figura 28 – Pilha de navegação Order Stack . . . . . . . . . . . . . . . . . . . . . . 55
Figura 29 – Estados dos pedidos: 5 e 6 . . . . . . . . . . . . . . . . . . . . . . . . . 55
Figura 30 – Estados dos pedidos: 1, 3 e 4 . . . . . . . . . . . . . . . . . . . . . . . 56
Figura 31 – Página de detalhes do pedido. 1: em andamento, 2: cancelado, 3: finalizado 57
Figura 32 – Página de perfil do usuário. 1: perfil, 2: editar perfil, 3: mudar senha . . 57
LISTA DE TABELAS

Tabela 1 – Tabela de um banco de dados relacional . . . . . . . . . . . . . . . . . 14


Tabela 2 – Especificações da instância T2 medium. . . . . . . . . . . . . . . . . . 32
Tabela 3 – Estado inicial do componente ChangePassword.js . . . . . . . . . . . . 47
Tabela 4 – Mapeamento da figura 22 para as pilhas de navegação . . . . . . . . . 49
Tabela 5 – Mapeamento da figura 22 para as pilhas de navegação . . . . . . . . . 49
Tabela 6 – Mapeamento da figura 26 para as telas da pilha de navegação . . . . . 52
Tabela 7 – Mapeamento da figura 28 para as telas da pilha de navegação . . . . . 54
Tabela 8 – Mapeamento da figura 32 para as telas da pilha de navegação . . . . . 58
LISTA DE ABREVIATURAS E SIGLAS

API Application Programming Interface

REST Representational State Transfer

GUI Graphical User Interface

JSON JavaScript Object Notation

ACID Atomicidade, consistência, isolamento e durabilidade

HTTP Hypertext Transfer Protocol


SUMÁRIO

1 INTRODUÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.1 Contextualização . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.2.1 Objetivo geral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.2.2 Objetivos específicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.3 Estrutura do Trabalho . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2 REFERENCIAL TEÓRICO . . . . . . . . . . . . . . . . . . . . . . . 14
2.1 Banco de dados relacionais e não relacionais . . . . . . . . . . . . . . 14
2.1.1 Banco de dados relacionais . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.1.2 Banco de dados não relacionais . . . . . . . . . . . . . . . . . . . . . . . 16
2.1.3 O banco de dados escolhido . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.2 Protocolo HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.3 REST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.4 Aplicativos móveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.5 Desenvolvimento híbrido de aplicações móveis . . . . . . . . . . . . . 19
2.6 Trabalhos relacionados . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3 DESENVOLVIMENTO . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.1 Banco de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.1.1 Contas: o módulo de autenticação . . . . . . . . . . . . . . . . . . . . . . 24
3.1.2 Catálogo: o módulo de vitrine . . . . . . . . . . . . . . . . . . . . . . . . 25
3.1.3 Entregas: o coração da aplicação . . . . . . . . . . . . . . . . . . . . . . . 26
3.1.4 Pedidos: conectando todos os pontos . . . . . . . . . . . . . . . . . . . . 28
3.2 Construção da API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.2.1 Amazon AWS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.2.2 Django e Django REST Framework . . . . . . . . . . . . . . . . . . . . . 33
3.2.3 Django: Arquitetura MVC vs MTV . . . . . . . . . . . . . . . . . . . . . . 34
3.2.4 Django e sua ORM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.2.5 Serviços adicionais utilizados . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.3 A aplicação móvel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.3.1 React . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.3.2 Estrutura de navegação . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.3.2.1 Store stack: a listagem de lojas . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.3.2.2 Checkout stack: a realização do pedido . . . . . . . . . . . . . . . . . . . . . 43
3.3.2.3 Order Stack: o acompanhamento dos pedidos . . . . . . . . . . . . . . . . . 44
3.3.2.4 Profile Stack: os dados pessoais . . . . . . . . . . . . . . . . . . . . . . . . 46

4 RESULTADOS E DISCUSSÕES . . . . . . . . . . . . . . . . . . . . 48
4.1 Interfaces da aplicação móvel . . . . . . . . . . . . . . . . . . . . . . . 48
4.1.1 Store stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.1.2 Checkout Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4.1.3 Order Stack: acompanhando os pedidos . . . . . . . . . . . . . . . . . . . 53
4.1.4 Profile Stack: os dados do pessoais . . . . . . . . . . . . . . . . . . . . . 56

5 CONCLUSÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.1 Dificuldades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.2 Trabalhos futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

REFERÊNCIAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
12

1 INTRODUÇÃO

Este Capítulo descreve o contexto e as principais motivações que levaram ao


desenvolvimento deste trabalho. Na seção 1.1 a contextualização da temática desta imple-
mentação é apresentada. Na seção 1.2, a motivação que levou ao desenvolvimento dessa.
Na seção 1.3, os objetivos, gerais e específicos.

1.1 Contextualização
Segundo o Shopify, uma das maiores plataformas e e-commerce do mundo (STA-
TISTA, 2017), o comércio eletrônico, ou e-commerce, consiste na compra e venda de pro-
dutos, serviços e informações através da internet (SHOPIFY, 2019). O termo e-commerce
é comumente utilizado para se referir a venda de bens físicos online. Entretanto, o termo
também descreve qualquer tipo de transação comercial que é facilitada através da internet.
Enquanto o e-business (negócio eletrônico, em tradução livre) se refere a todos os aspec-
tos da operação de um negócio online, o comércio eletrônico se refere especificamente à
transação de bens e serviços.
Cada vez mais indivíduos e empresas estão eletronicamente conectados e isso vem
impulsionando e estimulando o crescimento do comércio eletrônico. Este é um mercado
que deve movimentar 6542 trilhões de dólares americanos em 2023 (CLEMENT, 2019).
Todo este comércio por meio da internet é, de forma geral, operacionalizado por
sistemas de comércio eletrônico. Estes sistemas são páginas na internet com um software
de gerenciamento ou aplicativos móveis. E este último tem crescido muito. Em 2017, 34.5%
das vendas do e-commerce mundial foram feitas em dispositivos móveis (MALI, 2019).
Juntamente com este crescimento, novos caminhos se abrem para o comércio
eletrônico. E um deles é o mercado de entregas rápidas. Este trabalho entende como
entregas rápidas uma compra de bens ou serviços físicos que devem ser entregues ou
prestados em um período curto, de menos de 24 horas. Este mercado vem crescendo,
principalmente no setor alimentício. Neste setor, os pedidos online devem chegar a 58% de
todas as compras feitas no ano de 2020 (HIRSCHBERG et al., 2016).
Estes dados mostram uma forte tendência: o crescimento das economias de conveni-
ência. Este trabalho entende como economia de conveniência todo o serviço e-commerce
cuja compra de bens ou serviços acontece através do delivery. Por esta tendência de
crescimento do mercado de delivery, do uso dos smartphones e do comércio online, este
trabalho foi proposto.
Capítulo 1. Introdução 13

1.2 Objetivos
1.2.1 Objetivo geral
O objetivo geral corresponde ao resultado principal da realização deste trabalho,
ou seja, o desenvolvimento de uma plataforma de e-commerce, da API à aplicação móvel,
com foco no modelo de delivery. Os objetivos específicos complementam o objetivo geral
em termos da finalidade do projeto.

1.2.2 Objetivos específicos


Os objetivos específicos apresentam-se como um conjunto de checkpoints que devem
ser atingidos com o intuito de concluir o trabalho. ‘

• OS1- Modelar banco de dados para autenticação de usuários, compra, venda e entrega
de produtos;

• OS2- Implementar regras de negócio de um delivery e disponibiliza-las via API;

• OS3- Projetar uma aplicação móvel funcional para que um consumidor possa realizar
uma compra;

• OS4- Fazer com que esta implementação seja utilizada por usuários;

• OS5- Validar a implementação realizando vendas, cadastros e downloads da aplicação


móvel;

1.3 Estrutura do Trabalho


Este trabalho tem a estrutura dividida em capítulos, inicia-se com o Capítulo
1 abordando toda a parte introdutória da implementação, por meio da apresentação
da introdução, contextualização, motivação, objetivos, e esta estrutura. O Capítulo 2
tem por objetivo apresentar e aprofundar um pouco mais os conceitos envolvidos desta
implementação. São eles: bancos de dados relacionais, protocolo HTTP, arquitetura de
software REST, aplicativos móveis, desenvolvimento híbrido de aplicações móveis e, por fim,
trabalhos relacionados relevantes ao nosso tema. O Capítulo 3 descreve o desenvolvimento
adotado para este trabalho de implementação, onde é apresentada a modelagem do
banco de dados, a infra-estrutura, a tecnologia e os serviços externos usados na API, a
tecnologia, estrutura e modos de navegação utilizados na aplicação móvel. No Capítulo 4
são apresentados os resultados desta implementação e todo o seu detalhamento, tais como
as interfaces de usuário. No Capítulo 5 são apresentadas as conclusões desta implementação,
incluindo as dificuldades encontradas e possíveis trabalhos futuros.
14

2 REFERENCIAL TEÓRICO

2.1 Banco de dados relacionais e não relacionais


O conceito de Bancos de Dados é um dos principais conceitos envolvidos no desen-
volvimento de sistemas para a Web. A utilização de bancos de dados está diretamente
relacionada ao o armazenamento, a leitura, ao processamento, as validações, a disponibili-
dade, a consistência e a durabilidade dos dados. Durante a escolha da solução de banco de
dados, duas opções devem ser consideradas de início: os bancos de dados relacionais e os
bancos de dados não relacionais.

2.1.1 Banco de dados relacionais


Banco de dados relacionais armazenam dados como um conjunto de tabelas, cada
uma com informações diferentes. Todos os dados estão relacionados para que seja possível
acessar informações de tabelas diferentes simultaneamente. Cada tabela é formada por um
conjunto de tuplas com os mesmos atributos, como podemos visualizar na tabela 1.

Quantidade
ID do produto Nome Preço
em estoque
1 SKOL R$ 3,90 2
2 MERLOT R$ 29,90 1
3 CHOPE 20L R$ 330,00 5
Tabela 1 – Tabela de um banco de dados relacional
Fonte – Própria

As tabelas são conectadas para que os dados de uma tabela possam estar relacionados
a outros por meio de uma chave. Estas chaves pode ser de dois tipos: primária e estrangeira.
A chave primária é usada para identificar na tabela inteira, cada tupla, como única. No
exemplo da tabela 1, a chave primária é o ID do produto. A chave estrangeira é usada para
tabelas de referência cruzada. Por exemplo, a figura 1 no caso cada produto possua uma
ou mais variantes, e uma variante pertença apenas a um produto, temos uma tabela de
variante de produto com uma chave estrangeira referindo-se ao produto que dono daquela
variante. Chave estrangeira em uma tabela pode representar uma chave primária na outra
(DATE, 2015).
Capítulo 2. Referencial Teórico 15

Figura 1 – Exemplo de banco relacional


Fonte – Própria

Com o objetivo de diminuir a repetição dos dados no banco relacional, é realizado


uma normalização dos dados. Através deste processo pode-se, gradativamente, substituir um
conjunto de entidades e relacionamentos por um outro, o qual se apresenta "purificado"em
relação às anomalias de atualização (inclusão, alteração e exclusão) as quais podem
causar certos problemas, tais como: grupos repetitivos (atributos multi-valorados) de
dados, dependências parciais em relação a uma chave concatenada, redundâncias de dados
desnecessárias, perdas acidentais de informação, dificuldade na representação de fatos da
realidade observada e dependências transitivas entre atributos. E este processo corrige
estes problemas (MACHADO; ABREU, 2012).
Um banco de dados relacional também possui a característica transacional. O
conceito de transações provem o mecanismo para descrever unidades lógicas de proces-
samento do bando de dados. Transações devem ter algumas propriedades, chamadas de
propriedades ACID: atomicidade, consistência, isolamento e durabilidade (ELMASRI;
NAVATHE, 2015).

1. Atomicidade: uma transação é uma unidade atômica: deve ser deve ser executado
na sua totalidade ou não ser executado.

2. Consistência: Uma transação deve preservar a consistência, o que significa que, se


for completamente executada do começo ao fim sem interferência de outras transações,
deve levar o banco de dados de um estado consistente para outro.

3. Isolamento: Uma transação deve aparecer como se estivesse sendo executada isolada-
mente de outras transações, mesmo que muitas transações estejam sendo executadas
simultaneamente. Ou seja, a execução de uma transação não deve ser interferida por
outras transações executadas simultaneamente.
Capítulo 2. Referencial Teórico 16

4. Durabilidade: As alterações aplicadas ao banco de dados por uma transação


completa devem persistir no banco de dados. Essas alterações não devem ser perdidas
devido a qualquer falha.

2.1.2 Banco de dados não relacionais


Um banco de dados não relacional tem um esquema dinâmico e não estruturado
para os dados, os valores são armazenados de várias formas: orientado a coluna, orientado
a documento, baseado em grafos ou organizado como chave-valor (FERREIRA, 2018).
Diferentemente da normatização, os bancos de dados não relacionais realizam
particionamento horizontal, onde as linhas são separadas em vez de serem quebradas em
colunas(FOWLER, 2012). Cada partição desta é chamada de shard, que por sua vez pode
ser instalada em um servidor diferente.
Devido a esta característica elástica do banco de dados não relacional, este tipo
de banco de dados não consegue garantir as propriedades de atomicidade, consistência,
isolamento e durabilidade. Para garantir estas propriedades, os sistemas de bancos de
dados clássicos são baseados em transações com estas propriedades (ACID), fato que não
acontece neste tipo de banco de dados (MONIRUZZAMAN; HOSSAIN, 2013).

2.1.3 O banco de dados escolhido


A plataforma a ser implementada neste trabalho é um e-commerce. Isto é, um
comércio eletrônico. E, para que haja comércio, alguns processos precisam acontecer. Por
exemplo: checagem de disponibilidade em estoque e o processo de finalização de compra,
também conhecido pelo termo em inglês Checkout.
Para que um usuário possa adquirir um produto, o sistema necessita de consistência
nos dados. Ou seja, quando um usuário vir que um produto está disponível, isto deve
significar que naquele exato momento aquele produto encontra-se com estoque maior que
zero.
Para que um usuário possa finalizar a compra, isto é, passar pelo processo de
Chcekout, várias condições devem ser checadas e registros devem ser feitos. Por exemplo,
se um usuário deseja comprar um produto chamado SKOL, o sistema executar alguns
processos. Primeiro, checar se há disponibilidade para a quantidade solicitada, se sim,
atualizar a quantidade para o valor atual subtraído da quantidade solicitada. Depois, deve
criar a tupla do pedido, com todos os seus atributos. E se um destes processos falhar por
algum motivo, toda esta transação deve falhar. Caso contrario, o e-commerce terá uma
inconsistência.
Por estes motivos, o modelo de banco de dados adotado nesta implementação foi o
Capítulo 2. Referencial Teórico 17

banco de dados relacional.

2.2 Protocolo HTTP


Hypertext Transfer Protocol (HTTP) é um protocolo de camada de aplicação
para transmissão de documentos hipermídia, como o HTML. Foi desenvolvido para
comunicação entre navegadores Web e servidores Web, porém pode ser utilizado para outros
propósitos também. Segue um modelo cliente-servidor clássico, onde um cliente abre uma
conexão, executa uma requisição e espera até receber uma resposta. Nesta aplicação, a API
(Application Prgramming Interface) é o servidor e a aplicação móvel o cliente. É também
um protocolo sem estado ou stateless protocol, que significa que o servidor não mantém
nenhum dado entre duas requisições (state). Apesar de ser frequentemente baseado em
uma camada TCP/IP, pode ser utilizado em qualquer camada de transporte confiável, ou
seja, um protocolo que não perde mensagens silenciosamente como o UDP (NETWORK,
2019b).
O protocolo HTTP define um conjunto de métodos para o HTTP/1.1 (versão 1.1
do protocolo e usada nesta implementação) a serem executados para uma data fonte.
Este métodos também são chamados de verbos HTTP (NETWORK, 2019a). Nesta
implementação, nem todos os métodos serão utilizados. Entretanto, os utilizados são
definidos a seguir (FIELDING et al., 1999).

1. GET : o método GET significa recuperar qualquer informação (na forma de uma
entidade) que é definida pela URI 1 (endereço de destino de navegação) da requisição.
Se a URI da requisição refere a um processo de produção de dados, é o dado produzido
que deve ser retornado como a entidade na resposta e não o texto fonte do processo.
A não ser que o texto seja o resultado final do processo;

2. PATCH : o método PATCH solicita um conjunto de mudanças, descritas na enti-


dade da requisição, a serem aplicadas ao recurso (entidades) identificado pelo URI
da requisição (no caso desta implementação, a aplicação cliente). O conjunto de
mudanças requisitadas é representado no formato chamado de "patch document",
identificado pelo tipo de mídia. Diferentemente do HTTP PUT, o método PATCH
não requer a mudança completa do recurso, podendo apenas requisitar atualização
de parte dele (DUSSEAULT; SNELL, 2010);

3. POST : O método HTTP POST envia dados ao servidor, podendo acarretar a criação
de uma um novo recurso ou não. Uma solicitação POST geralmente é enviada por
meio de um formulário HTML e resulta em uma alteração no servidor. No caso desta

1
https://en.wikipedia.org/wiki/UniformR esourceI dentif ier
Capítulo 2. Referencial Teórico 18

implementação, o POST é usado nas chamadas diretas a API implementada neste


trabalho.

4. DELETE: o método DELETE requisita ao servidor de origem a deleção de um


recurso identificado pela URI da requisição. Este método pode ser sobrescrito por
uma intervenção humana. E, no caso desta implementação, é. Neste caso, nenhum
dado é propriamente deletado do banco de dados, apenas indisponibilizado através
de um identificador booleano.

2.3 REST
Representational State Trasnfer (REST) é uma arquitetura de software que define
um conjunto de regras para serem utilizadas na criação de um serviço Web (BOOTH et
al., 2019). Permite, também, que a aplicação cliente execute ações sobre recursos, tais
como: criar novos recursos (por exemplo, um novo produto) e atualizar recursos existentes
(por exemplo, atualizar o preço de um produto), por exemplo. Para que um API seja
considerada RESTful, ela precisa seguir um conjunto de regras quando escritas. Estas
regras fazem com que as APIs fiquem fáceis de usar e descobrir, ou seja, um desenvolvedor
que começou a utilizar a API há pouco tempo terá uma maior facilidade aprendendo
utiliza-la. A arquitetura REST possui como principais regras: o padrão cliente-servidor,
sem estado (stateless), cache, interface uniforme (FIELDING, 2000).

1. Cliente-servidor: a separação de responsabilidades é o princípio por trás desta


regra. Separando a responsabilidade da interface de usuário e do armazenamento de
dados, a portabilidade da interface de usuário é melhorada em várias plataformas e
também melhora a escalabilidade simplificando os componentes do servidor. Esta
separação permite que os componentes evoluam de forma independente, dando
suporte ao requisito de escala da internet;

2. Stateless: a comunicação é sem estado, por natureza. Cada requisição do cliente


para o servidor deve conter todas as informações necessárias para o entendimento da
requisição, não podendo utilizar qualquer contexto salvo no servidor. Por exemplo, o
estado da sessão do usuário é completamente armazenado na aplicação cliente;

3. Cache: a fim de melhorar a eficiência, esta regra forma o estilo de arquitetura


client-cache-stateless-server. Esta regra regra requer que o dado contido na resposta
a uma requisição seja implicitamente, ou explicitamente, marcado com armazenável
em cache ou não. Se a resposta é armazenável em cache, o cache do cliente é dado o
direito de reutilizar esta resposta depois, para requisições equivalentes;
Capítulo 2. Referencial Teórico 19

4. Interface uniforme: a diferença central que distingue a arquitetura REST de outras


baseadas em rede é a ênfase em uma interface uniforme entre componentes. Aplicando
a generalização no componente de interface, toda arquitetura do sistema é simplificada
e a visibilidade de interações é melhorada. Implementações são desacopladas do
serviços que elas provém, o que encoraja uma evolução independente.

Devido a popularidade do REST (STACKOVERFLOW, 2019), a integração com o


protocolo HTTP (FIELDING, 2000), o padrão cliente-servidor, o baixo acoplamento a
não necessidade de manter o estado do sistema no servidor - o que reduz a necessidade de
memória volátil e a oferta de bibliotecas com implementações REST, foram os motivos de
escolha desta arquitetura de software para a comunicação da API.

2.4 Aplicativos móveis


Um aplicativo móvel, neste trabalho, é uma aplicação desenvolvida para ser instalada
em um dispositivo eletrônico móvel, tais como tablets e smartphones. Desde a sua criação
ingênua como acessório para telefones móveis para fins pessoais como ouvir música e jogos,
aplicativos móveis se transformaram em uma plataforma onipresente para fins sociais e
comerciais (GASIMOV et al., 2010). E com a evolução dos aplicativos e das plataformas
de desenvolvimento, atrelado com a crescente procura, a quantidade de categorias de App’s
(ZIMER; BARRETT; METCALF, 2011) aumentou, como jogos, GPS, venda de ingressos,
redes sociais, negócios, mercados de ações, dentre outros. Atualmente os principais sistemas
operacionais de aplicativos são o iOS 2 e o Android 3 (GASIMOV et al., 2010).

2.5 Desenvolvimento híbrido de aplicações móveis


Um dos maiores problemas no desenvolvimento de aplicações móveis é a necessidade
de implementar uma aplicação diferente para cada plataforma (JOORABCHI; MESBAH;
KRUCHTEN, 2013). Isso ocasiona um maior tempo de desenvolvimento, mais pessoas
envolvidas e, por consequência, maior custo para trazer estas soluções para o mercado.
Uma solução para este problema é o desenvolvimento híbrido de plataformas móveis. São
bibliotecas que fazem um código ser executado em várias plataformas diferentes, com
algumas configurações específicas para cada plataforma. E estas bibliotecas estão crescendo
muito (HUYNH et al., 2017). Para entender este conceito, primeiro, é necessário entender
os dois principais conceitos para este tipo de desenvolvimento.
O primeiro é o aplicativo móvel nativo. É uma aplicação móvel escrita na linguagem
de programação e com ferramentas específicas de um plataforma. Por exemplo: uma
2
https://www.apple.com/ios/
3
https://www.android.com/
Capítulo 2. Referencial Teórico 20

aplicação nativa para iOS seria escrita usando Swift 4 ou Objetctive-C (APPLE, 2014) e
compiladas usando Xcode (APPLE, 2019). Já no Android, uma aplicação nativa é escrita
usando Kotlin 5 , Java 6 ou C++ e compilada usando Android Studio. O segundo conceito
é o de a aplicação Web. São aplicações executadas em um navegador comum: seja ele móvel
ou não. Estas são aplicações tradicionais escritas em HTML, CSS e JavaScript.
Cada um destes conceitos gera uma tipo de desenvolvimento híbrido: híbrido-nativo
e híbrido-Web (KREMER, 2019). O primeiro é uma biblioteca que executa, normalmente
em JavaScript, em ambas as plataformas mas com chamadas que gerenciam uma interface
native de cada plataforma específica. Já o segundo é uma aplicação Web sendo executada
em um navegador nativo. Isto é, uma aplicação que pode ser executada em qualquer
navegador.
Em geral, devido a sua natureza de chamadas a funções nativas de interface, o
desenvolvimento híbrido-nativo possui uma melhor performance perante ao híbrido-Web
(SORAL, 2018). Por isto, foi escolhido para a implementação neste trabalho.

2.6 Trabalhos relacionados


Atualmente, há vários sistemas de e-commerce com foco em delivery. Em sua
maioria, são sistemas comerciais pouco documentados academicamente. Muitos deles,
também, com uma aplicação móvel para consumidor final. Foram encontrados, também,
alguns trabalhos acadêmicos para implementação de plataformas de e-commerce mas sem
a perspectiva de uma aplicação móvel.
Em (MAASS, 2013), o autor descreve o desenvolvimento de uma plataforma de e-
commerce de código fonte aberto utilizando uma biblioteca já conhecida de nome Magento
7
. Neste trabalho, o autor mostra as dependências e explica como instalar e utilizar esta
plataforma de código aberto. As tecnologias utilizadas foram PHP, servidor Apache e o
banco de dados relacional MySQL 8 .
Em (GEMELLI, 2015), o autor descreve como transformar uma plataforma de
e-commerce em um marketplace. Isto é, um e-commerce onde vários vendedores podem
comercializar bens e serviços. O autor sugere o uso da plataforma de código aberto Magento
como a estrutura base de sua implementação. As tecnologias utilizadas foram PHP, servidor
Apache e o banco de dados relacional MySQL.
Em (BRANGER, 2015), a autora descreve a implementação de um sistema de

4
https://developer.apple.com/swift/
5
https://developer.android.com/kotlin
6
https://developer.android.com/guide/components/fundamentals?hl=en
7
https://magento.com/
8
https://www.mysql.com/
Capítulo 2. Referencial Teórico 21

cardápio, ou portfólio online. O trabalho não trata da ação de compra e venda direta,
embora seja facilitada pela exibição dos produtos do portfólio. As tecnologias utilizadas
foram: PHP, Dreamwaver e o banco de dados relacional MySQL.
Em (HOEFLING, 2015) , a autora descreve a implementação de e-commerce
denominado “Angel e Re acessórios”. Tem como objetivo um sistema para que o usuário
possa ver e comprar os produtos disponibilizados no sistema. Este é um sistema de e-
commerce para apenas um vendedor, o que não o caracteriza como um marketplace. As
tecnologias utilizadas foram: PHP, Dreamwaver e o banco de dados relacional MySQL.
Todos os trabalhos acima usam PHP como linguagem de programação, enquanto o
presente trabalho usa Python. Não foi encontrada uma implementação de um sistema de
e-commerce no formato de API para alimentar uma aplicação móvel. Entretanto, várias
soluções comerciais deste formato são encontradas.

1. iFood 9 : o maior aplicativo de delivery de alimentos da América Latina (BELLONI,


2018) possui uma API que alimenta as aplicações Android, iOS e Web. Ele está
presente no Brasil, Argentina, México e Colômbia;

2. Rappi 10 : é um aplicativo de delivery de tudo: comida, serviços, produtos, diheiro,


etc. Possui uma API que alimenta as aplicações Android, iOS e Web. Ele está presente
no Brasil, Colômbia, Argentina, México, Chile, Uruguai, Peru, Equador e Costa
Rica;

3. Uber Eats 11 : é um aplicativo de delivery de alimentos subsidiário da empresa Uber.


O seu maior diferencial é ser responsável por toda a logística de entrega, conectando
os lojistas aos entregadores da sua rede já estabelecida do Uber. Ele está presente
em mais de 50 cidades e 13 países (UBER, 2019).

Dentre os trabalhos apresentados, os trabalhos acadêmicos não apresentam as


características de entrega que este trabalho se propõe. Entretanto, os comerciais já englobam
as funcionalidades exibidas aqui. Mas como nenhum deles está disponível para a academia,
este trabalho de propõe registrar uma implementação de um aplicativo de e-commerce
com uma aplicação móvel para que fique disponível a comunidade científica.

9
https://ifood.com.br
10
https://rappi.com
11
https://ubereats.com
22

3 DESENVOLVIMENTO

A implementação de uma plataforma de e-commerce com interface móvel envolve


duas frentes: API application programming interface e aplicação móvel em si. Isto é, o
back-end e o aplicativo para celular, respecitvamente.
A frente da API (também chamada de back-end nesta implementação) é a aplicação
Web responsável por receber requisições HTTP (Hypertext Transfer Protocol), manipular o
banco de dados e responder às requisições das aplicações cliente.
A frente da aplicação móvel implementa uma interface amigável que se comunica
com a API através de requisições HTTP. Esta frente é responsável por abstrair os protocolos
de comunicação, mostrando ao usuário final dados e informações em uma representação
que pode ser naturalmente lida por humanos.
Cada frente possui um conjunto dinstinto de tecnologias, devidamente escolhi-
das para as necessidades do negócio: integridade dos dados, disponibilidade do sistema,
velocidade e custos de desenvolvimento.
A arquitetura utilizada nesta implementação é mostrada na figura 2.

Figura 2 – Arquitetura desta implementação


Fonte – Própria

3.1 Banco de Dados


Duas características foram levadas em consideração na implementação desta API:
integridade e disponibilidade do sistema. E os motivos são intrínsecos as regras de negócio.
Capítulo 3. Desenvolvimento 23

A integridade dos dados se faz necessária devido ao processo de compra. Isto é,


se um usuário deseja comprar um produto, o sistema deve garantir a disponibilidade
em estoque, preço unitário, preço total, forma de pagamento, troco para pagamento em
espécie e endereço de entrega. Para isso, deve-se escolher um banco de dados que garanta
a integridade destas relações. Um modelo cuja concepção está baseada nisso é o banco de
dados relacional. Para este trabalho, o PostgreSQL foi a implementação SQL escolhida.
Os motivos para esta escolha foram: licença de uso aberta, gratuidade, grande comunidade
e conhecimento prévio das interfaces de gerência.
Nesta aplicação de e-commerce, precisamos entender alguns requisitos importantes
para modelar o banco: quais os tipos de usuários, como as lojas se relacionam com os
produtos e como será o processo de checkout. Para melhor entender a modelagem, a
aplicação foi dividia em 4 módulos:

1. Contas: chamado de accounts nesta aplicação, este é o módulo responsável por gerir
os tipos de usuários, a autenticação deles e o que mais referir-se apenas aos tipos
de usuários consumidor e loja. Alguns exemplos são: disponibilidade de lojas online,
redefinição de senhas e a autenticação por token. Neste módulo forma definidos
quatro modelos: usuário, loja, consumidor, horários de funcionamento e código de
redefinição de senha.
O autor informa exatamente onde o elemento gráfico deve ficar no texto, evitando
que quebras de páginas aconteçam no meio de um elemento. O problema com esta
abordagem é que todo o trabalho de posicionamento pode ser perdido caso se inclua
ou se exclua algum texto ou elemento.

2. Catálogo: chamado de catalog nesta aplicação, este é o módulo responsável por


gerir os produtos do lojista. Nele foram definidos três modelos principais: categoria,
produto e variante do produto.

3. Entregas: chamado de shipping nesta aplicação, este é o módulo responsável por


gerir tudo o que diz respeito a endereços. Aqui está o coração de aplicação para que
ela usada como um sistema de entregas a domicílio. Nele foram definidos os modelos
de endereço, código postal, cidade, bairro e zona de entrega.

4. Pedidos: chamado de checkout nesta aplicação, este módulo é responsável por


conectar todas as pontas do software para que ele possa ser chamado de um e-
commerce. Aqui é onde os pedidos são realizados. Isto é, onde um usuário consumidor
compra de um usuário lojista os produtos devidamente disponibilizados no seu
catálogo. Neste módulo foram definidos os modelos: método de pagamento, pedido,
itens do pedido, endereço de entrega do pedido e avaliação do pedido.
Capítulo 3. Desenvolvimento 24

3.1.1 Contas: o módulo de autenticação


Como dito anteriormente, esta aplicação possui dois tipos de usuários: consumidor e
loja. Ambos possuem atributos diferentes em suas definições. Entretanto, há uma coisa em
comum aos dois: autenticação. Ambos precisam de um e-mail e uma senha para autenticar-
se no sistema. Então, foram criados três entidades para geri-los: usuário, consumidor e
loja. A ideia é: todo consumidor e todo o lojista possui um, e apenas um, usuário, como
mostrado na figura 3.

Figura 3 – Modelagem relacional dos usuários da aplicação


Fonte – Própria

A razão para esta modelagem é a capacidade de expansão de tipos de usuários e


possibilidade de separar o sistema de autenticação do monolito principal. Note que com
uma tabela exclusiva para usuários, a facilidade de adicionar N outras especializações desta
entidade - com relações cardinais 1:1 - surge e esta flexibilidade pode ser utilizada para
quebrar o sistema em serviços separados. Entretanto, embora muitas possibilidades sejam
aceitas pelas relações apresentadas na figura 3, esta aplicação possui o requisito de que um
usuário possua apenas um tipo, definido na propriedade user type da entidade User. Desta
forma, cada usuário restringe-se ao seu contexto da aplicação e evita conflitos entre casos
de uso ligados a uma especialização de usuário ou a outra. E para que cada usuário seja
devidamente identificado e devidamente direcionado ao seu contexto, a aplicação precisa
autentica-los.
Capítulo 3. Desenvolvimento 25

Autenticação é o mecanismo de associar uma requisição recebida com um conjunto


de credenciais de identificação, tais como: o usuário que fez a requisição ou o seu token
usado para assinar a requisição. No caso desta aplicação RESTful, uma boa prática descrita
por Jacob Kaplan-Moss em seu artigo "REST worst practices" (KAPLAN-MOSS, 2008)
foi aplicada aqui: a autenticação deve ser plugável. Como? Através da autenticação por
token, cujas relações são representadas na figura 4.

Figura 4 – Modelagem relacional do token de autenticação


Fonte – Própria

Cada usuário, quando autenticado, possui um Token cuja função é identifica-lo


no sistema. E o baixo acoplamento do sistema de autenticação brilha aqui. Este hash
de 40 caracteres ASCII aleatórios não precisa ser gerado necessariamente neste software.
Com o advento de um Token, um usuário poderia muito bem ser possui um Token criado
por outro sistema. Por exemplo, criado por uma autenticação de uma rede social como o
facebook, por exemplo.

3.1.2 Catálogo: o módulo de vitrine


Se o intuito é produzir um e-commerce, os produtos das lojas precisam estar
disponíveis e os consumidores preciam vê-los! Para isto, é necessário analisar os requisitos
do projeto: um produto pode ter N variações, e cada uma delas pode possuir um preço
diferente. No mercado de bebidas alcoólicas, por exemplo, lojas de conveniência costumam
ter dois preços para o mesmo produto dependendo de sua temperatura: gelada ou natural.
Ou ter preços diferenciados para produtos vendidos em pacotes com quantidades fixas.
Desta forma, percebe-se que um produto pode ter nenhuma ou N variações.
Outra informação importante para o consumidor é a categoria do produto. Nova-
mente, para o mercado de bebidas alcoólicas, poderíamos ter: cervejas, uísques, vodcas,
cachaças, liquores e etc. O consumidor precisa ter esta informação para encontrar o que
deseja. E no caso deste trabalho, um produto pode conter apenas uma categoria mas uma
categoria pode possuir N produtos. Estes relacionamentos são mostrados na figura 5.
Capítulo 3. Desenvolvimento 26

Figura 5 – Modelagem relacional dos produtos


Fonte – Própria

3.1.3 Entregas: o coração da aplicação


Como dito no início deste trabalho, o objetivo é construir a aplicação de entregas
a domicílio. Para isto, várias informações são necessárias: onde o produto será entregue,
quais lojas entregam neste endereço e qual o valor da entrega.
A primeira informação é a mais simples. O usuário do tipo consumidor possui um
endereço que será utilizado para a realização da entrega. Da mesma forma, para pagamentos
online, o usuário consumidor precisa de um endereço de cobrança do seu cartão de crédito.
Entretanto, note que embora haja tipos diferentes, os campos da entidade são os mesmos.
Além disso, a entidade de endereços pode ser utilizada tanto por consumidores como lojistas.
Para abarcar ambos os casos, a tabela possui uma referência a entidade de usuários. Cada
utilizador da plataforma, seja uma loja ou um consumidor, pecisa de um usuário. Desta
forma, a entidade de endereços fica acessível a ambas especializações da tabela de usuário,
como mostra o diagrama entidade relacional na figura abaixo.
Com o endereço, agora pode-se obter a segunda informação: quais lojas entregam
no endereço dado. Cada loja deve escolher onde entregar e quanto cobra na entrega. A
entidade responsável por isso é a Zona de Entrega (Shipping Zone). Uma loja pode possuir
nenhuma ou N zonas de entrega, já uma zona possui uma e apenas uma loja. Uma Zona
de Entrega é um conjunto de bairros com um preço de entrega. Isto é, por exemplo, se
uma loja funciona em Natal/RN e quer entregar nos bairros de Tirol, Petrópolis, Ribeira
e Cidade Alta pelo valor de oito reais, ela pode criar uma Zona de Entrega cobrando o
Capítulo 3. Desenvolvimento 27

Figura 6 – Modelagem relacional do endereço


Fonte – Própria

mesmo valor para entregar nestes bairros.


A modelagem destes bairros também é um fator importante neste trabalho. Para
moradores de uma capital como, por exemplo, Natal ou São Paulo, um Código de Endere-
çamento Postal (CEP) refere-se apenas a uma rua e nunca está contido em dois bairros.
Entretanto, em cidades menores como Caicó/RN, por exemplo, um CEP pode ser utilizado
para a cidade inteira. Isto é, para cidades maiores, um bairro possui ao menos um ou
vários CEPs. Já para cidades menores, um CEP pode possuir um ou vários bairros. Ou
seja, temos uma cardinalidade M:N, ou many to many. A figura 7 mostra as relações entre
estas entidades.
Uma importante regra de negócio aplicada a esta modelagem é: um bairro não pode
estar contido em duas zonas de entrega pertencentes a mesma loja. O motivo é simples: se
um bairro está contido em duas zonas, não se pode afirmar qual delas será utilizada para
consultar o valor da entrega em um determinado bairro.
Desta forma, pode-se obter toda as informações citadas no primeiro parágrafo desta
seção. Onde o produto será entregue? O endereço do tipo delivery address vai dizer. Quais
as lojas entregam em um determinado endereço? Checa-se qual o bairro deste endereço,
quais as zonas de entrega contém este bairro e quais são as lojas detentoras destas zonas -
Capítulo 3. Desenvolvimento 28

Figura 7 – Modelagem relacional da Zona de Entrega


Fonte – Própria

as lojas que entregam no endereço fornecido. E, por final, qual o preço da entrega? Cada
zona de entrega possui um preço de entrega para o seu conjunto de bairros.

3.1.4 Pedidos: conectando todos os pontos


A base de qualquer comércio, digital ou offline, é a venda. E este é o módulo para
isto. Todas as pontas descritas anteriormente se encontram no checkout. E para iniciar a
modelagem, a anatomia de uma venda deve ser entendida.
Cada venda possui dois atores: um consumidor e uma loja. E como o objetivo
também é a recorrência nas vendas, um consumidor pode ter nenhum (um novo consumidor)
ou N pedidos. Da mesma forma, o objetivo é que uma loja venda bastante. Ou seja, uma
loja pode ter nenhum pedido (uma nova loja) ou N pedidos. Desta forma, nota-se que um
pedido deve possuir a chave estrangeira de um, e apenas um, consumidor e uma chave
estrangeira de uma, e apenas uma, loja.
Além disso, em um e-commerce, uma venda precisa conter os produtos comprados.
Novamente, como o objetivo é vender mais, um pedido possui vários itens. Cada item
refere-se a uma cópia de uma linha da tabela de variante de produto. Pois, nesta modelagem,
a variante é quem possui o preço. Neste caso a cópia é necessária porque um item do
pedido representa o estado de uma variante no momento em que ela foi adquirida. Isto é,
se um consumidor realiza uma compra de uma bebida quando este produto está listado a
R$ 3,50, este item do pedido será criado referenciando a linha do banco que contém este
Capítulo 3. Desenvolvimento 29

produto. Ou seja, no momento que o lojista alterar o preço dele, o preço do item do pedido
também irá mudar - o que não é um comportamento aceitável para um e-commerce. Esta
relação está descrita na imagem 8.

Figura 8 – Modelagem relacional do pedido


Fonte – Própria

Outra relação a ser considerada em um pedido é a forma de pagamento. Cada


loja deve possui uma ou N formas de pagamento. Entretanto, estas formas de pagamento
devem ser disponibilizadas pela plataforma para que a loja as escolha. Ou seja, uma forma
de pagamento pode estar presente em nenhuma ou N lojas. Isto é, há uma relação N:N
entre lojas e formas de pagamento, como mostra a figura 12.

Figura 9 – Modelagem relacional da forma de pagamento


Fonte – Própria

Esta mesma entidade deve estar presente no pedido, porque uma venda precisa de
uma forma de pagamento. Aqui, diferentemente do item do pedido, temos uma referência
Capítulo 3. Desenvolvimento 30

direta a tabela de formas de pagamento. O motivo é simples: como esta é uma tabela a
qual apenas a plataforma pode inserir dados, não há riscos de um usuário consumidor ou
loja alterar esta informação. Embora seja verdade que estes usuários possam alterar quais
formas de pagamento aceitam, entretanto, após a realização do pedido, a referência fica
registrada e nenhum desses usuários pode alterá-la. Este relacionamento é mostrado na
figura 10.

Figura 10 – Modelagem relacional entre forma de pagamento e o pedido


Fonte – Própria

E a última relação importante para um e-commerce focado em entregas a domicílio


é o endereço de entrega. Um pedido precisa ter um endereço de entrega para que a loja
saiba onde entregar a mercadoria adquirida. E neste caso também precisamos de uma
entidade de endereço referente apenas à venda: endereço do pedido. Assim como o item
de um pedido, o endereço de um pedido pedido representa o estado de um endereço no
momento em que o pedido foi feito. Ou seja, o endereço do pedido é uma cópia de um
endereço do tipo "endereço de entrega".
Entretanto, um pedido deve ter dois endereços. São eles dos tipos: de entrega e
de cobrança. Cada um podendo estar presente apenas uma vez para um pedido. Isto é,
um pedido possui 2, e apenas 2, endereços de pedido. Para pedidos online, os meios de
pagamento virtual exigem este endereço para que a compra seja validada com sucesso.
Também vale ressaltar que há a possibilidade de ambos os endereços serem iguais, mudando
apenas o tipo. Mas, mesmo assim, as duas linhas na tabela de Endereço do Pedido devem
ser registradas - respeitando seus tipos respectivos. Este relacionamento é mostrado na
figura 11.
Ainda há dois atributos da tabela de endereços do pedido que devem ser menciona-
Capítulo 3. Desenvolvimento 31

dos: latitude e longitude. Ambos eles são utilizados em um caso de uso bem específico:
navegação GPS do entregador. Isto é, ao invés de digitar o endereço e torcer para que o
forward geocoding (o ato de enviar um endereço digitado e retornar a latitude e longitude
aproximadas) possua uma boa precisão, a latitude e a longitude ficam disponíveis com os
valores fornecidos pelo consumidor. Isso acontece quando o usuário do tipo consumidor
cadastra um novo endereço. A aplicação cliente deve mostrar um mapa para que o usuário
selecione a latitude e a longitude exatas do endereço que está sendo cadastrado.

Figura 11 – Modelagem relacional entre pedido e endereço de pedido


Fonte – Própria

3.2 Construção da API


Esta sessão apresenta a implementação de fato desta API. Na subseção 5.2.1,
apresenta-se a infraestrutura escolhida para a aplicação. Na subseção 5.2.2, apresenta-se
as especificações técnicas do banco de dados e as razões pela escolha do mesmo. Na sessão
5.2.3, o framework utilizado para auxiliar no desenvolvimento do software. Na sessão 5.2.4,
é apresentada a arquitetura do software: como foi idealizada e as razões para tal. Ao final,
na sessão 5.2.5, apresenta-se a forma de comunicação entre as partes da aplicação.

3.2.1 Amazon AWS


Amazon Web Services 1 , também conhecido por AWS, é um serviço de computação
na nuvem usado para distribuir aplicações de software através da internet. Como o próprio
nome sugere, é um serviço mantido pela gigante estadunidense Amazon. É um serviço
que oferece vários produtos, dentre eles: balanceadores de carga, computação elástica,
1
https://aws.amazon.com/
Capítulo 3. Desenvolvimento 32

máquinas virtuais, serviços DNS, bancos de dados, envio de emails, envio de notificações e
vários outros. Este serviço é utilizado por grande parte das aplicações Web nos dias de
hoje. O relatório Custom Applications and IaaS Trends (MCAFEE; ALLIANCE, 2019),
mostra que 41.5% das aplicações implantadas através da internet utilizaram AWS. E este é
o primeiro motivo da opção por este serviço. Com muitas pessoas utilizando, a comunidade
online da AWS tornou-se muito grande. Isso facilita a busca por informações, tutoriais e
eventuais erros durante a implementação. Principalmente quando utilizando o seu produto
de computação elástica.
O Amazon EC2 2 (Elastic Cloud Computing), é um serviço Web que provém
computação em nuvem de forma segura e redimensionável. Ele foi projetado para tornar a
computação em nuvem em escala na Web mais fácil para os desenvolvedores. E realmente
tornou. Por isso, foi escolhido para este trabalho. Também é necessário citar o tipo da
instância escolhida. Para tomar esta decisão, precisa-se entender quais serão as necessidades
da aplicação. A possibilidade de escalabilidade horizontal é um requisito importante, embora
ainda não implementado neste trabalho. Para isso, o sistema foi dividido em três partes:
aplicação, serviço de caching e banco de dados.
Para o servidor de aplicação, é preciso um balanço entre poder de processamento e
disponibilidade de memória RAM. Então, de acordo com a documentação dos tipos de
instância fornecidos pelo EC2 (AMAZON, 2019a), a T2 medium preenche estes requisitos.
De acordo com o mesmo documento, este tipo é indicado para aplicações de propósito
geral. A tabela 2 sintetiza as especificações técnicas da instância.

Tabela 2 – Especificações da instância T2 medium.

T2 Medium
vCPU 2
Mem. (GiB) 4
Performance de rede Baixa a moderada.
Fonte – Amazon EC2 Instance Types - Amazon Web Services 2019

Os processadores deste tipo de instância possuem até 3.3 GHz Intel Scalable
Processor. O sistema operacional escolhido para ser instalado nesta instância foi o Ubuntu
Server 3 versão 18.04 LTS. A escolha se dá por dois motivos: gratuidade e grande comunidade
- o que facilita discutir erros e encontrar artigos descrevendo algum eventual processo de
instalação de dependências. E pela facilidade, claro, de conexão com outros seviços da
AWS como, por exemplo o de banco de dados.
O Amazon RDS Amazon Relational Database Service 4 , é o serviço de banco de

2
https://aws.amazon.com/ec2/
3
https://ubuntu.com/download/server
4
https://aws.amazon.com/rds/
Capítulo 3. Desenvolvimento 33

dados relacionais da Amazon o qual oferece uma abstração na infraestrutura e operação


destes tipos de bancos em um ambiente de computação em nuvem. Ele provém a capa-
cidade de redimensionamento e automação de tarefas administrativas demoradas como
provisionamento de hardware, configurações, atualizações e backups. Além disso, o fato de
haver uma grande comunidade de usuários e sua capacidade de escalar automaticamente 5
foram decisivos para a escolha deste serviço.

3.2.2 Django e Django REST Framework


A biblioteca Django 6 , na sua versão 2.2.1 foi utilizada como base para a construção
da API no presente trabalho. Django foi escolhido para esta implementação porque é um
framework Web baseado em Python, gratuito e de código fonte aberto que segue o padrão
de arquitetura MVC (Model-View-Controller). Nesta implementação, a versão 3.6.5
do Python foi utilizada. O Django é mantido pela comunidade e pala Django Software
Foundation 7 , uma organização independente e sem fins lucrativos. O objetivo primário
do Django é facilitar a criação de sistemas complexos que utilizam bancos de dados. E
para isso, Django segue a filosofia "all batteries included"8 do Python, disponibilizando
muitas funcionalidades diretamente no seu próprio código fonte. Esta característica reduz
muito o tempo de desenvolvimento pois não é necessário "reinventar a roda"toda vez que
precisa-se implementar uma funcionalidade já consolidada. O framework também tem
ênfase na reutilização de e "plugabilidade"de seus componentes, com menos código, menos
acoplamento, desenvolvimento rápido e o princípio DRY (Don’t Repeat Yourself ). E por
causa destes princípios, principalmente da "plugabilidade", novas bibliotecas surgem para
dar novas funcionalidades a ele.
Um exemplo delas é o Django REST framework 9 . Um kit de ferramentas flexíveis
e poderosas para construir APIs Web. Esta biblioteca é uma camada de abstração que
adiciona funcionalidades como classes com comportamento padrão para fazer um CRUD
(Create, retrieve, update and delete) das tabelas do banco de dados, serializar os dados
para o formato JSON (Javascript object notation), cache e throttling.
Por todas as características acima: baixo acoplamento, grande comunidade, pluga-
bilidade, poderosa ORM Object-relation mapping, gratuidade e a existência do Django
REST framework, o Django foi escolhido como ferramenta base desta implementação.
Capítulo 3. Desenvolvimento 34

Figura 12 – Padrão MVC: Model view controller


Fonte – (RAMOS, 2019)

3.2.3 Django: Arquitetura MVC vs MTV


Como dito na seção anterior, o Django utiliza o padrão de arquitetura MVC.
Entretanto, ele usa uma nomenclatura diferente: Model-View-template (DJANGO, 2019).
O Model do Django possui a mesma função: manipulação de dados, leitura, escrita e
validação dos dados. Já o que o Django chama de View, o padrão MVC chama de
Controller. Isto é, o responsável por receber todas as requisições do usuário. Seus métodos
chamados ações são responsáveis por uma página, controlando qual model usar e o que
será mostrado ao usuário. E, por fim, o que o Django chama de Template, o padrão MVC
chama de View. Isto é, a camada de interação com o usuário. Ela apenas faz a exibição
dos dados, sendo ela por meio de um HTML, XML, JSON ou outro formato de dados.

3.2.4 Django e sua ORM


A maioria das consultas ao banco que nós escrevemos são simples. A ORM (Object-
Relational Model do Django fonece um excelente atalho de produtividade: não apenas
gerado boas queries SQL para casos de uso comuns, mas provendo funcionalidades de
5
(AMAZON, 2019b)
6
https://www.djangoproject.com/
7
https://www.djangoproject.com/foundation/
8
https://docs.python.org/3/tutorial/stdlib.html#batteries-included
9
https://www.django-rest-framework.org/
Capítulo 3. Desenvolvimento 35

acesso e atualizações de modelos que vem completas com validações e segurança. Ela nos
permite escrever um código trivial que funciona com diferentes bancos de dados. Esta
funcionalidade da ORM alimenta grande parte do ecossistema dos pacotes de terceiros
desenvolvidos para o Django.
A ORM do Django, como qualquer ORM, converte dados de tipos diferentes em
objetos que podem ser usados de forma bem consistente através dos bancos de dados
suportados. Então ela fornece um conjunto de métodos para interagir com estes objetos.
No caso de uma busca no modelo de usuários (User) cujo tipo de conta é 0, a consulta fica
como na figura 13.

Figura 13 – Django ORM: Busca por usuário to tipo 0


Fonte – Própria

Esta abstração traz uma produtividade muito grande quando se está desenvolvendo
e temos, na maioria das vezes, consultas simples. Entretanto, a ORM também permite a
execução de um código SQL, diretamente no banco. Este último é útil para consultas mais
complexas, que envolvem operações de JOIN em tabelas, agrupamentos dentre outros.

3.2.5 Serviços adicionais utilizados


Para esta implementação, outros serviços externos à aplicação principal também
foram utilizados. São eles: AWS ElastiCaching 10 , Amazon S3 11 e o Firebase 12 . Cada um
com o seu objetivo bem definido.

1. AWS ElastiCache: é um serviço de cache e armazenamento de dados na memória


totalmente gerenciado pela Amazon Web Services (AWS). o serviço Oferece bancos
dados gerenciados em memória, em vez de depender inteiramente de bancos de dados
mais lentos baseados em disco. Os motivos dele ter sido escolhido são: disponibilidade
do banco de dados Redis 13 , facilidade de integração com o serviço Amazon EC2

10
https://aws.amazon.com/elasticache/?nc=sn&loc=0
11
https://aws.amazon.com/s3/
12
https://firebase.google.com/docs
13
https://aws.amazon.com/redis/
Capítulo 3. Desenvolvimento 36

Figura 14 – Logos do ElastiCache, Firebase e Amazon S3, respectivamente.


Fonte – Própria

(utilizado nesta implementação), dimensionamento, processos burocráticos automáti-


cos (backup, restauração do conjunto de dados e adição de recursos), conhecimento
prévio de suas configurações, facilidade de integração com o Django. E todos estes
recursos podem ser acionados através de uma única chamada de API.

2. Firebase: é uma plataforma do Google para ajudar no desenvolvimento de aplicativos


móveis. Alguns serviços ofertados são: banco de dados, autenticação, análises de
dados, demografia, relatório e notificações. Este último é o que foi utilizado nesta
implementação. O serviço se chama Cloud Messaging. É responsável pelo envio de
mensagens para o APNS (Apple Push Notification Service), serviço de notificações
push da Apple e para o serviço de notificações do Google. Os dois grandes motivos
para esta escolha foram: facilidade de integração em Python 14 e a gratuidade no
envio de mensagens 15 . Além do mais, a grande comunidade do Firebase faz com
que seja fácil de encontrar respostas na internet 16 .

3. Amazon S3: O Amazon Simple Storage Service (Amazon S3) é um serviço de


armazenamento de arquivos que oferece escalabilidade, disponibilidade de dados,
segurança e desempenho. O Amazon S3 fornece recursos de gerenciamento fáceis de
usar, deixando simples a tarefa de organizar os dados e configurar controles de acesso
aprimorados para atender aos requisitos específicos de negócios, organizacionais e de
conformidade. Além disso, a sua integração com o Django se torna extremamente
simples por causa da biblioteca django-storages 17 e o SDK (Software Development
Kit) Boto3 18 , desenvolvida em Python pela própria Amazon. Por esta facilidade, o

14
https://firebase.google.com/docs/cloud-messaging/server#choosing-a-server-option
15
https://firebase.google.com/pricing
16
https://stackoverflow.com/questions/tagged/firebase
17
https://django-storages.readthedocs.io/en/latest/
18
https://boto3.amazonaws.com/v1/documentation/api/latest/index.html
Capítulo 3. Desenvolvimento 37

tempo de desenvolvimento diminui bastante pois não há a necessidade de criar todas


as requisições que serão feitas para a API da Amazon Web Services. Ademais, os
custos de armazenamento e de transferência de dados são baixos 19 .

3.3 A aplicação móvel


A aplicação móvel é aquela que produz a interface que o usuário final usará. Nesta
implementação, temos os seguintes requisitos.

1. Ser executada em dispositivos Android 20 e iOS, sistemas operacionais produtos pelo


Google e pela Apple, respectivamente. 21

2. Tempo de desenvolvimento

3. Comunidade

4. Perfomance

Para isso, algumas tecnologias de desenvolvimento foram levadas em consideração:


Ionic 22 , React Native 23 e desenvolvimento nativo com Swift para iOS 24 e com Kotlin
para Android 25 . Cada uma destas escolhas tem suas vantagens e desvantagens perante os
requisitos levantados acima. Entretanto, alguns requisitos possuem mais importância do
que ouros no contexto de produto.
Este requisito de maior importânica é o tempo de desenvolvimento. Nesta imple-
mentação, o software foi desenvolvido para uma empresa, e tempo de desenvolvimento é
diretamente proporcional ao custo: quanto menor, melhor. Por este motivo, a opção de
desenvolver de forma nativa com Swift e Kotlin para iOS e Android, repsectivamente, foi
descartada. Haveria a necessidade de duas aplicações distintas, com tecnologias diferentes,
o que causa uma impossibilidade no reuso de código, fazendo com que o tempo de desen-
volvimento aumente muito. Assim, sobram duas opções: Ionic e React Native. Ambas com
tecnologias híbridas, permitindo o desenvolvimento concomitante entre as plataformas iOS
e Android.
Dentre estes, primeiro fora analizado o tamanho das comunidades. Quando maior,
melhor. E o motivo é simples: mais pessoas perguntando e respondendo sobre o assunto

19
https://aws.amazon.com/s3/pricing/
20
https://www.android.com/
21
https://developer.apple.com/ios/
22
https://ionicframework.com/
23
https://facebook.github.io/react-native/
24
https://developer.apple.com/swift/
25
https://developer.android.com/kotlin
Capítulo 3. Desenvolvimento 38

na internet - ocasionando maior facilidade em encontrar perguntas e respostas. De acordo


com a figura 15. site Stack Overflow, a comunidade Ionic vem caindo e a comunidade
React vem subindo(STACKOVERFLOW, 2019).

Figura 15 – Comparativo de quantidade de perguntas feitas no StackOverflow: React


Native versus Ionic.
Fonte – Própria

O último requisito a ser analisado é a performance. O React e o Ionic possuem


uma diferenças fundamentais. O primeiro é executado em uma thread Javascript que se
conecta a uma nativa através de uma ponte para, assim, executar chamadas a funções
nativas do sistema. Já o segundo é uma WebView 26 , renderizado como uma página Web.
Neste quesito, o React Native foi vencedor, como mostra o experimento 1, no capítulo 6 -
Experimentos e Resultados.

3.3.1 React
React.js 27 é uma biblioteca para a linguagem JavaScript usada para o desenvolvi-
mento de interfaces de usuário dinâmicas e aplicações Web. Atualmente é mantido pelo
Facebook e por uma vasta comunidade de desenvolvedores, além de ser amplamente usada
na indústria da tecnologia 28 .
Aplicações construídas com esta biblioteca são baseadas em componentes isolados e
reutilizáveis que, quando combinados, podem formar interfaces de usuário mais complexas.
26
Um componente de interface que executa uma tela de navegador em uma aplicação nativa
27
https://reactjs.org/
28
https://stackshare.io/react
Capítulo 3. Desenvolvimento 39

Todos os elementos que são renderizados na tela são componentes, tais como: botões,
campos de texto, listas, etc.
Esses componentes são classes ou funções escritas em JavaScript que contém tanto
o código necessário para sua renderização quanto a lógica usada para reagir a interações
do usuário e mostrar conteúdo dinamicamente.
Cada aplicação React tem pelo menos um componente, chamado de root compo-
nent, ou componente raiz, em tradução livre. Esse componente contém todos os outros
componentes como filhos, formando uma árvore cujo a profundidade aumenta com a
complexidade da aplicação e a quantidade de componentes necessários para formá-la.
Os componentes são criados de maneira declarativa, definindo-se como os mesmos
devem reagir a um conjunto de estados, alterado a forma como são renderizados a cada
mudança. Por isso a biblioteca se chama React (que pode ser traduzido como Reagir), pois
os elementos reagem a mudanças de estados.
Para unir a lógica de renderização aos componentes React, a biblioteca faz uso
de uma extensão de sintaxe do Javascript chamada JSX 29 . Com ela é possível usar tags
similares as utilizadas no HTML, porém denro do príprio código Javascript.
Os componentes React possuem, além disso, comportamentos e características que
devem ser mencionados. Aqui, entretanto, não será feita menção aos React Hooks 30 . Nesta
implementação, as seguintes definições foram utilizdas:

1. Props: cocentualmente, componentes são funções Javascript. Eles aceitam inputs


arbitrários e imutáveis chamados props, ou proriedades em tradução livre. Eles
podem ser estados, funções, outro componentes ou qualquer outro elemento que seja
necessário;

2. Callbacks: são funções, anônimas (aqui chamadas de arrow functions) ou não,


passadas de um componente pai para os componentes filhos na forma de props. Elas
contém o contexto do componente pai mas podem receber argumentos do componente
filho. Um exemplo de um Callback é um evento específico que deve acontecer quando
um botão (componente filho) foi pressionado;

3. Filhos: são componentes React que são passados na forma de props para serem
renderizados dentro do contexto do componente pai. Por exemplo, campos de texto
em um formulário. Eles permitem que as aplicações crescam e se tornem cada vez
mais complexas utilizando pequenos componentes filhos;

29
https://reactjs.org/docs/introducing-jsx.html
30
https://reactjs.org/docs/hooks-intro.html
Capítulo 3. Desenvolvimento 40

4. Estado: variável de classe 31 que define os parâmetros que compõem o contexto atual
de um componente React. Por exemplo: o texto sendo digitado em um componente
de entrada. O estado é a forma que o componente guarda informação durante seu
ciclo vida. Sempre que o estado é alterado, o método render é chamado para que o
componente seja re renderizado na tela em resposta a essa mudança.

5. Funções de Ciclo de Vida: são métodos de classe (e funções com a introdução do


React Hooks), chamados quando eventos pré determinados acontecem. Isto é, quando
um componente é montado, quando um componente tem suas props atualizadas,
quando um componente é desmontado e etc;

6. Função Render: método da classe onde é definido a estrutura do componente que


deve ser renderizada na tela. Aqui são usadas as tags JSX mencionadas anterior-
mente. Em componentes baseados em função, o React entende que o retorno deles é
equivalente ao retorno no método render. Ou seja, sempre retornando um JSX.

Estes conceitos aplicam-se durante toda a implementação. Ademais, o conceito de


Estados é trabalhado de duas formas: estados no nível de componentes e estados em nível
de aplicação. Isto é, estados em nível de componente são aqueles os quais o contexto só diz
respeito àquele componente em si e aos seus filhos com no máximo 1 grau de profundidade.
Por exemplo, um formulário é um conjunto de entradas de texto que concentra todo o
estado de seus componentes filhos (as entradas). Já estados que dizem respeito a mais
de um componente na de mesma profundidade são chamados, nesta implementação, de
estados em nível de aplicação. Exemplos estes estados são informações de carrinho, token
de autorização do usuário e as informações do usuário autenticado.

3.3.2 Estrutura de navegação


Para esta aplicação, o usuário precisa ter 4 grandes iterações com o aplicativo:
selecionar o produto a partir de uma loja, finalizar o carrinho, acompanhar o andamento
do produto e visualizar suas informações pessoais. Desta forma, a aplicação foi dividida
em quadro pilhas de navegação chamadas de: perfil, lojas, pedidos e carrinho. Cada pilha
foi criada com o auxílio de uma biblioteca de navegação chamada React Navigation 32 .
Esta biblioteca expõe uma API de navegação em React Native com integração com as
plataformas Android e iOS. Ela fornece uma estrutura chamada Stack Navigation, pilha
de navegação em tradução livre, que fornece um meio do aplicativo fazer a transição entre
telas onde cada nova tela é colocada no topo da pilha. Esta estrutura foi utilizada para que
o usuário pudesse interagir com as quatro pilhas de navegação mencionadas anteriormente.

31
Com a introdução dos novos React Hooks, funções também possuem estados
32
https://reactnavigation.org/
Capítulo 3. Desenvolvimento 41

Uma quinta estrutura, chamada de BottomTabNavigator (navegação nas abas de baixo,


em tradução livre) foi utilizada a estrutura pai, como mostra o diagrama da figura 16.

Figura 16 – Estrutura de navegação da aplicação móvel


Fonte – Própria

1. Store stack: pilha de navegação que contém as telas usadas para que o usuário
possa selecionar o seu endereço de entrega, selecionar a uma loja, ver o catálogo de
uma loja selecionada e adicionar um produto ao seu carrinho;

2. Checkout stack: pilha de navegação que contém as telas usadas para que o usuário
finalize a sua compra. Nesta pilha, temos as seguintes telas: carrinho e seleção de
método de pagamento;

3. Order Stack: nesta pilha de navegação estão as telas: pedidos ativos, histórico de
pedidos e detalhes do pedido;

4. Profile Stack: a última pilha de navegação contém as telas para que o usuário
edite suas informações pessoais, sugira um estabelecimento, demonstre interesse em
cadastrar-se como parceiro, mudança de senha e detalhes gerais da aplicação.

3.3.2.1 Store stack: a listagem de lojas

Esta é a primeira pilha de navegação que o usuário verá quando interagir com
esta aplicação de e-commerce para delivery. Neta pilha, as telas são componentes React
que foram separados em arquivos com os mesmos nomes dos components: StoreList.js,
StoreDetails.js, ProductDetails.js e AddressList.js. Esta estrutura é mostrada na figura 17.
Quando o componente StoreList é montado, o primeiro método chamado é a Função
de Ciclo de vida componentDidMount, executada automaticamente pelo React. Dentro
deste método, é chamado o método assíncrono _fetchDataAsync. Ele tem como objetivo
requisitar da API quais lojas entregam no endereço selecionado pelo usuário e atualizar o
estado do componente com esta lista. Por consequência, como mencionado na seção acima,
Capítulo 3. Desenvolvimento 42

Figura 17 – Pilha de navegação, lojas, seleção de produtos e endereço


Fonte – Própria

a função render deste componente é chamada e as informações são mostradas ao usuário


no formato de uma interface amigável a seres humanos. Esta interface mostra as lojas em
dois estados: abertas ou fechadas, com as abertas no topo da lista.
Neste momento, o usuário tem a lista de lojas que entregam no endereço selecionado,
podendo selecionar qual o estabelecimento irá consultar o catálogo. Ao clicar em uma loja
aberta, a aplicação realiza a navegação para a tela StoreDetails, colocando-a no topo da pilha
Store stock, passando como props o identificador desta mesma loja. Ao ser montada, a tela,
um componente React, tem o seu método componentDidMount executado automaticamente
pela biblioteca. Dentro dele, o método assíncrono _fetchDataAsync é chamado. Ele tem
como objetivo requisitar da API o catálogo de produtos do estabelecimento selecionado
e lidar com os possíveis erros de resposta. Alguns destes erros são: a loja fechou entre o
momento que a aplicação solicitou a lista de lojas para o endereço selecionado e a seleção
propriamente dita da loja pelo usuário.
Ainda na tela de StoreDetails, o usuário pode selecionar um produto. Esta ação
faz com que a aplicação navegue para a tela ProductDetails, passando como props o
identificador deste mesmo produto. Ao ser montada, a tela, um componente React, tem o
seu método componentDidMount executado automaticamente pela biblioteca. Dentro dele,
o método assíncrono _fetchDataAsync é chamado. Ele tem como objetivo requisitar da
API os detalhe do produto selecionado e lidar com os possíveis erros de resposta. Neste
caso, o usuário verá as informações do produto e suas variantes. É importante mencionar
que, como citado na seção Catálogo: o módulo de vitrine, o preço não se encontra no
produto em si, mas em suas variantes. E são estas variantes que são selecionadas pelo
usuário. Após isto ele pode, então, selecionar o botão para adicionar ao carrinho. Uma
mensagem de sucesso na adição ao carrinho é exibida e o usuário pode escolher se quiser
continuar comprando ou ser direcionado ao carrinho.
Capítulo 3. Desenvolvimento 43

3.3.2.2 Checkout stack: a realização do pedido

Após o usuário escolher ir ao carrinho, a aplicação navega até a pilha de Checkout.


Nesta pilha, as telas são componentes React que foram separados em arquivos com os
mesmos nomes dos components: Cart.js e SelectPaymentMethod.js, como mostrados na
figura 18.

Figura 18 – Pilha de navegação de realização do pedido: carrinho e seleção de pagamento


Fonte – Própria

A primeira tela desta pilha a ser mostrada ao usuário é a tela Cart, cujo arquivo
de extensão JS possui o mesmo nome. Quando este componente React é montado o
primeiro método chamado é a Função de Ciclo de vida componentDidMount, executada
automaticamente pelo React. Dentro deste método, duas ações ocorrem: o componente
passa a ser ouvinte de um evento, e chama o método _componentDidFocus quando ele
ocorre, e o método assíncrono _validateCart é chamado.
O evento a qual o componente é assinalado como ouvinte é o didFocus (focou, em
tradução livre). Este é o evento de quando a tela está em foco, isto é, é a tela que está
sendo mostrada ao usuário naquele momento. O método _componentDidFocus implemen-
tado neste trabalho tem uma única função: chamar o método assíncrono _validateCart,
responsável por fazer uma requisição HTTP POST, com o seu corpo em formato JSON,
com o atual estado do carrinho para a API. Ou seja, toda vez que o usuário coloca a tela
Cart em foco, o método _validateCart é invocado.
Este é o método responsável por validar o carrinho do usuário. Nesta implementação,
uma escolha foi tomada para melhorar a experiência do usuário: o carrinho não é persistido
na API. Isto é, o carrinho é uma entidade efêmera, em memória, na aplicação cliente. O
motivo desta decisão é simples: evitar a necessidade de fazer chamadas à API todas as
vezes que carrinho sofresse qualquer alteração. Ou seja, toda vez que o usuário necessitasse
alterar uma quantidade de um produto, uma nova requisição deveria ser feita, deixando
cada iteração do usuário cada vez mais lenta. E, ao invés disso, a validação do carrinho é
chamada quando a tela está em foco. A validação do carrinho checa as seguintes regras de
negócio:
Capítulo 3. Desenvolvimento 44

1. Preço de entrega: checa se o preço da entrega que o usuário possui no carrinho


em memória é o mesmo que está na API;

2. Preço das variantes de produto: checa se o preço das variantes de produto que
o usuário possui no carrinho em memória é o mesmo que está na API;

3. Disponibilidade do produto: checa se as variantes de produto que o usuário


possui no carrinho em memória estão disponíveis na API;

4. Disponibilidade do lojista para o endereço selecionado: checa se o lojista


selecionado está entregando no endereço selecionado pelo usuário.

Com estas regras de negócio satisfeitas, o usuário pode, enfim, finalizar o seu
pedido. Ainda na tela Cart, o usuário pressiona um botão que invoca a função assíncrona
_placeOrder. Esta função faz uma requisição HTTP POST para a API, com o seu corpo em
formato JSON, com as informações do carrinho. A API valida as informações novamente,
com as mesmas regras de negócio da validação do carrinho, e responde com um código
HTTP 201, caso o pedido tenha sido criado, ou um código HTTP 400 caso alguma validação
tenha falhado. Em caso de erro, o usuário recebe um alerta com as mensagens de erro das
validações e em caso de sucesso, o usuário é redirecionado para página de pedidos ativos,
na Order Stack (pilha de pedidos, em tradução livre).

3.3.2.3 Order Stack: o acompanhamento dos pedidos

Após o usuário realizar o pedido, a aplicação navega até a pilha de pedidos. Nesta
pilha, as telas são componentes React que foram separados em arquivos com os mesmos
nomes dos components: ActiveOrders.js, OrderHistory.js e OrderDetails.js, como mostrados
na figura 19.

Figura 19 – Pilha de navegação do acompanhamento de pedidos


Fonte – Própria

Nesta pilha, a primeira tela a ser mostrada é a ActiveOrders, cujo arquivo de extensão
JS possui o mesmo nome. Quando este componente React é montado o primeiro método
chamado é a Função de Ciclo de vida componentDidMount, executada automaticamente
Capítulo 3. Desenvolvimento 45

pelo React. Dentro dele, o método assíncrono _fetchDataAsync é chamado com o objetivo
de requisitar os pedidos ativos do usuário autenticado. Como mencionado na seção 3.1.4,
cada pedido possui um status do tipo inteiro. Nesta implementação, cada pedido tem os
seguintes estados:

1. Aguardando Confirmação: quando um pedido é criado corretamente e está aguar-


dando confirmação do parte do lojista;

2. Pagamento Pendente: quando um pedido é criado corretamente, com o pagamento


online selecionado mas ainda não verificado;

3. Pedido Confirmado: quando um pedido criado corretamente, que estava aguar-


dando confirmação é confirmado pelo lojista. Isto significa que o lojista irá entregar
os produtos requisitados pelo usuário;

4. Saiu para Entrega: quando um pedido que foi confirmado pelo lojista é despachado
por ele para que seja entregue ao usuário;

5. Pedido finalizado: quando um pedido despachado pelo lojista é recebido pelo


usuário corretamente;

6. Pedido cancelado: quando um pedido não pôde ser finalizado por algum motivo.
Por exemplo: falta de estoque, indisponibilidade do motoqueiro, recusa de recebimento
por parte do cliente, fim do horário de entrega, dentre outros.

Entende-se como pedido ativo, qualquer pedido que tenha um status diferente de
5 ou 4 (Pedido cancelado, ou Pedido finalizado, respectivamente. E são estes os pedidos
retornados pela API, em formato JSON, na chamada do método _fetchDataAsync. Este
mesmo método é responsável por atualizar o estado do componente com a lista retornada
pelo servidor. Nest momento, o React invoca o método render. Por consequência, como
mencionado na seção acima, a função render deste componente é chamada e as informações
são mostradas ao usuário no formato de uma interface amigável a seres humanos.
Ainda nesta pilha de navegação, o usuário autenticado pode escolher ver o seu
hatórico de pedidos. Quando realizada tal ação, a aplicação navega até a tela OrderHistory
cujo arquivo de extensão JS possui o mesmo nome. Quando este componente React é
montado o primeiro método chamado é a Função de Ciclo de vida componentDidMount,
executada automaticamente pelo React. Dentro dele, o método assíncrono _fetchDataAsync
é chamado com o objetivo de requisitar à API, através de uma requisição HTTP GET,
os dados dos pedidos finalizados ou cancelados, isto é, pedidos cujo status sejam 5 ou
4. Ao receber os dados, em formato JSON, o componente atualiza o seu estado com as
informações recebidas. Por consequência, como mencionado na seção acima, a função
Capítulo 3. Desenvolvimento 46

render deste componente é chamada e a lista é mostrada ao usuário no formato de uma


interface amigável a seres humanos.
Em qualquer uma das duas listas: pedidos ativos ou histórico pedidos, o usuário
pode selecionar um para ver os detalhes daquele pedido. Quando tal ação acontece, a
aplicação navega até a tela OrderDetails cujo arquivo de extensão JS possui o mesmo
nome. Quando este componente React é montado o primeiro método chamado é a Função
de Ciclo de vida componentDidMount, executada automaticamente pelo React. Dentro
dele, o método assíncrono _fetchDataAsync é chamado com o objetivo de requisitar à
API, através de uma requisição HTTP GET, os dados do pedido selecionado. Ao receber
os dados, em formato JSON, o componente atualiza o seu estado com as informações
recebidas. Por consequência, como mencionado na seção acima, a função render deste
componente é chamada e os detalhes do pedido selecionado são mostrados ao usuário no
formato de uma interface amigável a seres humanos. Estes detalhes incluem: loja a qual o
pedido foi feito, itens do pedido, valor de entrega, valor total, forma de pagamento, estado
atual do pedido e endereço de entrega.

3.3.2.4 Profile Stack: os dados pessoais

Cada usuário cadastrado possui suas informações pessoais, tais como: e-mail, nome,
telefone, CPF, data de nascimento e senha. E o usuário tem a opção de editar toda
estas informações com exceção da data de nascimento e o CPF. Estas informações são
apresentadas nesta pilha. As telas são componentes React que foram separados em arquivos
com os mesmos nomes dos componentes: Profile.js, EditProfile.js e ChangePassword.js,
como mostrados na figura 32.

Figura 20 – Pilha de navegação do perfil do usuário


Fonte – Própria

Nesta pilha, a primeira tela a ser mostrada é a Profile, cujo arquivo de extensão
JS possui o mesmo nome. Antes deste componente React ser montado, as informações do
usuário são resgatadas através do mapeamento dos estados da aplicação para props do
componente. Quando ele inicia a montagem, a função render é chamada e estes dados são
mostrados ao usuário no formato de uma interface amigável a seres humanos. O usuário
tem duas opções: editar seus dados pessoais ou trocar a sua senha.
Capítulo 3. Desenvolvimento 47

Quando escolhe editar os seus dados, a aplicação navega até a tela EditProfile. Nela,
antes deste componente React ser montado, as informações do usuário são resgatadas
através do mapeamento dos estados da aplicação para props do componente. Para, assim,
serem mostradas ao usuário como um formulário pré-preenchido. Qualquer mudança
feita pelo usuário, requer que ele confirme-as apertando um botão. Com isso, o método
_patchUserInfo é chamado e uma requisição HTTP PATCH é feita para a API contendo
como corpo, em formato JSON, apenas os campos alterados pelo usuário.
Quando o usuário escolhe mudar a sua senha, a aplicação navega até a tela Change-
Password. Nela, quando o componente é montado, o seu estado inicial é definido na tabela
3.

Tabela 3 – Estado inicial do componente ChangePassword.js

Estado Valor
ActualPassword null
NewPassword null
ConfirmNewPassword null
Fonte – Própria

Os valores são iniciados como null, isto é, nulos, pois devem ser preenchidos pelo
usuário. O componente pai ChangePassword é um formulário de mudança de senha com três
entradas: a senha atual, a nova senha e a confirmação da nova senha. Cada entrada é um
componente React filho. Como são componentes com apenas 1 grau de profundidade, seus
estados são salvos no componente pai, o ChangePassword. Cada um dos componentes filhos
recebem como props o valor inicial definido na tabela 3: ActualPassword, NewPassword,
ConfirmNewPassword, respectivamente. Quando o usuário preenche todos os campos e
confirma a edição, o método assíncrono _updateUserPassword é chamado. Este método
faz uma requisição HTTP POST para a API. Caso as informações estejam corretas, o
senha do usuário autenticado é atualizada e uma resposta HTTP 200 é fornecida pela API.
Caso algum erro de validação ocorra, a API retorna um HTTP 400 detalhando os erros no
formato JSON.
48

4 RESULTADOS E DISCUSSÕES

4.1 Interfaces da aplicação móvel


As interfaces finais da aplicação desenvolvida são apresentadas nas imagens seguintes.
As sequências de imagens representam a jornada de um usuário, devidamente autenticado,
que deseja adquirir um produto para entrega. Cada sequência diz respeito a uma Stack de
navegação descrita na seção 3.3.2. A estrutura do BottomTabNavigator, descrita na figura
16 tem sua interface final mostrada na figura abaixo, em um iPhone 1 , onde o componente
pai BottomTabNavigator encontra-se em destaque.

Figura 21 – BottomTabNavigator destacado em vermelho


Fonte – Própria

Como citado na 3.3.2, este componente pai possui quatro componentes filhos. Cada
1
https://www.apple.com/iphone/
Capítulo 4. Resultados e Discussões 49

um destes componentes, chamados nesta implementação de Pilhas de Navegação, estão


presentes na BottomTabNavigator. A figura 22 mostra cada uma destas pilhas, enumeradas
de 1 a 4. A tabela 4 mostra qual pilha pertence a qual aba da navegação.

Figura 22 – Pilhas de navegação filhas do componente BottomTabNavigator


Fonte – Própria

Tabela 4 – Mapeamento da figura 22 para as pilhas de navegação

Númeração Pilha de navegação


1 Store stack
2 Checkout stack
3 Order Stack
4 Profile Stack
Fonte – Própria

4.1.1 Store stack


Nesta primeira pilha de navegação, como mencionado na seção 3.3.2.1, temos três
telas, com responsabilidades diferentes. A figura 23 mostra a interface final destas telas,
enumeradas de 1 a 3. A tabela 5 mapeia o número mostrado na figura 23 com as descritas
na seção 3.3.2.1.

Tabela 5 – Mapeamento da figura 22 para as pilhas de navegação

Númeração Tela
1 StoreList.js
2 StoreDetails.js
3 ProductDetails.js
4 AddressList.js
Fonte – Própria

Como também descrito na seção 3.3.2.1, há dois casos de uso para as telas desta
pilha de navegação: seleção de endereço e adição de um produto no carrinho. O caso de
uso de seleção de endereço é representado, sequencialmente, na figura 24. Já a adição dos
produtos no carrinho é representado, sequencialmente, na figura 25. As ações tomadas pelo
Capítulo 4. Resultados e Discussões 50

Figura 23 – Pilha de navegação de lojas


Fonte – Própria

usuário em cada tela são destacadas por um quadrado vermelho. A sequência de ações é
enumerada no topo de cada tela.
A figura 24 mostra dois passos que o usuário necessita fazer ao selecionar o seu
endereço Primeiro, o usuário deve tocar em algum ponto da barra de endereço. Assim,
a aplicação irá navegar para a tela AddressList.js. Quando a tela, que é um componente
React, é montada, a requisição dos endereços do usuário autenticado é feita para o servidor,
através de uma requisição HTTP GET. Quando a tela recebe a resposta, atualiza o estado
do componente, fazendo com que o método render seja chamado e a lista de usuários
seja renderizada, como mostra a figura 24. Ao selecionar um dos endereços, uma função
de Callback, passada pelo componente anterior (a tela StoreList.js) através de props, é
chamada para atualizar o estado do componente pai. Assim, após a escolha do endereço, o
usuário é navegado de volta para a tela inicial.
A figura 25 demonstra o caso de uso em que o usuário adiciona um produto ao
carrinho. Inicialmente, o usuário é apresentado a tela de StoreList, mostrando todas as lojas
que entregam no endereço selecionado pelo usuário no caso de uso anterior. Primeiro, neste
exemplo, o usuário toca na loja "DrinkApp (Loja Teste)", ação que faz a aplicação navegar
até a página StoreDetails, passando como props o identificador da loja selecionada pelo
usuário. Quando chega no passo 2, a tela requisita da API os produtos da loja escolhida e
renderiza a resposta para o usuário, como mostra o passo 2 da figura 25. Neste exemplo, o
usuário toca no produto "SKOL BEATS SENSE", ação que faz a aplicação navegar até a
Capítulo 4. Resultados e Discussões 51

Figura 24 – Caso de uso: selecionar um endereço


Fonte – Própria

página ProductDetails, passando como props o identificador do produto selecionado pelo


usuário. Quando chega no passo 3, a tela ProductDetails requisita da API os dados do
produto escolhido e renderiza para o usuário, como mostra o passo 3 da figura 25. Ainda
neste passo, com o produto selecionado, o usuário toca no botão "Adicionar"para adicionar
ao carrinho. Após, o usuário é redirecionado para uma outra pilha de navegação: Checkout
stack.

Figura 25 – Caso de uso: adicionar produto ao carrinho


Fonte – Própria
Capítulo 4. Resultados e Discussões 52

4.1.2 Checkout Stack


Como mostrado na seção 3.3.2.2, a pilha de navegação Checkout Stack possui duas
telas: Cart.js e SelectPaymentMethod.js. A figura 26 mostra a interface final destas telas,
enumeradas de 1 a 2. A tabela 5 mapeia o número mostrado na figura 26 com as descritas
na seção 3.3.2.1.

Figura 26 – Caso de uso: adicionar produto ao carrinho


Fonte – Própria

Tabela 6 – Mapeamento da figura 26 para as telas da pilha de navegação

Númeração Tela
1 Cart.js
2 SelectPaymentMethod.js
Fonte – Própria

A figura 26 demonstra a jornada do usuário para finalizar o seu pedido. Como


Capítulo 4. Resultados e Discussões 53

mencionado na seção 3.3.2.1, a primeira tela a ser mostrado ao usuário é a tela Cart.js.
Quando esta tela entra em foco, uma requisição HTTP POST é feita para a API para
validar as informações do carrinho, como descrito na seção 3.3.2.1. Com o carrinho validado,
o usuário necessita tomar mais duas ações obrigatórias: escolher a forma de pagamento e
finalizar o pedido.
No estado atual, para finalizar o pedido, o é necessário que o usuário forneça a
forma de pagamento. Para isso,o usuário seleciona a opção "Escolher"na tela Cart.js,
destacada com um quadrado vermelho. Esta ação faz a aplicação navegar para a tela
SelectPaymentMethod.js, passando como props o identificador da loja escolhida pelo usuário
para realizar o seu pedido e uma função de Callback, utilizada para atualizar o estado do
componente Cart.js com a forma de pagamento escolhida. Quando montada, a tela de
seleção de pagamentos requisita à API quais os métodos de pagamento aceitos pela loja
selecionada pelo usuário, através de uma requisição HTTP GET. A resposta, em formato
JSON, é uma lista de todos os métodos de pagamento aceitos pela loja. Então, o usuário
seleciona o meio de pagamento que lhe for mais conveniente. Esta ação invoca a função de
Callback passada via props, mencionada anteriormente, fazendo com que o estado da tela
anterior seja atualizado com a forma de pagamento escolhida e a aplicação navegue de
volta para tela anterior.
Por fim, após a seleção do método de pagamento, o usuário tem preenchido todos
os campos obrigatórios para a realização do pedido. Opcionalmente, ele também pode
escolher por adicionar o CPF, para que o lojista emita uma nota fiscal com esta informação.
Caso escolha fornecer este dado ou não, o usuário pode deslizar a tela e tocar no botão de
título "FINALIZAR PEDIDO", como mostrado na figura 27.
Neste momento, a aplicação faz uma requisição HTTP POST para a API para
criar o novo pedido. Aqui, a API refaz todas as validações do carrinho descritas na seção
3.3.2.2. Em caso de falha, recebe um HTTP 400 com as mensagens de erro. Em caso
de sucesso, recebe um código HTTP 201 - significando a criação do pedido. Ainda no
caso de sucesso, o componente Cart.js atualiza o seu estado em nível de componente.
O estado showSuccessModal é assinalado como verdadeiro, o método render é invocado
automaticamente pela biblioteca e uma mensagem de sucesso é mostrada para o usuário.
Dentro dela, o usuário tem a opção de acompanhar o seu pedido recém criado. Ao tocar
no botão "Ver pedido", como mostrado na figura 27, a aplicação navega para uma pilha de
navegação: Order Stack.

4.1.3 Order Stack: acompanhando os pedidos


Como mostrado na seção 3.3.2.3, a pilha de navegação Order Stack possui três
telas: ActiveOrders.js, OrderHistory.js e OrderDetails.js. A figura 28 mostra a interface
Capítulo 4. Resultados e Discussões 54

Figura 27 – 1: usuário toca no botão "FINALIZAR PEDIDO"; 2: o usuário toca no botão


para ver o andamento do pedido recém criado
Fonte – Própria

final destas telas, enumeradas de 1 a 3. A tabela 7 mapeia o número mostrado na figura


28 com as descritas na seção 3.3.2.3.

Tabela 7 – Mapeamento da figura 28 para as telas da pilha de navegação

Númeração Tela
1 ActiveOrders.js
2 OrderHistory.js
3 OrderDetails.js
Fonte – Própria

Quando o usuário é navegado para esta pilha de navegação, a primeira tela mostrada
é a ActiveOrders. Quando montado, este componente React faz uma requisição HTTP GET
à API para receber os pedidos das últimas 24h realizados pelo usuário autenticado. Quando
a tela recebe a resposta, uma lista em formato JSON, atualiza o etado do componente,
fazendo com que o método render seja chamado e a lista de pedidos seja renderizada,
como mostra a tela 1 da figura 28.
Como mencionado, na seção 3.3.2.3, cada pedido possui um estado. Nesta implemen-
tação, não foi feita uma interface para o estado número 2 (pagamento pendente) porque a
Capítulo 4. Resultados e Discussões 55

Figura 28 – Pilha de navegação Order Stack


Fonte – Própria

funcionalidade de pagamento online não foi implementada, será uma função futura. Entre-
tanto, todos os estados são mostrados na figuras 30 e 29. A figura 30 mostra os pedidos
nos estados de: aguardando confirmação, confirmado e saiu para entrega, respectivamente.
Já a figura 30 mostra a interface dos pedidos já finalizados ou cancelados, isto é, com
estados 6 e 5, respectivamente.

Figura 29 – Estados dos pedidos: 5 e 6


Fonte – Própria

Quando um usuário toca em um dos pedidos, a aplicação navega para a tela de


OrderDetails, passando como props as informações do pedido já obtidas na tela anterior.
Capítulo 4. Resultados e Discussões 56

Figura 30 – Estados dos pedidos: 1, 3 e 4


Fonte – Própria

A tela de OrderDetails tem três modos: se o pedido está em andamento (estado de 1 à


4), se o pedido foi cancelado ou se foi finalizado. A interfaces implementadas para estes
três casos é mostrada na 31. No primeiro caso, a interface mostra ao usuário qual o estado
atual e quais os subsequentes. Na figura 31, a tela 1 mostra um pedido que saiu para ser
entregue ao usuário comprador. No segundo caso, a interface mostra os detalhes de um
pedido cancelado. A interface mostra que o pedido foi cancelado e mostra o motivo do
cancelamento: "A loja encerrou o horário de entrega". Também é sugerido o usuário volte
a comprar, através de um botão, para que ele possa ter o seu problema resolvido. Por fim,
o terceiro caso mostra um pedido que foi devidamente entregue e finalizado. Neste caso, o
usuário pode avaliar a sua experiência com uma nota discreta de 1 até 5, conferir os itens
desta compra, valores, endereço de entrega e forma de pagamento.

4.1.4 Profile Stack: os dados do pessoais


Como mostrado na seção 3.3.2.4, a pilha de navegação Profile Stack possui três
telas: Profile.js, EditProfile.js e ChangePassword.js. A figura 32 mostra a interface final
destas telas, enumeradas de 1 a 3. A tabela 8 mapeia o número mostrado na figura 32
com as telas descritas na seção 3.3.2.3.
Quando a aplicação navega até a pilha de navegação de perfil, através de um toque
do usuário no item 4 da figura 22, o usuário é apresentado à tela Profile. Esta tela, ao
Capítulo 4. Resultados e Discussões 57

Figura 31 – Página de detalhes do pedido. 1: em andamento, 2: cancelado, 3: finalizado


Fonte – Própria

Figura 32 – Página de perfil do usuário. 1: perfil, 2: editar perfil, 3: mudar senha


Fonte – Própria
Capítulo 4. Resultados e Discussões 58

Tabela 8 – Mapeamento da figura 32 para as telas da pilha de navegação

Númeração Tela
1 Profile.js
2 EditProfile.js
3 ChangePassword.js
Fonte – Própria

ser montada, recupera as informações do usuário autenticado e atualiza o seu estado em


nível de componente. Por consequência, o React invoca o método render e o componente
renderiza a tela 1 da figura 32 para o usuário. Na imagem, os dados pessoais do usuário
são parcialmente cobertos para que a privacidade seja mantida. A tela Profile.js apresenta
6 opções para o usuário da quais apenas 2 ocasionam em navegação na plataforma: edição
de perfil e troca de senha. As demais opções levam o usuário para um site ou aplicativo de
e-mail padrão do telefone.
Quando o usuário seleciona a edição de perfil, tocando no lápis presente no canto
superior direito da tela 1 da figura 32, a aplicação navega até a tela EditProfile. Quando
montada, a tela recupera as informações do usuário autenticado que estão presentes no
estado da em nível de aplicação. Assim, a tela invoca a função render e renderiza a interface
número 2 da figura 32. Novamente, os dados pessoais do usuário foram parcialmente cobertos
para que a privacidade seja mantida. O usuário pode editar os campos de: nome, e-mail
e telefone. CPF e data de nascimento são campos considerados imutáveis e não podem
ser atualizados pelo usuário. Após a edição, o usuário toca no botão "Salvar"para que
suas mudanças sejam persistidas na API. A aplicação faz uma requisição HTTP PATCH
apenas com as informações enviadas pelo usuário. Em caso de falha, a API retorna um
HTTP 400 com uma mensagem de erro. Mas nem todos os campos podem ser alterados.
Em caso de sucesso, o retorno da API possui um código HTTP 200, a aplicação mostra
uma mensagem de sucesso ao usuário e navega de volta para a tela Profile.js.
De volta a tela Profile.js, o usuário pode escolher mudar a sua senha tocando em
"Mudar a senha", fazendo a aplicação navegar até a tela ChangePassword.js. Esta tela,
diferente das outras, não recupera nenhuma informação, apenas renderiza o formulário
contento: senha original, nova senha e confirmação da nova senha. Ao finalizar o preen-
chimento do formulário, o usuário toca no botão "Salvar nova senha"para persisti-la na
API. No momento que o usuário toca neste botão, a aplicação móvel checa se a nova
senha e confirmação da nova senha são iguais. Se não, o usuário recebe uma mensagem de
erro avisando deste fato. Caso sim, a aplicação faz uma requisição HTTP POST para a
API contento no corpo a senha atual e a nova senha. A API vai checar se a senha atual
é realmente a enviada pelo usuário e, se sim, atualiza-la com a nova senha enviada na
requisição. Em caso de falha, a API retorna um HTTP 400 com uma mensagem contendo
Capítulo 4. Resultados e Discussões 59

o erro. Em caso de sucesso, o usuário recebe uma mensagem de sucesso e a aplicação


navega de volta para a tela de Profile.js.
60

5 CONCLUSÃO

Neste Capítulo são apresentadas as conclusões sobre este trabalho de pesquisa a


partir da visão dos objetivos gerais e secundários propostos, assim como as possibilidades
de trabalhos futuros.
Este trabalho teve como objetivo geral o desenvolvimento de uma plataforma de
e-commerce com foco em delivery, da API à aplicação móvel. Para atingir este objetivo
geral, foram traçados objetivos secundários como forma de checkpoints.
O primeiro objetivo secundário foi a modelagem do banco de dados para os casos
de uso do e-commerce. Para isto, foi necessário aplicar o conceito de diagrama entidade
relacional, entender de que forma as entidades se relacionam e, assim, disponibilizar uma
estrutura de banco de dados com uso focado para o delivery.
O segundo objetivo secundário foi a implementação das regras de negócio e dispo-
nibilização delas através de uma API. Com a ajuda do Django REST Framework e das
entidades modeladas no primeiro objetivo, as regras de negócio referentes a autenticação
de usuários, compra, venda e entrega de produtos foram possíveis.
O terceiro objetivo secundário foi a implementação da aplicação móvel. Utilizando
React Native, tecnologia baseada no desenvolvimento híbrido, foi possível desenvolver esta
aplicação e disponibiliza-la nas lojas de aplicativos App Store 1 e Play Store 2 sob o nome
DrinkApp - Delivery de Bebidas.
O quarto objetivo foi fazer com eque esta implementação seja utilizada por usuários.
Até às 23:59 do dia 22/11/2019, de acordo com os dados da App Store, o aplicativo final já
foi baixado 2346 vezes nesta plataforma e de acordo com a PlayStore o aplicativo final já
foi baixado 8566 vezes. Até às 16:05h do dia 23/11/2019, de acordo com a tabela CUstomer,
mencionada na seção 3.1.1, esta aplicação teve 6462 clientes cadastrados.
O quinto objetivo secundário foi a validação da implementação através de vendas e
cadastros da aplicação móvel. Os dados de downloads e cadastro foram citados acima. E,
até às 16:05h do dia 23/11/2019, esta aplicação já recebeu R$ 95,740.72 em pedidos.
Por estes cinco objetivos, a aplicação final conseguiu lograr êxito no que foi proposto
como objetivo deste trabalho.

1
https://www.apple.com/ios/app-store/
2
https://play.google.com/
Capítulo 5. Conclusão 61

5.1 Dificuldades
Para operacionalizar esta implementação, uma grande dificuldade foi conseguir uma
fonte fidedigna de códigos postais válidos. Devido a grande quantidade de cidades e bairros
com nomes repetidos, além da constante mudança dos números de CEP, a operacionalização
desta implementação sofreu algumas inconsistências, pois é completamente dependente de
uma base de códigos postais fidedigna. Uma solução para este problema é passara a utilizar
a localização geográfica como forma de determinação dos bairros, usando a abordagens de
polígonos para definir os bairros e estruturas como o GeoJSON para representa-los 3 .

5.2 Trabalhos futuros


Nesta Seção são apresentadas algumas sugestões para trabalhos futuros que com-
plementam a implementação realizada nesse trabalho. São elas:

a) A implementação de uma interface Web para o usuário cliente, trazendo mais um


canal de interação do usuário com o e-commerce;

b) Parar de utilizar o CEP como forma de definição de bairros e passar a utilizar uma
abordagem de localização, utilizando uma estrutura como GeoJSON;

c) Implementar um sistema de análise de dados para entender melhor o comportamento


do usuário na plataforma;

3
https://geojson.org/
62

REFERÊNCIAS

AMAZON. Amazon EC2 Instance Types - Amazon Web Services. 2019. Acessado em 12 de
Novembro de 2019. Disponível em: <https://aws.amazon.com/ec2/instance-types/>. 32
AMAZON. Amazon RDS. 2019. Acessado em 16 de Novembro de 2019. Disponível
em: <https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora-
.Integrating.AutoScaling.html>. 34
APPLE. Programming with Objective-C. 2014. Acessado em 14 de novembro de
2019. Disponível em: <https://developer.apple.com/library/archive/documentation-
/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html>.
20
APPLE. Start Developing iOS Apps (Swift). 2019. Acessado em 12 de novembro de
2019. Disponível em: <https://developer.apple.com/library/archive/referencelibrary-
/GettingStarted/DevelopiOSAppsSwift/>. 20
BELLONI, L. Como o iFood se tornou o maior aplicativo de delivery de comida
da América Latina. 2018. Acessado em 30 de agosto de 2019. Disponível em:
<https://www.huffpostbrasil.com/2018/04/18/como-o-ifood-se-tornou-o-maior-
aplicativo-de-delivery-de-comida-da-america-latina a 23414651/>. 21
BOOTH, D. et al. Web Services Architecture. 2019. Acessado em 09 de Novembro de 2019.
Disponível em: <https://www.w3.org/TR/ws-arch/>. 18
BRANGER, F. Transformação de um site de e-commerce em um e-marketplace.
FAMÍLIA FIGUEIREDO FESTAS PORTFÓLIO DIGITAL, 2015. Disponível em:
<https://www.unifacvest.net/assets/uploads/files/arquivos/3f2cb-branger,-f.-familia-
figueiredo-festas-portifolio-digital.-unifacvest,-2013..pdf>. 20
CLEMENT, J. Retail e-commerce sales worldwide from 2014 to 2023 (in billion
U.S. dollars). Statista, 2019. Acessado em 14 de novembro de 2019. Disponível em:
<https://www.statista.com/statistics/379046/worldwide-retail-e-commerce-sales/>. 12
DATE, C. J. Sql and relational theory - how to write accurate sql code. In: SQL and
Relational Theory. [S.l.]: O’Rilley Media, 2015. p. 81–102. ISBN 978-1-491-94117-1. 14
DJANGO. Django appears to be a MVC framework, but you call the Controller the
View, and the View the Template. How come you don’t use the standard names? 2019.
Acessado em 12 de Outubro de 2019. Disponível em: <https://docs.djangoproject.com/en-
/2.2/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-
the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names>.
34
DUSSEAULT, L.; SNELL, J. PATCH Method for HTTP. 2010. Acessado em 02 de
novembro de 2019. Disponível em: <https://tools.ietf.org/html/rfc5789>. 17
ELMASRI, R.; NAVATHE, S. B. Fundamentals of database systems. In: Fundamentals of
Database Systems. [S.l.]: Pearson, 2015. p. 745–780. ISBN 978-0-13-397077-7. 15
Referências 63

FERREIRA, L. As diferenças entre SQL e NoSQL: MySQL x MongoDB. 2018. Acessado


em 08 de outubro de 2019. Disponível em: <https://medium.com/devtranslate/diferencas-
entre-sql-e-nosql-51311f9069bd>. 16

FIELDING, R. et al. Hypertext Transfer Protocol – HTTP/1.1. 1999. Acessado em 19 de


novembro de 2019. Disponível em: <https://tools.ietf.org/html/rfc2616#section-9>. 17

FIELDING, R. T. Architectural styles and the design of network-based software


architectures. Doctoral dissertation, University of California, Irvine, 2000. Disponível em:
<https://www.ics.uci.edu/˜fielding/pubs/dissertation/top.htm>. 18, 19

FOWLER, P. J. S. e M. NoSQL distilled: a brief guide to the emerging world of polyglot


persistence. [S.l.]: Addison-Wesley Professional, 2012. ISBN 9780321826626. 16

GASIMOV, A. et al. Visiting mobile application development: What, how and where.
2010 Ninth International Conference on Mobile Business and 2010 Ninth Global Mobility
Roundtable (ICMB-GMR), IEEE, 2010. ISSN 0967-0661. 19

GEMELLI, B. G. M. Transformação de um site de e-commerce em um e-marketplace.


UCS, TRABALHO DE CONCLUSÃO DE CURSO, 2015. Disponível em: <https:/-
/repositorio.ucs.br/handle/11338/1206>. 20

HIRSCHBERG, C. et al. The changing market for food delivery. 2016. Acessado em 10
de Junho de 2019. Disponível em: <https://www.mckinsey.com/industries/technology-
media-and-telecommunications/our-insights/the-changing-market-for-food-delivery>.
12

HOEFLING, R. E-commerce – angel e re acessÓrios. CENTRO UNIVERSITARIO


UNIVESC, Trabalho de Conclusão de Curso, 2015. Disponível em: <https://www-
.unifacvest.net/assets/uploads/files/arquivos/7ba27-hoefling,-r.-e-commerce—angel-e-re-
acessorios.-unifacvest,-2012..pdf>. 21

HUYNH, M. et al. Hybrid app approach: Could it mark the end of native app domination?
Informing Science Institute, 2017. Disponível em: <http://iisit.org/Vol14/IISITv14p049-
065Huynh3472.pdf>. 19

JOORABCHI, M. E.; MESBAH, A.; KRUCHTEN, P. Real challenges in mobile app


development. 2013 ACM / IEEE International Symposium on Empirical Software
Engineering and Measurement, IEEE, 2013. Disponível em: <https://ieeexplore.ieee.org-
/abstract/document/6681334>. 19

KAPLAN-MOSS, J. REST worst practices. 2008. Acessado em 12 de Junho de 2019.


Disponível em: <hhttps://jacobian.org/2008/nov/14/rest-worst-practices/>. 25

KREMER, M. Ionic vs. React Native: A Comparison Guide. 2019. Acessado em 10 de


novembro de 2019. Disponível em: <https://ionicframework.com/resources/articles/ionic-
vs-react-native-a-comparison-guide>. 20

MAASS, J. E. Desenvolvimento de loja virtual utilizando plataforma de e-commerce open


source. UFTPR, TRABALHO DE CONCLUSÃO DE CURSO, 2013. Disponível em:
<http://repositorio.roca.utfpr.edu.br/jspui/bitstream/1/2010/1/PB COADS 2013 2 08-
.pdf>. 20
Referências 64

MACHADO, F. N. R.; ABREU, M. P. de. Projeto de banco de dados - uma visão prática.
In: Projeto de banco de dados. [S.l.]: Érica, 2012. p. 115–178. ISBN 978-8536502526. 15

MALI, N. Why does mobile commerce matter. BigCommerce, 2019. Acessado em 10


de novembro de 2019. Disponível em: <https://www.bigcommerce.com/blog/mobile-
commerce/#why-does-mobile-commerce-matter>. 12

MCAFEE; ALLIANCE, C. S. Custom Applications and IaaS Trends. 2019. Acessado


em 12 de Outubro de 2019. Disponível em: <https://www.mcafee.com/enterprise/en-
us/assets/skyhigh/white-papers/wp-csa-survey-custom-apps-iaas-survey-report.pdf>.
32

MONIRUZZAMAN, A. B. M.; HOSSAIN, S. A. Nosql database: New era of databases


for big data analytics - classification, characteristics and comparison. International
Journal of Database Theory and Application, Cornell University, 2013. Disponível em:
<https://arxiv.org/abs/1307.0191>. 16

NETWORK, M. M. D. HTTP request methods. 2019. Acessado em 10 de Novembro de


2019. Disponível em: <https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods>.
17

NETWORK, M. M. D. Hypertext Transfer Protocol (HTTP). 2019. Acessado em 10 de


Novembro de 2019. Disponível em: <https://developer.mozilla.org/en-US/docs/Web-
/HTTP>. 17

RAMOS, A. O que é MVC? 2019. Acessado em 14 de Novembro de 2019. Disponível em:


<https://tableless.com.br/mvc-afinal-e-o-que/>. 34

SHOPIFY. What is Ecommerce? 2019. Acessado em 14 de novembro de 2019. Disponível


em: <https://www.shopify.com/encyclopedia/what-is-ecommerce>. 12

SORAL, R. React Native vs Ionic: Comparing performance, User Experience and


much more. Ionic, 2018. Acessado em 16 de outubro de 2019. Disponível em: <https:-
//ionicframework.com/resources/articles/ionic-vs-react-native-a-comparison-guide>.
20

STACKOVERFLOW. StackOVerflow Trends. 2019. Acessado em 22 de novembro de 2019.


Disponível em: <https://bit.ly/33hsGtb>. 19

STACKOVERFLOW. Stackoverflow Trends. 2019. Acessado em 14 de Novembro de 2019.


Disponível em: <https://insights.stackoverflow.com/trends/>. 38

STATISTA. Market share of leading e-commerce software platforms and technologies


worldwide in 2017. 2017. Acessado em 15 de novembro de 2019. Disponível em: <https:/-
/www.statista.com/statistics/710207/worldwide-ecommerce-platforms-market-share/>.
12

UBER. When and where is Uber Eats available? 2019. Acessado em 22 de novembro de
2019. Disponível em: <https://help.uber.com/ubereats/article/when-and-where-is-uber-
eats-available-\?nodeId=3f8de61e-09dd-4844-afb2-749c9ffc65a8>. 21
Referências 65

ZIMER, B.; BARRETT, G.; METCALF, A. “app” 2010 word of the year, as voted
by american dialect society. American Dialect Society, American Dialect Society, 2011.
Disponível em: <https://www.americandialect.org/app-voted-2010-word-of-the-year-by-
the-american-dialect-society-updated>. 19

Você também pode gostar