NOTA - O seguinte está relacionado à construção de arquiteturas de software a partir do zero. Portanto, se você estiver interessado em conhecer o âmago da questão das tecnologias envolvidas, prossiga. Caso contrário, compartilhe com quem definitivamente vai adorar: P

De onde veio este guia

Eu mesmo trabalhei em alguns produtos em estágio inicial e, para ser sincero, cometi erros. Eu sempre desejei que houvesse uma lista de verificação a seguir ao criar um produto a partir do zero.

Há tantas coisas envolvidas na construção de uma arquitetura a partir do zero que você esquecerá totalmente certas peças. E eles voltarão para morder você nas etapas posteriores do ciclo do produto.

Finalmente, decidi criar essa lista de itens que você deve considerar antes de pressionar o botão de implantação pela primeira vez.

Portanto, sem mais desenvolvimentos, eis a lista de verificação que você deve seguir ao criar uma arquitetura de back-end para um produto do zero.

Escolha o idioma e a estrutura CORRETOS (para o seu projeto)

Escolher o idioma e a estrutura corretos para o seu produto é complicado, e não há nenhuma bala de prata específica para isso. Meu conselho é escolher um idioma com o qual você se sinta mais confortável e conheça os meandros de entrar e sair.

Dito isso, é raro, porque existem muito poucas pessoas que são Javascript Ninjas, ou Python Panthers, ou quaisquer nomes descolados.

Portanto, escolha uma linguagem que tenha um suporte realmente bom no setor, como Javascript, Python, Java ou Vá para citar alguns. Você pode escolher qualquer idioma, basta escolher qual é o mais confortável para você.

E lembre-se: você está construindo um MVP (Produto Mínimo Viável) e estará no processo de criação de um POC (Prova de Conceito). Portanto, tire seu produto o mais rápido possível. Você não precisa ficar preso em questões que possam vir do novo idioma da cidade. Para evitar esses problemas, escolha um idioma mais amplamente usado e bem documentado.

Por fim, você pode escalar posteriormente. Se você estiver na fase de fazer POCs, apenas crie e conclua. Mas se você está construindo algo realmente específico, e há uma linguagem e uma estrutura criadas especialmente para isso, você definitivamente deve escolher essa tecnologia.

Mas na maioria das vezes, os problemas que estamos tentando resolver podem ser facilmente resolvidos com qualquer uma das linguagens mencionadas acima e suas respectivas estruturas. Então, basta escolher um e iniciar o seu produto.

Um bom recurso para ajudá-lo a decidir -

https://content.techgig.com/top-5-programming-languages-for-backend-web-development/articleshow/67337449.cms

Implementar microsserviços de autenticação e autorização

Existem várias maneiras de autenticar e autorizar um usuário. Você pode experimentar os tokens de sessão, JWT (JSON Web Tokens) ou OAuth, para citar alguns. Cada opção tem seus próprios prós e contras. Então, vamos olhar para alguns deles mais de perto.

Tokens da Web JSON

Os JWTs são rápidos e fáceis de implementar. Isso ocorre porque os tokens nunca são armazenados em nenhum lugar do seu sistema. Eles são apenas codificados, criptografados e enviados ao usuário. Portanto, validar um JWT é mais rápido que qualquer outro método.

Porém, como eles não estão armazenados no sistema, não é possível fazer com que um token expire antes do tempo real de expiração, e isso pode ser um problema em alguns casos.

Então, descubra os prós e os contras de cada sistema de autenticação e escolha o que melhor se adapta aos seus requisitos. Pessoalmente, prefiro JWTs (mas essa é minha própria escolha).

Autorização

Nunca se esqueça de implementar a autorização dos usuários. Você não deseja que o Usuário1 conectado altere os detalhes do Usuário2. Isso pode causar puro caos no seu sistema.

Identifique os terminais que precisam de autorização e implemente-os imediatamente. Você não deseja que o estado do seu banco de dados seja corrompido assim. Lembre-se da diferença entre 401 e 403.

A seguir estão alguns pontos finais que você definitivamente deve considerar ao criar seu sistema de autenticação (eu criei um no Django usando JWT). Pode haver certas adições / exclusões para o seu caso de uso, mas estas são as que você deve considerar construir.

Muitas estruturas as fornecem prontas para uso, mas considere-as antes de construí-las por conta própria. Verifica authentication_classes e permission_classes no Django Rest Framework para referência adicional.

Dê uma olhada neste recurso do Django REST Framework -

https://www.django-rest-framework.org/tutorial/4-authentication-and-permissions/

Screenshot 2020 04 20 at 4.40.10 PM

Crie um modelo base abstrato a ser herdado por todos os outros modelos em seu banco de dados

Lembre-se do princípio DRY – não se repita? Deve ser seguido até o núcleo em Engenharia de Software.

Com base no processo de pensamento acima, haverá no seu banco de dados determinadas colunas que estarão presentes em todas as tabelas. Portanto, é melhor criar uma classe abstrata para eles, para que outras Classes de Modelo possam herdar delas.

Screenshot 2020 04 20 at 4.48.32 PM

Vamos analisar esse código e o que isso significa:

  • Eu iria + Embora não esteja escrito aqui, é criado automaticamente pelo framework Django. Mas se não estiver no seu, escreva-o nesta classe. É apenas um campo incrementado automaticamente que pode ser usado como uma chave primária na sua relação de banco de dados.
  • criado em – Isso implica quando o campo / linha foi inserido na sua tabela e é preenchido pela própria estrutura. Você não precisa defini-lo explicitamente.
  • updated_at – Isso implica quando o campo / linha foi modificado / atualizado pela última vez na sua tabela e, novamente, é preenchido pela própria estrutura.
  • delete_at + is_deleted – Então este é um campo controverso. Não tenho uma resposta exata para saber se deveria estar lá ou não – porque, para ser sincero, nada na internet é excluído. Este campo, se preenchido, mostra que a linha é excluída do sistema (embora os dados permaneçam no sistema para futuras referências e possam ser retirados do banco de dados e armazenados em backups)
  • uuid – Depende se você deseja colocar isso na sua mesa ou não. Se você precisar expor a chave primária da sua tabela a um sistema externo, é melhor expor essa chave em vez do campo inteiro incrementado automaticamente. Você pode se perguntar por que …? Bem, por que você gostaria de dizer a um sistema externo que você tem 10378 pedidos em sua tabela? Mas, novamente, é uma escolha pessoal.

Configurar um microsserviço de notificação

Todo produto precisa enviar lembretes e notificações ao usuário para fins de interação e transação. Portanto, todo produto precisará disso.

Você definitivamente deve considerar a criação de um microsserviço que forneça serviços de notificação (como notificação por push, e-mails e SMS) para seus usuários finais.

Este deve ser um microsserviço separado. Não crie isso dentro do microserviço de autenticação ou do serviço de aplicativos (a lógica de negócios real).

Existem muitas bibliotecas / serviços de terceiros que podem ser usados ​​para compilá-lo para seu aplicativo. Alavancá-los e construí-lo em cima disso.

Lembre-se de criar todas as 3 funcionalidades:

  • Notificações por push (APNS + FCM),
  • E-mails (basta integrar um cliente SMTP para iniciar)
  • e SMS

NOTA – Tenha dois canais para enviar SMS, transacional e promocional. Nunca envie um SMS promocional em um canal transacional, pois há chances de você ser processado por um usuário bem informado e motivado.

Uma maneira fácil de configurar seu cliente SMTP no seu aplicativo é usando isso nas suas configurações:

Screenshot 2020 04 20 at 5.05.44 PM

Eu fiz isso no Django, mas você pode fazer o mesmo na linguagem e estrutura escolhidas.

Configurar o log de erros

Use um middleware para registrar erros que ocorrem no seu sistema de produção. Seu sistema de produção não será monitorado por humanos sentados lá para ver os logs do aplicativo 24/7. Portanto, você precisará de um sistema que registre esses erros internos do servidor em um local central. Depois, você pode checá-los diariamente ou criar um webhook para que você possa ser alertado no momento certo e cuidar deles.

Existem muitas ferramentas de registro de erros de terceiros no mercado. Basta escolher qualquer um que atenda às suas necessidades. Eu uso principalmente Sentry / Airbrake.

Screenshot 2020 04 20 at 5.14.22 PM

Considere configurar webhooks, como mencionei acima. Eles informarão seus usuários sobre erros e, por exemplo, você poderá publicá-los como e quando ocorrerem em determinados canais frouxos. Em seguida, você pode verificar esses canais regularmente e corrigi-los com base em sua gravidade.

Página inicial oficial do Airbrake – https://airbrake.io/

Página inicial oficial da Sentinela – https://sentry.io/welcome/

Implementar solicitação – resposta e log do aplicativo

Cenário – Um usuário entra em seu suporte e diz que não recebeu o Recibo transacional pela compra que fez no site. O que você vai fazer?

Se você colocou o Registro de aplicativos no seu sistema, não se preocupe. Agora, o que quero dizer com isso? É sempre melhor mostrar um exemplo do que tentar explicar com palavras. Então aqui está:

Screenshot 2020 04 20 at 5.26.51 PM

Registrei que estou prestes a enviar o email para o email_id mencionado. Posso verificar nos logs do aplicativo para ver se o email foi realmente enviado ao cliente, verificando se esse log existe no sistema. Certifique-se de inserir logs abrangentes em seu sistema para poder rastrear a jornada da solicitação.

Além disso, é uma boa idéia implementar um sistema assíncrono que escolha esses logs de aplicativo-resposta e aplicativo do seu sistema e os despeje em um local central. Lá eles podem ser processados ​​para serem mais facilmente interpretáveis.

A pilha ELK é uma boa opção para isso: ElasticSearch – Logstash – Kibana.

Mais sobre a pilha ELK – https://www.elastic.co/what-is/elk-stack

NOTA – Ao registrar a solicitação e as respostas, cuide do seguinte:

  • Não registre senhas.
  • Não registre tokens (os tokens de acesso usados ​​para autenticação)
  • Não registre OTPs

Introduzir otimização em suas APIs e limitar a taxa nos servidores de aplicativos

Cenário – Você acabou de lançar seu serviço e comercializou o produto nas plataformas de mídia social. Um hacker de chapéu preto descobriu e só queria brincar com seu sistema. Então eles planejaram um ataque do DOS (Denial of Service) no seu sistema.

Para combater isso, você pode definir o limite de taxa com base em vários fatores, além dos balanceadores de carga para os servidores de aplicativos. Isso cuidará dos ataques do DOS e impedirá que o usuário mal-intencionado ataque seus servidores.

Cenário – O terminal da API / otp / validate, que utiliza OTPs de 4 dígitos para autenticar o usuário e devolve tokens para serem usados ​​nas APIs autenticadas. Um usuário mal-intencionado obtém o número de celular de um de seus clientes e começa a atingir o ponto de extremidade da API com um ataque de força bruta alterando os IPs, um ataque DDOS (Negação de Serviço Distribuída). O limitador de taxa não pode parar o usuário, porque o IP continua mudando a cada solicitação feita.

Para impedir isso, você também pode limitar as APIs com base no usuário. Você pode configurar quantas solicitações podem ser feitas por um usuário específico para um terminal da API. Para validação OTP, um bom número é de 5 solicitações por 10 minutos. Isso impedirá que o usuário mal-intencionado execute um ataque DDOS de força bruta na API acima.

Limitação no REST Framework do Django –

https://www.django-rest-framework.org/api-guide/throttling/

Estabelecer e configurar comunicação assíncrona desde o primeiro dia

Cenário – Você precisa enviar um email de boas-vindas ao usuário quando ele se registrar no seu aplicativo. O cliente front-end acessa a API Register, você cria o usuário no back-end após as validações e isso inicia o processo de envio de um email de boas-vindas.

O envio desse email de boas-vindas levará tempo, talvez alguns segundos. Mas por que você deseja que o cliente móvel fique preso a esse processo? Isso pode ocorrer em segundo plano sem que o usuário fique preso por nenhum motivo específico na página de registro. Cada segundo é precioso e você não quer que o usuário perca esses segundos preciosos.

Portanto, basta enviar o email por meio de uma tarefa assíncrona. Use trabalhadores, tarefas, intermediários de mensagens e resultados finais para fazer isso.

Um bom exemplo disso no mundo Python é o trabalhador do aipo. Basta colocar a tarefa que precisa ser executada em um intermediário de mensagens (Rabbit MQ / SQS, etc). O aipo ouvirá isso e enviará a tarefa ao trabalhador designado. Esse trabalhador processará a solicitação e colocará o resultado em um backend de resultado, que pode ser um sistema de cache / sistema de banco de dados. (Redis / PostgreSQL por exemplo).

Você pode monitorar essas tarefas e filas com várias bibliotecas de terceiros. Um bom exemplo disso é a Flor de Aipo, que monitora tudo isso.

Screenshot 2020 04 20 at 5.57.47 PM

Você pode ler mais sobre o RabbitMQ aqui – https://www.rabbitmq.com/

E Aipo – https://docs.celeryproject.org/en/stable/django/first-steps-with-django.html

E, finalmente, Flor de Aipo – https://flower.readthedocs.io/en/latest/

Configurar tarefas cron

Cenário – Você acabou de lançar seu produto e precisa enviar recomendações aos usuários sobre novos produtos em sua plataforma. Você os enviará com base no histórico de compras deles todo fim de semana.

A tarefa acima pode ser facilmente executada usando uma tarefa cron. É facilmente configurável em qualquer estrutura. O importante é ter em mente que você não deve colocar os trabalhos cron diretamente no arquivo crontab do seu servidor. Você deve deixar a estrutura lidar com isso.

Isso ocorre porque o engenheiro de implantação / engenheiro do Devops deve ser a única pessoa a ter acesso ao sistema como esse por razões de segurança. Embora você não precise implementá-lo dessa maneira, é bom ter algo desde o início.

No mundo do Django, você pode usar o aipo para configurar seus crons usando trabalhadores do aipo.

Saiba mais sobre o Aipo Beat aqui –https://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html

Gerencie seus segredos corretamente (arquivo de parâmetros)

Existem várias maneiras de gerenciar segredos de parâmetros em seus servidores de produção. Alguns deles são:

  • Criando um arquivo de segredos e armazenando-o em um bucket s3 privado e puxando o mesmo durante a implantação do seu aplicativo.
  • Configurando os parâmetros nas variáveis ​​de ambiente durante a implantação do seu aplicativo (armazenando-os no s3 novamente)
  • Colocar os segredos em algum serviço de gerenciamento secreto (por exemplo, https://aws.amazon.com/secrets-manager/) e usá-los para obter os segredos do seu aplicativo.

Você pode escolher qualquer um desses métodos de acordo com seu conforto e caso de uso. (Você pode optar por manter diferentes arquivos secretos para ambientes locais, de preparo e produção.)

Versão de suas APIs desde o primeiro dia

Isso é algo que você definitivamente deve considerar a partir do dia 1. Você nunca saberá com que frequência seus modelos de negócios podem mudar e precisa ter compatibilidade com versões anteriores em seu aplicativo. Portanto, você deve versionar suas APIs para garantir que tudo corra bem para todos.

Você pode ter aplicativos diferentes para versões diferentes e deixar o nginx lidar com isso no seu aplicativo. Ou você pode ter o controle de versão no próprio aplicativo e deixar que as rotas no servidor de aplicativos o tratem. Você pode escolher qualquer método para implementá-lo – o ponto principal é ter o controle de versão ativado desde o início.

Screenshot 2020 04 20 at 7.07.08 PM

Decida sobre as verificações de atualização de hardware e software para seus clientes front-end

Então, qual é a diferença entre atualizações de hardware e software?

Atualizações completas referem-se a quando o usuário é forçado a atualizar a versão do cliente para um número de versão superior ao instalado no celular.

Atualizações suaves consulte quando o usuário recebe um aviso de que uma nova versão está disponível e pode atualizar seu aplicativo para a nova versão, se desejar.

As atualizações rígidas não são incentivadas, mas há momentos em que você precisa aplicá-las. Seja qual for o caso, você definitivamente deve considerar como implementará isso para seus aplicativos.

Você pode fazer isso implementando ou configurando-o na Play Store ou na App Store. Outra maneira é criar uma API no seu aplicativo de back-end que será atingida toda vez que o aplicativo móvel for iniciado. Isso enviará duas chaves: hard_update -> true / false e soft_update -> true / false, dependendo da versão do usuário e das versões de atualização rígidas e flexíveis definidas em seu sistema de back-end.

Um bom local para armazenar essas versões está no seu cache (Redis / Memcache), que você pode alterar em tempo real sem precisar implantar seu aplicativo.

Introduzir integração contínua (CI) desde o primeiro dia

Cenário – um dos estagiários que trabalha no seu projeto não é proficiente o suficiente para escrever código de nível de produção. Eles podem ter mudado algo que pode quebrar algum componente crítico em seu projeto. Como você pode garantir que tudo esteja bem nesses casos?

Introduzir integração contínua. Ele executará linters e casos de teste em cada confirmação e quebrará se alguma regra for violada. Isso, por sua vez, impedirá que a solicitação pull seja mesclada até que todas as regras de conexão e casos de teste sejam aprovados. É bom ter uma coisa, e na verdade também ajuda a longo prazo, portanto, lembre-se disso.

Existem muitas opções disponíveis no mercado. Você pode optar por implementar um por conta própria (Jenkins CI / CD) ou pode usar TravisCI, CircleCI, etc. para o mesmo.

Leia aqui o TravisCI – https://travis-ci.org/

E CircleCI – https://circleci.com/

Ativar suporte ao Docker (preferência pessoal)

Crie um Dockerfile e um docker-compose.yml para o seu aplicativo, para que todos executem o aplicativo usando o Docker desde o início. Um dos principais motivos para usar essa abordagem é ter consistência em seu ambiente local / de preparação / produção, para que nenhum desenvolvedor possa dizer isso novamente:

Mas funcionou na minha máquina.

Não é difícil empregá-lo desde o primeiro dia. No começo, basta usar o Docker no seu ambiente local para que a configuração do seu aplicativo possa ser realmente tranquila. Mas lembre-se de como você pode executá-lo com e sem o Docker em produção.

Veja mais informações sobre o Docker Hub – https://hub.docker.com/

Uma Ferramenta de Monitoramento de Aplicativos é essencial se você deseja monitorar as APIs, transações, conexões com o banco de dados do aplicativo e assim por diante.

Cenário – o disco rígido do servidor cron está quase cheio e não é capaz de executar trabalhos cron. Como não consegue encontrar espaço no disco, seus crons não estão funcionando. Então, como você pode ser notificado quando isso acontece?

Existem muitas ferramentas de APM que você pode usar para monitorar isso. Você pode configurá-los de acordo com quando você precisa ser notificado. Você receberá notificações no meio de sua escolha quando esse caos acontecer no seu sistema – e confie em mim, isso acontece o tempo todo. Então é melhor estar preparado para isso. New Relic é uma boa opção.

Leia mais sobre a New Relic aqui – https://newrelic.com/

Use o ElasticSearch para impulsionar pesquisas em todo o aplicativo nos aplicativos clientes

De acordo com a wikipedia,

O Elasticsearch é um mecanismo de pesquisa baseado na biblioteca Lucene. Ele fornece um mecanismo de pesquisa de texto completo distribuído e com capacidade para vários operadores, com uma interface da Web HTTP e documentos JSON sem esquema. O Elasticsearch é desenvolvido em Java.

No começo, você ficará tentado a usar consultas tradicionais de banco de dados para obter resultados nessa barra de pesquisa para o aplicativo cliente. Por quê? Porque é fácil.

Mas os bancos de dados tradicionais não se destinam a essas consultas de alto desempenho. Descubra um bom momento para migrar sua pesquisa para o ElasticSearch e introduzir um pipeline de dados em seu sistema. Alimenta a pesquisa elástica com dados e, em seguida, conecta a pesquisa do ElasticSearch ao servidor de aplicativos.

Aqui está uma boa visão geral do Elasticsearch para você começar.

E os ElasticSearch Docs – https://www.elastic.co/guide/index.html

Coloque um firewall no seu servidor de produção

Você definitivamente deveria fazer isso – é um must-have. Coloque um firewall no servidor de produção e feche todas as portas, exceto as que serão usadas nas APIs (conexões https). Roteie os pontos de extremidade da API usando um servidor Web proxy reverso, como NGiNX ou Apache. Nenhuma porta deve estar acessível para o mundo externo além daqueles permitidos pelo NGiNX.

Por que você deve usar o NGiNX:

Empacotando

Os pontos acima mencionados são baseados em minhas próprias preferências e eu os desenvolvi ao longo dos anos. Haverá pequenas diferenças aqui e ali, mas os conceitos permanecem os mesmos.

E, no final, fazemos tudo isso para ter um sistema suave construído do zero, executando a produção o mais rápido possível depois que você tiver a ideia.

Tentei anotar todo o meu conhecimento que adquiri ao longo dos anos e eu devo estar errado em um alguns lugares. EuSe você acha que pode oferecer melhores informações, Por favor, fique à vontade para comentar. E, como sempre, compartilhe se você acha que isso é útil.