Use aplicações do mundo real | Chris Frewin | Skillshare

Velocidade de reprodução


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Use aplicações do mundo real

teacher avatar Chris Frewin, Full Stack Software Engineer

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Aulas neste curso

    • 1.

      Introdução

      0:52

    • 2.

      Por que ir

      5:15

    • 3.

      API de alergia

      2:27

    • 4.

      Requisitos de aplicação

      1:29

    • 5.

      Instale o Go e a extensão do Visual Studio Go

      1:13

    • 6.

      Como estruturar o projeto

      1:47

    • 7.

      Como criar o trabalho Cron

      6:07

    • 8.

      Como criar uma função de utilitário HTTP genérica

      8:57

    • 9.

      Como chamar e analisar a API de alergia

      15:39

    • 10.

      Como criar um aplicativo do Slack e uma função de mensagens

      6:07

    • 11.

      Concluindo o trabalho Cron

      3:15

    • 12.

      Executando o aplicativo

      2:13

    • 13.

      Testes de escrita

      7:48

    • 14.

      Dockerize o aplicativo

      4:58

    • 15.

      Como reiniciar o recipiente com tempo de inatividade mínimo

      2:19

    • 16.

      Adicionando formatação sofisticada às mensagens do Slack

      6:25

    • 17.

      Movendo segredos e valores codificados para um arquivo ENV

      8:11

    • 18.

      Criando um pipeline de CI CD com Circle CI

      24:28

    • 19.

      Conclusão

      0:41

  • --
  • Nível iniciante
  • Nível intermediário
  • Nível avançado
  • Todos os níveis

Gerado pela comunidade

O nível é determinado pela opinião da maioria dos estudantes que avaliaram este curso. Mostramos a recomendação do professor até que sejam coletadas as respostas de pelo menos 5 estudantes.

17

Estudantes

--

Sobre este curso

Mergulhe no poderoso mundo do Go (Golang) e aprenda a criar, testar e implantar aplicativos do mundo real do zero. Quer você esteja começando a usar o Go ou queira aplicar suas habilidades em projetos práticos, este curso vai equipar você com um fluxo de trabalho essencial e moderno.

Junte-se a mim neste curso prático onde vamos explorar por que o Go é um recurso incrível para qualquer desenvolvedor. Aproveitaremos seu desempenho, recursos de teste integrados e manipulação simples de JSON para criar um aplicativo funcional.

Neste curso, você vai aprender a:

  • Organize um projeto inicial: comece do zero, configurando uma nova estrutura de projeto corretamente.

  • Escreva código Go funcional: desenvolva a lógica principal para um aplicativo prático e orientado por API.

  • Implemente testes de unidade: use o pacote de testes integrado do Go para garantir que seu código seja confiável e robusto.

  • Container com o Docker: compacte seu aplicativo Go em um container Docker leve e portátil.

  • Automatize seu fluxo de trabalho: configure um pipeline completo de CI/CD (integração contínua/implantação contínua) com o CircleCI para testar e construir seu projeto automaticamente.

Ao final deste curso, você terá uma compreensão abrangente e prática de todo o ciclo de vida de desenvolvimento de um aplicativo Go moderno, de uma única linha de código a um pipeline de implantação totalmente automatizado.

Conheça seu professor

Teacher Profile Image

Chris Frewin

Full Stack Software Engineer

Professor

Hi everyone!

I've been a professional full stack software engineer for 7+ years, and I've been programming for many more. In 2014, I earned two separate degrees from Clarkson University: Mechanical Engineering and Physics. I continued at Cornell for my M.S. Degree in Mechanical Engineering. My thesis at Cornell was a technical software project where I first learned Bash and used a unique stack of Perl and Fortran, producing a publication in the scientific journal Combustion and Flame: "A novel atom tracking algorithm for the analysis of complex chemical kinetic networks".

After opening up my first terminal while at Cornell, I fell in love with software engineering and have since learned a variety of frameworks, databases, languages, and design patterns, including TypeScrip... Visualizar o perfil completo

Level: Intermediate

Nota do curso

As expectativas foram atingidas?
    Superou!
  • 0%
  • Sim
  • 0%
  • Um pouco
  • 0%
  • Não
  • 0%

Por que fazer parte da Skillshare?

Faça cursos premiados Skillshare Original

Cada curso possui aulas curtas e projetos práticos

Sua assinatura apoia os professores da Skillshare

Aprenda em qualquer lugar

Faça cursos em qualquer lugar com o aplicativo da Skillshare. Assista no avião, no metrô ou em qualquer lugar que funcione melhor para você, por streaming ou download.

Transcrições

1. Introdução: Go é uma linguagem de back-end incrivelmente poderosa que pode ser uma vantagem para o kit de ferramentas de qualquer desenvolvedor É de alto desempenho. Ele tem serialização e desserialização integradas JSON, ele tem testes integrados e muito mais. Neste curso, vamos começar completamente do zero, criando uma nova pasta, estruturando um projeto G, escrevendo todo o código para ele, escrevendo testes para o Dockerizando o aplicativo e, finalmente, automatizando um pipeline CICD de fluxo de trabalho de teste e criação com o CircleCI Ao final do curso, espero que você tenha uma visão geral prática de como criar aplicativos go dockerizados, incluindo testes Espero que você se junte a mim neste curso, Go for real world applications. 2. Por que ir: Antes mesmo de começarmos a falar sobre o que nosso aplicativo fará ou qualquer programação, quero explicar rapidamente por que escolhemos G como opção de linguagem em primeiro lugar. Então, por que escolheríamos G? Em primeiro lugar, é extremamente eficiente. Até agora, escrevi pelo menos uma dúzia de aplicativos de go e nunca precisei identificar qualquer tipo de condição de corrida ou problema de desempenho. E uma delas era uma API para uma startup relativamente grande. Tínhamos cerca de 10.000 usuários e, em alguns momentos, 1.000 a 2.000 usuários simultâneos E mesmo assim, nunca tivemos grandes problemas de desempenho, e isso estava sendo executado em uma máquina virtual de quatro núcleos. O Go também é extremamente compacto. Portanto, o aplicativo normalmente é executado a partir de um único arquivo dot go principal, e isso pode ser feito simplesmente emitindo go run main dot go Como veremos mais adiante no curso, isso é extremamente poderoso para quando queremos dockerizar nosso aplicativo É muito simples transportar e executar um aplicativo go. O Go também é extremamente testável. Ele tem uma estrutura de teste incorporada. Então, importaríamos esse pacote de teste. Passamos isso para nossa função de teste. E então é tão simples quanto chamar a função que queremos testar. E nesse caso, retornei um erro dessa função. Se o erro não for Nulo, isso é válido para não nulo ou vazio Em seguida, usamos esse ponteiro para a estrutura de teste e emitimos um erro. Então, isso está embutido. Não precisamos de nenhuma configuração externa. Não precisamos de bibliotecas externas. Ele é incorporado ao idioma. O Go também é extremamente compatível com a API. Então, eu tenho um exemplo aqui para mostrar como isso funciona em Go. Então, se assumirmos que temos algum tipo de resposta JSON de uma API como essa, podemos usar o pacote JSON e também o identificador JSON quando definimos um tipo aqui, chamá-lo de API, é uma estrutura E sabemos que nossa resposta tem algum tipo int e alguma matriz de string. É uma matriz de strings. Usamos esse identificador JSON. Agora, a mágica acontece quando usamos esses identificadores e usamos o pacote JSON incorporado, vamos supor que já temos a resposta da API, algum tipo de resultado binário Podemos simplesmente chamar JSON Unmarshal e Golang serializará esse resultado binário serializará esse resultado binário em nosso objeto de resposta. E quando ele vê essas chaves, ele sabe colocar esses valores em cada uma dessas partes dessa estrutura. Então, assumimos que não havia nenhum erro, organizando a resposta. Se desconectássemos algum int, obteríamos cinco e, se fizéssemos um loop na desconectássemos algum int, obteríamos cinco e, obteríamos cinco e matriz de strings, obteríamos esses A, B e C. Então, novamente, não precisamos de nenhum arquivo de configuração , de nenhuma biblioteca externa Nós apenas usamos a biblioteca JSON integrada com o método Unmarshal, e Golang lida com toda a serialização e desserialização do e desserialização Ir também é extremamente uniforme. Então, quando você estiver escrevendo com um editor de código moderno, como o Visual Studio Code, use os formatos ao salvar de acordo com suas próprias regras incorporadas. E isso significa que não importa onde você esteja lendo o código G, seja um pacote externo, um pacote de terceiros código de seus colegas de equipe, você sempre verá os mesmos padrões, recuo e espaçamento em Isso facilita muito a leitura de outros projetos go. Isso também evita que você e sua equipe debatam sobre regras de formatação como guias, espaços e todas Essas regras também são incorporadas à linguagem go. Então, em resumo, G é muito eficiente. É muito rápido, pelo menos em toda a experiência que usei, é muito compacto. Você só precisa do seu único arquivo dot go principal. É facilmente testável. O teste vem com a própria linguagem. É muito compatível com a API. Essa serialização e desserialização de JSON também vem pronta para uso com a linguagem e é uniforme Essas regras de linting e formatação também vêm com o idioma Portanto, o G é uma escolha muito sólida para qualquer software de back-end que você precise criar Então, com um histórico básico do que é G e de algumas de suas vantagens, na próxima lição, podemos começar a analisar o aplicativo real que criaremos e, finalmente, começar a codificar o aplicativo 3. API de alergia: Neste curso, vamos criar um aplicativo que nos envia mensagens e nos avisa diariamente sobre os níveis esperados de pólen no Se você é como eu, pode sofrer de febre do feno de meados de maio a meados de junho de cada ano, pelo menos no hemisfério norte. E não se preocupe. Mesmo que você não tenha nenhuma alergia, prometo que o conteúdo e os padrões deste curso são extremamente úteis, independentemente do tipo de aplicativo go que você esteja usando Então, onde eu moro na Áustria, a Universidade de Medicina de Viena tem um ótimo site que prevê os níveis de pólen do dia E com algumas pesquisas e inspeções das chamadas de API para este site, encontrei os endpoints que produzem todos os dados Existem basicamente dois endpoints que usaremos. A primeira é obter dados de carga por hora, que têm uma chave de sucesso e o resultado. Mais importante ainda, aqui está essa matriz horária. Então, para cada hora, ele fornecerá um valor esperado do pólen no ar, variando de zero a, acredito, oito ou nove O segundo ponto final que utilizaremos neste curso é obter os dados atuais do gráfico Este será usado para médias históricas. Então, como você pode ver aqui, também temos uma chave de sucesso. Temos alguns resultados. E para cada resultado, temos uma data, a atual ou, neste caso, o que realmente aconteceu nessa data este ano e, em seguida, a média histórica. No entanto, agora é 16 de maio e, como você pode ver, a corrente é zero e, mesmo ontem, a corrente é zero. Portanto, esses dados estão um pouco atrasados. No entanto, como mencionei, vamos usá-lo principalmente para os valores médios. Então, enviaremos o valor esperado para o dia a partir desses dados horários e também a média histórica do dia. Então, com uma visão geral e uma ideia do que nosso aplicativo será na próxima lição, discutiremos brevemente os requisitos técnicos que queremos que nosso aplicativo atenda e, em seguida, poderemos finalmente começar a escrever alguns códigos. 4. Requisitos de aplicação: Na última lição, analisamos a API de alergia que usaríamos e de onde vinham esses dados. E nesta lição, discutiremos brevemente requisitos do aplicativo em um nível mais técnico antes de começarmos a codificar. Portanto, do ponto de vista do fluxo de aplicativos, em um horário diário específico, queremos chamar esses endpoints de alergia Vamos analisar a resposta JSON cada chamada e, em seguida, fazer algum trabalho de formatação para transformá-la em uma boa mensagem legível por humanos Então, finalmente, queremos enviar essa boa mensagem por meio dos webhooks do Slack Todas as funções que escrevemos devem ter testes. O aplicativo deve ser executado a partir de um contêiner docker. O contêiner docker deve ser reiniciado em caso de qualquer tipo de falha ou falha Deve ser construído um pipeline automatizado que execute todos os testes que escrevemos e , em seguida, publique o contêiner do Docker , caso todos esses testes sejam realmente E, finalmente, os vários valores importantes usados no aplicativo, como os endpoints da API, o URL do web hook do Slack, o horário do Cron Job e o fuso horário do Crown job, Cron Job e o fuso horário do Crown job devem ser todos Portanto, ao longo deste curso, abordaremos e atenderemos passo a passo todos esses requisitos. Na próxima lição, finalmente começaremos a montar nosso aplicativo go 5. Instale o Go e a extensão do Visual Studio Go: Comece, todos devemos verificar se temos o G instalado. Para verificar se tenho o G instalado, simplesmente lançarei a versão G. E eu posso ver que tenho G 1.20 0.2. Se esse comando não retornar nada ou um erro, provavelmente você precisará instalar o G no seu sistema. Você pode acessar go dot dev slash dClash Install, e eles têm as instruções de instalação para Linux, Mac No restante deste curso, presumo que você esteja programando junto comigo no Visual Studio Code comigo no Visual Studio Portanto, eu também recomendo que você tenha a extensão G instalada. Para encontrar a extensão G, vá até a guia de extensões e pesquise por G. Deve ser o primeiro resultado e, claro, eu já a tenho instalada. Essa extensão é um balcão único para tudo o que você precisa para editar o código G. É uma combinação de inter, testador, depurador e formato para G. Depois de instalar essa extensão, podemos começar 6. Como estruturar o projeto: Na última lição, nos certificamos de que tínhamos o G instalado e também instalamos a extensão do Visual Studio Code G. Agora vamos montar nosso aplicativo. Normalmente, ao iniciar um novo projeto G, você cria uma nova pasta para esse aplicativo. Nesse caso, eu o chamaria de Allergy Cron e você emitiria make DR Allergy cron No entanto, como já estou no repositório do curso, tenho uma pasta aqui para o projeto e não vou criar uma nova pasta A próxima etapa seria então inicializar um módulo para o projeto Normalmente, uso o mesmo nome do próprio nome da pasta. No seu caso, isso seria alergia. Então, aqui, vamos inicializá-lo de acordo com o nome da pasta O comando para inicializar um módulo G é Gomd init e, em nosso caso, Allergy Crown Go nos dirá que criou um novo arquivo mod go dot. Podemos entrar nesse arquivo gomd e ver o que está nele. Por enquanto, como não instalamos nenhum pacote adicional, ele tem apenas o nome do módulo e a versão go que foi usada para criá-lo. Em seguida, podemos criar o arquivo principal, ou seja, toque em main dot go. E se você ainda estivesse em apenas um ambiente de terminal, você não tinha um editor aberto. Você poderia, é claro, abrir o ponto principal com o comando Abrir. Ou se você quiser abri-lo no código do Visual Studio, você pode emitir o código main dot go. Então, depois de toda essa configuração, finalmente estamos prontos para começar a escrever algum código G. 7. Como criar o trabalho Cron: Na última lição, estruturamos nosso novo projeto G, inicializando um módulo G, inicializando um módulo G que nos deixou com esse arquivo go dot mod, e criamos um arquivo dot go principal vazio Nesta lição, começaremos a abordar o primeiro requisito técnico, que é ter um cron job diário que seja acionado exatamente ao mesmo tempo Cada arquivo go tem uma declaração de pacote na parte superior. Nesse caso, esse é o pacote Min. Então você pode ter algumas importações aqui. E no caso do arquivo dot go principal, teremos nossa função principal, que é simplesmente a função main. Agora, para trabalhos em Crown e G, gosto de usar a popular biblioteca Rob Fig Cron. Essa biblioteca também nos permite definir o Cron Job de acordo com um fuso horário específico Então, primeiro, vou usar o pacote de horário do Go para carregar o fuso horário e, em seguida, podemos configurar o Crown Job nesse fuso horário. Então, obtemos uma localização e um erro e, a partir do momento, a localização do carregamento. E como estou na Áustria, quero a Europa, Viena. Então, é claro, precisamos verificar se o erro não é Nil, então entraremos em pânico com esse erro e, caso contrário, podemos continuar Agora, para configurar um Crown Job com esse pacote, tudo o que precisamos fazer é ligar para um novo com a localização e passaremos por essa localização. Agora, vemos com o inter, assim que eu faço referência a esse cron, o inter sabe qual pacote eu quero usar O único problema aqui é que esse pacote ainda não está em nosso arquivo mod. Então, se passarmos o mouse sobre a importação aqui, Go reclama que não há nenhum módulo fornecendo esse pacote Mas, felizmente, o Linter nos fornece uma solução rápida, que é simplesmente a instalação ou o comando go get package Então, se clicarmos para que o pacote esteja instalado. Você deve ver seu arquivo mod obtido modificado e, em seguida, podemos continuar com nosso código aqui. Para não ultrapassar o tempo real do Cron, precisamos adicionar o ponto Cron Job ao Funk e isso usa o identificador cron padrão do tipo unix precisamos adicionar o ponto Cron Job ao Funk e isso usa o identificador cron padrão do tipo unix com seis caracteres. E esses são especificamente os segundos, os minutos, as horas, o dia do mês, o mês em si e o dia da semana. No nosso caso, acho que um horário razoável, pelo menos para mim, é às 8:00 da manhã todas as manhãs. Então, vou especificar zero para os segundos e minutos e, em seguida, oito para a hora. E então o segundo parâmetro desse ad funk é a função que realmente queremos executar E, por enquanto, vou colocar uma função vazia lá. Eu posso limpar esse comentário de importação e podemos salvar nosso arquivo. Outra coisa que quero destacar aqui é a capacidade de formatação automática das extensões Go do Visual Studio. Então, se tivermos algum espaçamento desleixado aqui ou algo parecido, assim que salvamos, no meu caso, em um Mac Command S, vemos que o inter formata automaticamente Também devo mencionar que, para esses fusos horários, eles são consultados em algo chamado banco de dados de fusos horários da Iana. Encontrei um bom site chamado Nota time, que lista todos os vários fusos horários. Então, onde quer que você esteja no mundo, fique à vontade para examinar esta tabela e definir o fuso horário de acordo com onde quer que esteja ou sempre que quiser que seu Cron Job seja acionado Também precisamos garantir que nosso cron job seja iniciado. Então, adicionamos a função, mas precisamos chamar explicitamente cronjob E então, se deixássemos isso, quando executássemos a função principal, ela simplesmente seria executada aqui e depois sairia. Portanto, precisamos bloquear o encadeamento principal para manter o processo go em execução, para que possamos manter esse cron job ativo depois de iniciá-lo, e o cron continuará sendo executado até cada dia, quando atingir o horário das 8h. Nesta lição, começamos a escrever nosso arquivo dot go principal. Aprendemos que todo arquivo go começa com uma declaração de pacote. Então, geralmente há algumas importações e, em seguida, suas funções. Nesse caso, é um caso um pouco especial. O arquivo dot go principal sempre tem uma função principal. E começamos a escrever o corpo da nossa função principal. Carregamos o fuso horário de Viena e usamos esse fuso horário de localização em nosso cron job, e configuramos o Cron job para ser acionado às 8:00 da manhã todos Vimos um bom recurso de como o formato de código do Visual Studio pode corrigir e formatar automaticamente o recuo em nosso E também discutimos todas as várias possibilidades que você pode passar para essa função de localização de carga para que você possa definir o fuso horário desejado. Na próxima lição, abordaremos a criação de uma função utilitária HTTP, para que possamos começar a ver como chamaremos os URLs da API que eventualmente adicionaremos ao URLs da API que eventualmente adicionaremos corpo da função aqui do nosso trabalho na Crown 8. Como criar uma função de utilitário HTTP genérica: Na última lição, começamos a montar nosso arquivo dot go principal e a configurar o cron job que poderia iniciar nossas várias tarefas às 8h no fuso nosso arquivo dot go principal e a configurar o cron job que poderia horário de Viena. horário de Viena. Agora vamos escrever uma função HTP genérica que será usada tanto para as chamadas da API de alergia quanto para enviar nossa mensagem do Slack Agora, essa função é bastante complexa e faz uso das funcionalidades genéricas de G. Não vou entrar em muitos detalhes sobre como a função foi construída. Tenho uma postagem separada no blog que detalha sua implementação, e você é mais do que bem-vindo a ler sobre isso separadamente. Para começar com essa função, criaremos uma nova pasta chamada Utils e um novo arquivo chamado make http request dot go O pacote aqui será Utils. E para nossa função, faça uma solicitação de HDP. Isso exige um tipo genérico. Em seguida, passaremos a URL completa, que é uma string, o método HTTP esperamos, que também é uma string. Qualquer cabeçalho que a chamada precise, que é um mapa de string e string Os parâmetros de consulta, que são do tipo RL, o corpo, que é leitor de E/S, e a resposta do tipo T, e retornaremos esse tipo ou um erro A primeira coisa que faremos nessa função é inicializar nosso cliente HTTP E converteremos o URL da string um objeto URL completo com Rl dot pars com esse URL completo Se o erro não for NIL, retornaremos apenas nosso tipo de resposta e o erro Se o método for G, precisamos acrescentar qualquer dos parâmetros de consulta que foram passados Então, primeiro, obterei a consulta do objeto URL e precisamos percorrer esses pares de valores-chave dentro dos parâmetros da consulta. E definiremos a chave e o valor. Para cada parâmetro. Em seguida, definiremos a consulta bruta como a consulta construída codificada idiota que criamos aqui Também podemos definir o corpo fazendo uma nova solicitação, passando o método, a versão da string da URL e o corpo. Se o erro não for nulo, novamente, retornaremos o tipo de resposta e o erro E agora que temos nossa solicitação, precisamos definir os cabeçalhos. Quanto à chave e ao valor desses cabeçalhos, definiremos o valor do cabeçalho E, finalmente, podemos fazer sua solicitação real, literalmente com a função dot do do cliente. Novamente, se o erro não for NIL, retornaremos esse tipo de resposta e o erro Também verificaremos se a resposta em si é NIL. Retornaremos o tipo de resposta e um erro informando que chamar a URL retornou uma resposta vazia e queremos passar essa versão de string do objeto URL Caso contrário, se continuarmos aqui, queremos ler o corpo. E, novamente, se o erro não for nulo, retorne esse erro do tipo de resposta adie o fechamento desse corpo E também queremos verificar se o código de status não é o código de status o. Tipo de resposta, e também cometeremos um erro personalizado aqui. Formatação semelhante aqui. Você pode inserir uma nova linha com o código de status, outra nova linha com os dados reais da resposta. E então queremos inserir a string do URL, o código de status real e os dados da resposta. Agora, se chegamos até aqui, podemos finalmente desagrupar os dados de resposta no objeto de resposta, que é o tipo T que esperamos. Então, declararemos o objeto de resposta e tentaremos desagrupar os dados de resposta no objeto de resposta Se o erro não for novo, altere o tipo de resposta e o erro em si. Por fim, podemos retornar com segurança o objeto de resposta completa com um erro NL. Agora, quando eu salvo aqui, a extensão do Visual Studio Go importará automaticamente todas as bibliotecas que usamos. Então IO, a biblioteca HDP, a biblioteca de URL, strings e assim por diante Então, com um pouco de esforço, temos uma função genérica muito poderosa, e eu gosto de usar essa função para praticamente qualquer chamada HTTP REST padrão que eu precise fazer. Como vimos, ele foi implementado para funcionar com get put, post e todos os tipos de verbos HTTP Então, com essa poderosa função agora implementada, na próxima lição, vamos realmente chamar a API de alergia. Também definiremos os tipos que passarão como esse tipo genérico. Portanto, sabemos que a resposta do JCN será serializada corretamente e, em seguida, poderemos consumi-la mais abaixo em nosso código G. 9. Como chamar e analisar a API de alergia: Na última lição, criamos essa função genérica de solicitação de HDP bastante poderosa e, agora, nesta lição, vamos usá-la chamando a API de alergia da Universidade de Medicina de Viena Então, para começar, criaremos uma nova pasta. Chamado Allergy API e um novo arquivo go Allergy underscore api dot go E esse pacote é igual ao nome da pasta e do arquivo, Allergy underscore API Agora, a primeira coisa que precisamos fazer é definir os tipos que passaremos para nossa função genérica aqui para que o JSON aqui, quando for desempacotado, saiba em que tipo deve ser desagrupado E analisando essas duas chamadas de API separadas, temos nossos dados de carga horária, que têm uma espécie de estrutura abrangente com as chaves de sucesso e resultado, e, dentro do resultado, temos outro objeto, que tem um total, algum tipo de opção personalizada e, o mais importante para nós, a matriz horária, que é uma matriz de Para obter os dados atuais do gráfico, também temos uma estrutura semelhante. Temos um objeto grande que tem as chaves de sucesso e resultado. Mas os resultados aqui são diretamente uma matriz com um objeto repetido que tem data atual, temporada média e data e hora E mais uma vez, o mais importante para nós aqui é a média. Vamos usar esse endpoint para a parte média histórica da mensagem que enviamos Então, vamos começar com os tipos de dados de carregamento por hora. Então, primeiro, vou definir a resposta, e isso tem uma chave de sucesso e resultado aqui. Então, vou definir isso como resposta de carga por hora. Este é um Strup e temos nosso sucesso, que é um int, e o identificador JSON aqui é um sucesso em minúsculas E o resultado, que precisamos para definir um novo tipo, uma nova estrutura para esse tipo aninhado, vou chamá-lo de resultado de carga horária E também precisamos definir a chave JSON que é o resultado em minúsculas Agora, como esse tipo usa essa outra estrutura, normalmente gosto de colocar o tipo acima aqui E o que temos? o total e o total por hora é um int. total em minúsculas e por hora do JSON é uma fatia dos pontos, e o E quando eu salvo aqui novamente, os Linters formatam tudo bem e arrumado em colunas Agora podemos passar para os dados do gráfico. Da mesma forma, temos a resposta de dados do gráfico. E vamos dar uma olhada nisso. Além disso, chaves de sucesso e resultado. Portanto, o sucesso é uma aposta. E o resultado ou, devo dizer, resultados no plural está em matriz, e esse tipo precisará ser outro tipo personalizado, que chamarei de resultado atual dos dados do gráfico E também precisamos especificar a chave JSON. Vou pegar isso e definir o tipo aqui. E tudo o que realmente precisamos é a data, que por enquanto será uma string, e a média, que é uma flutuação Portanto, temos a data e a média posso salvar isso, e isso deve ser tudo o que precisamos para digitações personalizadas Agora, escreveremos uma função separada para cada endpoint da API O primeiro, podemos chamar de get hour load data. E a segunda, chamaremos get current chart data. Agora, para ambos, esperamos que eles retornem um ponteiro de string e um erro E essa sequência será , em última análise, a mensagem que será transmitida ao nosso slack messenger E sabemos que o objetivo aqui é chamar nossa função genérica aqui. Então, teremos uma resposta e um erro de can import this Utils package que acabamos de criar na lição anterior e na requisição make HTTP Agora, não precisamos especificar o tipo explicitamente. Golan vai inferir isso para nós. E para o URL, nós o temos aqui. Esse é o ponto índice PhP. Nós podemos colocar isso. Sabemos que será uma solicitação de obtenção. Não precisamos passar nenhum cabeçalho. Precisaremos passar alguns parâmetros de consulta. Não há nenhum corpo que precisemos passar e o tipo de resposta é a resposta de carregamento por hora. E se o erro não for NL, retornaremos uma string Nil e o erro, por enquanto, vamos passar para esses parâmetros de consulta Esse tipo são os valores de URL. E podemos adicionar todos os parâmetros de que precisamos. Portanto, há muitos aqui para isso de hora em hora. Temos um EID, um tipo de ação pode fornecer um país postal e assim por diante Então, forneceremos todos esses parâmetros de consulta. Portanto, temos certeza de que nossa solicitação Get funciona exatamente como funciona no navegador. Então, vamos adicionar esse EID O tipo é ZIP O CEP é 6.800. O país é Austria A. T. E também há essa bandeira para o Cure JSON, e essa é uma delas Pode importar esse pacote de URL. E agora vamos prosseguir com a formatação e construção dessa string que queremos retornar Então, a partir dos dados aqui, temos a matriz completa da carga horária esperada. Então, o que faremos é percorrer essa matriz, criar uma média e, em seguida, criar uma string que mencione qual é essa média Então, primeiro definiremos uma carga média. E então vamos fazer um loop no intervalo que sabemos que está dentro da parte horária do resultado. Então, isso é apenas mais igual ao valor da hora, e então a carga média se torna a carga média dividida pela duração de todas as Outra coisa que notei ao examinar a API é que eles estão fazendo algum tipo de normalização dos dados Não é mostrado aqui, mas esses números podem chegar a oito ou nove, mas mostram apenas uma classificação 0 a 4 na interface real do site Então, por enquanto, para simular essa funcionalidade, vamos apenas dividir a média, vamos chamá-la de carga média escalonada, e isso será apenas essa carga média dividida por dois Na mensagem formatada que enviaremos, usaremos o pacote de formato, sprint F, e diremos a carga média de pólen de hoje é a média escalonada e retornaremos essa mensagem formatada sem erros A implementação para obter os dados atuais do gráfico é bastante semelhante. Na verdade, vou copiar tudo isso e, em seguida, poderemos fazer as alterações necessárias. E eu cometi um pequeno erro aqui. Essa é a chave de ação e o EID é, na verdade, a interface do aplicativo Você pode adicionar isso aqui. Agora, aqui, nesse caso, a ação é, como podemos ver aqui na URL , obter os dados atuais do gráfico. A identificação completa, na verdade, é para o tipo de planta. Nesse caso, eu o fiz para minha alergia, que é para gramíneas ou feno Ainda podemos passar o zíper. Só nos preocupamos com os dados da temporada, e essa é a bandeira dos dados da temporada. E também queremos que essa bandeira JCN pura seja ativada. O URL é o mesmo. O método é o mesmo. Ainda passamos, é claro, os parâmetros da consulta e agora só precisamos alterar o tipo de resposta, que é o tipo de resposta atual dos dados do gráfico. Agora, é claro, G reclamará aqui porque a forma da resposta é diferente Então, o que queremos fazer com esse método é repetir todos esses resultados até encontrarmos uma data correspondente e, em seguida, queremos imprimir a média histórica da data atual. Vou definir uma variável chamada YY MMDD atual. Agora é o ponto temporal e, em seguida, precisamos formatá-lo usando o estilo Go de formatação de strings Definiremos um histórico médio que inicializará um zero e, em seguida, examinaremos esses resultados e encontraremos a data correspondente Portanto, se a data do resultado for igual à data atual, sabemos que a média histórica é a média do resultado Da mesma forma, como fizemos acima, devemos criar uma média em escala E vamos fazer uma conversão interna disso, pois queremos apenas de zero a quatro, e vamos apenas arredondar a média histórica encontrada dividida por dois, e então podemos criar nossa mensagem formatada Nesse caso, diremos que, historicamente, a carga média de pólen de hoje é e passaremos essa média em escala Salvamos o inter, importaremos esses pacotes e tudo deve estar pronto Então, nesta lição, começamos a pensar em como podemos chamar esses dois endpoints e desserializar o JSON Começamos examinando a estrutura do JSON e definindo os tipos necessários e as partes necessárias desse JSON que precisamos usar para criar nossas mensagens Em seguida, começamos a escrever as funções reais que chamam o endpoint, usando nossa solicitação make HTP que criamos na lição anterior Depois de obtermos a resposta, fazemos um pouco de cálculo e formatação. E para cada função, finalmente retornamos a string formatada, que poderemos enviar pelo Slack Na próxima lição, pegaremos essa string de retorno e a enviaremos pelo Slack por meio de webhooks 10. Como criar um aplicativo do Slack e uma função de mensagens: Na última lição, definimos alguns tipos e escrevemos duas funções para chamar a API Allergy, fazer alguns cálculos e, finalmente, retornar uma string bem formatada, que dissemos que encaminharíamos para o Slack para que pudéssemos enviar a mensagem Para enviar nossas mensagens pelo Slack, primeiro precisaremos de um aplicativo Slack Em seguida, precisaremos ativar webhooks recebidos para esse aplicativo e, finalmente, teremos uma URL que podemos realmente publicar para enviar a mensagem Em seguida, voltaremos ao código e escreveremos outra função utilitária para enviar qualquer mensagem ao nosso aplicativo Slack Para começar a criar um aplicativo Slack, api dotslaq.com acesse api dotslaq.com e clique em seus aplicativos, e você precisará fazer login para acessar Vou entrar aqui com o Google. E eu quero a conta Full Stack Craft da minha empresa. E podemos simplesmente clicar em Cancelar aqui. Agora que estamos logados , podemos voltar para api dotslag.com voltar para api dotslag.com Em seguida, clique em seus aplicativos. Quando estivermos na página de listagem de aplicativos, clique em Criar novo aplicativo. E queremos criar nosso aplicativo do zero. Vou chamar o meu de Allergy Cron Bot. E, novamente, eu o quero em meu próprio Fullstack Craft Works. Na página resultante, queremos então adicionar webhooks recebidos E só queremos colocar essa chave na posição ligada, e veremos alguns códigos aparecerem Agora, queremos adicionar um novo webhook, então clicaremos aqui e precisaremos escolher um canal para permitir que ele publique Por enquanto, vou escolher Geral e clicar em AAO. Se já tivermos um aplicativo Slack aberto, seja na versão web ou desktop, veremos que a integração foi adicionada Então, aqui, em geral, vejo que adicionei meu bot de coroa de alergia. De volta à interface do usuário da web, você pode ver que o Slack criou uma URL de webhook para nós e, portanto, podemos copiá-la imediatamente Como alternativa, você pode copiar o exemplo deles aqui. Este é um exemplo de olá mundo. E logo no terminal aqui, vou colar este exemplo, deve disparar sem problemas. E se formos para o Slack, realmente veremos aquela mensagem Hello World do nosso novo aplicativo Slack Por enquanto, vamos apenas copiar o URL si e entrar em nosso projeto G. Criaremos uma função utilitária a qual podemos enviar uma mensagem. Então eu vou chamar esse arquivo, enviar uma mensagem para o Slack. Este é o pacote Utils e a função aqui é enviar mensagem para o Slack Apenas aceitaremos uma mensagem, que é uma string, e ela retornará um erro, se houver. Tudo o que precisamos fazer aqui é criar um corpo, usar o pacote JSON e um mapa de string com esse parâmetro de texto, e essa será a mensagem que passaremos para a passaremos para Se o erro não for Nil, retornaremos esse erro Então, podemos usar nossa solicitação make HTP. Essa será a nossa URL. Vamos postar sobre isso. Os cabeçalhos, não precisamos fornecer parâmetros de consulta. Também podemos sair como Nil. Criamos um buffer a partir do nosso corpo e podemos ter apenas uma string vazia como nosso tipo Nós realmente não recebemos nenhuma resposta. Só receberíamos um código 200 quando fosse bem-sucedido. Portanto, não há nada que precisemos analisar. E a partir daqui, podemos devolver Nil. E se eu salvar esse arquivo, o Linter importará o pacote JSON e estaremos prontos Agora, esse URL é tecnicamente secreto, pois se alguém soubesse disso, poderá enviar spam para seu canal do Slack indefinidamente Por enquanto, vamos deixá-lo codificado , mas em uma lição posterior, coletaremos todos esses valores codificados e colocaremos em um arquivo de ambiente Então, para resumir nesta lição, criamos um novo aplicativo Slack e ativamos os webhooks recebidos E depois de selecionar um canal para o qual queríamos enviar uma mensagem, Slack gerou uma URL na qual podemos postar que, por fim, encaminharia a mensagem para esse canal De volta ao nosso código G, escrevemos um UTIL conciso de envio de mensagens do Slack que podemos usar para encaminhar o que analisamos da API de alergia Na próxima lição, combinaremos todas as funções que escrevemos em main dot go e, em seguida, estaremos prontos pela primeira vez para executar nosso aplicativo. 11. Concluindo o trabalho Cron: Na última lição, criamos um aplicativo Slack e essa função de utilitário de envio de mensagens do Slack que pode realmente enviar as mensagens para o Slack que são geradas em nossas funções de API de alergia Nesta lição, finalmente combinaremos todas essas funções que escrevemos em main dot go. Então, dentro dessa função Cron, vou chamar nossos dados de carga horária G e obter os dados atuais do gráfico e atuais do gráfico em seguida, encaminhar essa mensagem combinada para o Slack Então, temos nossa mensagem média diária. E isso vem da API de alergia. Obtenha dados de carregamento por hora. Se o erro não for nulo, entraremos em pânico E também obteremos a média histórica. E da mesma forma, se o ar não estiver nulo, entraremos em pânico. E então a mensagem real do Slack que enviaremos combinará essas duas mensagens e colocaremos um novo caractere de linha entre as duas Com isso combinado, podemos chamar nossa função Enviar mensagem do Slack com essa mensagem do Slack E, novamente, se o erro não for nulo, entraremos em pânico se for Utils Pode importar isso. E, por enquanto, para depuração, vou me desconectar que enviamos a mensagem do Slack com sucesso e adicionaremos a mensagem real do Podemos salvar isso, e devemos estar prontos para partir. Então, como uma rápida revisão desta lição, finalmente voltamos ao nosso arquivo dot go principal e chamamos de Obter dados de carga horária e também de dados do gráfico atual G para ter uma mensagem de média diária e média histórica Nós os combinamos com uma nova linha e, em seguida, chamamos nossa função New Send Slack message, que, em última análise, completa o fluxo funcional completo do nosso Na próxima lição, modificaremos o horário do cron job para ser acionado mais ou menos imediatamente e, em seguida, executaremos nosso aplicativo 12. Executando o aplicativo: Na última lição, concluímos o corpo da função que realmente será acionada em nosso horário cron especificado Agora, como estamos prontos para realmente executar nosso aplicativo, devemos atualizá-lo para a próxima hora e minuto imediatos para que possamos ver rapidamente o cron job sendo acionado e testarmos o corpo real aqui para ver se tudo está funcionando Então, a partir desse tempo de gravação atual, é 1209, então vou aumentar isso para 1210, e então podemos chamar nossa função com go run main dot go E devemos esperar que, assim que o relógio chegar às 1210, essas APIs sejam chamadas e nossa mensagem do Slack seja enviada Então, de fato, vemos apenas um carrapato depois de 1210. Recebemos a seguinte mensagem do Slack que é enviada. A carga média de pólen de hoje é uma e, historicamente, a carga média de pólen de hoje é duas Também podemos ver aqui em nosso aplicativo Slack que realmente recebemos exatamente a mesma mensagem Portanto, nosso aplicativo está funcionando exatamente como esperamos. Até agora, o que criamos neste curso segue os requisitos técnicos que especificamos em termos de fluxo e de como o aplicativo funciona. Ele obtém os dados da API, os converte em uma boa string legível por humanos e envia essa mensagem via No entanto, ainda há muitas otimizações que podemos fazer para tornar esse aplicativo mais corporativo Então, nas próximas aulas, veremos coisas como remover essas sequências de caracteres e colocá-las em um ambiente, bem como coisas que realmente deveriam ser deixadas em um arquivo de ambiente, como o URL do Slack e também o endpoint da API de alergia Depois de fazermos isso, passaremos a analisar os testes e até mesmo a implementar um pipeline CICD automatizado 13. Testes de escrita: Na última lição, executamos nosso aplicativo e vimos que, de fato, tudo está funcionando conforme o esperado. Agora, está tudo bem, mas e se a API mudar ou algo estranho acontecer em nosso aplicativo fazendo com que ele falhe? Provavelmente queremos saber se alguma de nossas funções está quebrada sem precisar executar o aplicativo em um ambiente de produção completo. Portanto, nesta lição, escreveremos testes para cada uma das funções que escrevemos. Especificamente, a função Enviar mensagem do Slack e também as duas funções da API de alergia, a obtenção de dados de carga horária e a obtenção de dados atuais do gráfico Não escreveremos explicitamente um teste para a solicitação M HTP porque essa função é, na verdade chamada pelas outras três para as quais escreveremos testes Então, por proxy, se escrevermos um teste para essas três funções, também, por proxy, testaremos a função de solicitação make HTP Para começar a escrever nossos testes, criaremos uma pasta chamada tests. E criarei dois arquivos, um para cada um dos módulos ou funções que testaremos. Então, faremos nosso teste de API de alergia e também faremos nosso teste de envio de mensagens para o Slack E nota quatro, reconheça esses arquivos como testes reais. Eles precisam terminar com o dot go do teste de sublinhado Então, dentro de cada um deles, este é o nosso teste de pacote. Sabemos que precisaremos do módulo de teste, o módulo de teste embutido do G. E também para o nome da função, há uma regra de que o nome deve começar com test. Portanto, precisamos do sufixo do teste de sublinhado aqui e também do nome da função para começar com a palavra teste em maiúscula para que go reconheça totalmente o arquivo e as funções dentro dos arquivos para que seja um Então, aqui vou chamá-lo de test Allergy API, e temos que passar um ponteiro para esse módulo de teste Deixe-o vazio por enquanto e faça o mesmo aqui. Para nosso teste de mensagens do Slack, isso é um teste de pacote Importe o módulo de teste. E vou chamar esse teste de enviar mensagem ao Slack, e passamos um ponteiro para esse módulo de teste Agora, para realmente testar nossas funções, chamaremos os dados de carga horária G e as funções de dados do gráfico. E agora chamamos nossa função como faríamos em qualquer outro lugar em nosso código. Então, primeiro chamarei isso de get hour load data e, em seguida, faremos várias verificações sobre o erro e a mensagem para concluir nosso teste. Portanto, se o erro não for novo, queremos usar a função T dot f, e podemos dizer erro ao obter dados de carregamento por hora. Podemos transmitir o erro real. Você também deve verificar se a mensagem é Nil. Isso também é um caso de erro. E, nesse caso, diremos apenas erro ao obter dados de carregamento por hora. A mensagem é NIL e também podemos verificar se a mensagem em si é uma string vazia Isso provavelmente também não um resultado muito bom de nossa função. Portanto, erro ao obter dados de carregamento por hora. A mensagem está vazia. E quase o mesmo para obter os dados atuais do gráfico. Recebi nossa mensagem, nosso erro e as mesmas verificações. Então, se o erro não for nulo, pode realmente copiar isso. Só não se esqueça de alterar a mensagem aqui. Então, fica claro quando executamos nossos testes. Também verificaremos se a mensagem é Nil ou se a mensagem está vazia, e eu apenas substituirei essa string de carregamento por hora pelos dados atuais do gráfico Agora, no teste Send Slack message, temos apenas um erro retornado dessa função Util, e eu vou chamar a Send Slack com a mensagem Se o erro não for igual a Nil, diremos erro ao enviar mensagem de folga e inseriremos o erro real agora, e inseriremos o erro real usaremos o comando go test integrado para executar esses Então, eu gosto de passar algumas bandeiras quando faço meu teste. O primeiro é P, que define o número de testes paralelos como um. Em outras palavras, isso executaria seus testes em série. E eu gosto desse formato porque seus testes sempre serão executados na mesma ordem e você sempre obterá um resultado esperado de como seus testes são executados. Então, com o tempo, você pode se acostumar com a aparência dessa saída. Se você tiver uma base de código muito, muito grande, é claro, considere modificá-la para executar vários testes em paralelo Eu também adiciono o sinalizador V, que permite a saída detalhada. E isso é útil para que caso algo dê errado, você obtenha mais resultados e encontre o erro mais rapidamente. Também precisamos passar pela pasta em que queremos executar nossos testes. Nesse caso, é a pasta de testes. Então, juntos, o comando é ir testar P um e depois para o Verbose e depois para a pasta tests E se formos bons em nosso trabalho, ao executarmos esse comando, esperamos que todos os testes sejam aprovados. E, de fato, nossos dois testes, a API de teste de alergia e o teste Senss Slack Message, foram aprovados e nossos testes parecem bons Então, para recapitular rapidamente, escrevemos os testes para maioria das funções que escrevemos em nossa base de código Nós os colocamos na pasta de teste e discutimos como ser um teste válido para G. G precisa ver o teste de sublinhado no final e o nome da função no arquivo de teste para começar com o teste em maiúsculas Em seguida, escrevemos nossos testes. Nós os executamos com o comando G test com alguns sinalizadores adicionais e vimos que todos os nossos testes foram aprovados Na próxima lição, veremos como podemos dockerizar nosso aplicativo 14. Dockerize o aplicativo: Na última lição, escrevemos testes para nosso aplicativo e vimos que, de fato, os testes estavam sendo aprovados. Nesta lição, veremos como podemos dockerizar nosso aplicativo Como o GO compila em um único binário, não há muitas etapas complexas que precisamos realizar para que nosso aplicativo GO funcione sem problemas no Precisaremos definir dois arquivos, ou seja, o arquivo Docker em si e, em seguida, o arquivo de composição do Docker, que nos permitirá executar nosso contêiner com uma ferramenta como o Docker Compose, onde podemos gerenciar Então, vou começar com o arquivo Docker e colocá-lo aqui na raiz do nosso projeto Isso é simplesmente um arquivo Docker. E vou começar com o contêiner alpino Gang e vou pegar o contêiner 1.2 Golang Então, isso é do Golang 1.2 oh Alpine. Em seguida, definiremos o Wd como aplicativo, e essa é uma prática comum, pois não estamos construindo ou criando arquivos na raiz real desse contêiner, mas a definição de nosso próprio espaço de trabalho normalmente é considerada apenas como aplicativo nesse contêiner, e é aí que faremos a construção real Então, queremos copiar tudo o que temos aqui em nossa base de código para a pasta do aplicativo, e isso é apenas ponto a ponto. Então, na verdade, criaremos nosso aplicativo. Então, vamos fazer Go Build O, e vamos chamá-lo de Allergy Cron e, para executar isso, conforme mencionado, G criará um único binário, e só precisamos executar esse binário Portanto, esse Dockerfile já seria suficiente para criar um contêiner que pudéssemos construir e depois executar, mas para torná-lo mais amigável com o Docker Compose, para que possamos executá-lo imediatamente com o Docker Compose, também definiremos um ponto Yamofle do Docker Compose também definiremos Então, assim como o Dockerfile, colocarei aqui na raiz o Docker Compose Dot Yamofle e usarei a versão mais recente do Isso é 3,9. Em seguida, definimos nossos serviços. Temos o Allergy Cron, que é nosso único serviço E então definiremos o contexto de construção. Está aqui, o que significa que o Docker Compose procurará esse arquivo Docker diretamente em nossa raiz e usará Então, também podemos definir a política de reinicialização, e eu vou defini-la com o valor stop less stop. Então, isso significa que se nosso contêiner travar por algum motivo, Docker detectará isso e reiniciará o contêiner para Agora, para ver se configuramos tudo corretamente nesses dois arquivos, podemos criar e executar nosso contêiner. Então, primeiro, para criar o contêiner, vou usar o comando Docker Compose e queremos E como é a primeira vez que construímos nosso aplicativo como uma verificação dupla de segurança, também não publicarei nenhum caso, que significa que tudo o que for necessário para criar o contêiner será baixado recentemente da Internet Não vamos usar nenhum arquivo local aqui. Feito isso, também podemos executar o Docker Compose. E nesse caso, queremos subir e eu também passarei o sinalizador D, que é o sinalizador separado, que significa que o Docker iniciará nosso contêiner em segundo plano e nos devolverá nosso terminal Se não passarmos esse sinalizador D, começaremos a ver os registros do nosso contêiner anexados diretamente, e sair ou sair ambiente do terminal também sairemos do nosso Então, passamos esse D para que o contêiner continue funcionando em segundo plano. Portanto, se tudo funcionar corretamente, veremos um belo verde feito aqui no final de toda a saída da compilação. E podemos verificar se o contêiner está realmente execução com o comando Docker PsA E, de fato, vemos nossa alergia Cron Running criada há 18 segundos, até 15 segundos. Por isso, criamos e executamos com sucesso nosso aplicativo go em um contêiner Docker Como uma rápida recapitulação, definimos um arquivo Docker e um arquivo Docker Compose para permitir que nosso aplicativo seja executado com o Nós dois construímos e depois executamos nosso aplicativo em segundo plano, e vemos, de fato, nosso aplicativo está sendo executado em seu contêiner em nosso sistema local. Na próxima lição, veremos brevemente reiniciar nosso contêiner com o mínimo de tempo de inatividade 15. Como reiniciar o recipiente com tempo de inatividade mínimo: Na última lição, criamos os dois arquivos de configuração necessários para criar próprio contêiner Docker e, em seguida, executar esse contêiner Docker com o Docker Nesta lição, veremos rapidamente como podemos substituir um contêiner em execução com o mínimo de tempo de inatividade E, na verdade, tudo se resume a reconstruir o aplicativo e substituí-lo E, novamente, isso é usar esse comando Docker Compose. Vamos construir novamente sem cache. E emita o comando up separado e, o mais importante, com force recreate Passamos esse sinalizador para ter certeza de que o Docker sempre substituirá o contêiner existente pelo recém-construído Portanto, se emitirmos esse comando, veremos novamente que ele é concluído. E se eu verificar nossos contêineres com o PSA, veremos que a nova versão foi criada há 10 segundos em 7 segundos. Então, acabou de ser substituído. Agora, para um aplicativo Cron Job como esse, esse comando provavelmente é suficiente para suas necessidades Mas lembre-se de que esse não é um método de tempo de inatividade zero. Esse é apenas um método de tempo de inatividade mínimo. Você teria um tempo de inatividade durante os curtos momentos necessários para Docker substituir o Para uma solicitação de cron job como essa, é importante lembrar de não substituir esse contêiner perto do momento em que seu cron job é executado Se você estiver fazendo algo mais complicado que exigisse um verdadeiro tempo de inatividade zero, precisaria fazer algo mais complexo, como criar vários contêineres, trocar balanceadores de carga e assim por diante Mas esse tipo de estratégia fora do escopo deste curso. Mas, em resumo, se você sabe o que seu aplicativo está fazendo e quando é seguro substituir esse contêiner, esse método funciona muito bem para muitos tipos de aplicativos. Na próxima lição, voltaremos a programar e a melhorar a mensagem que enviamos via Slack 16. Adicionando formatação sofisticada às mensagens do Slack: Na última lição, discutimos brevemente como poderíamos reconstruir e substituir um contêiner com o mínimo de tempo de inatividade Nesta lição, voltaremos a alguns códigos e veremos como podemos melhorar a formatação das mensagens do Slack que enviamos Portanto, se acessarmos nosso arquivo da API de alergia, podemos lembrar que estamos enviando duas mensagens bastante simples do Slack Pode ser bom adicionar um pouco mais de cor e talvez até alguns emojis para que o sentimento de nossa mensagem possa ser forma mais rápida e interessante Então, o que faremos é modificar essa mensagem inicial. Vamos deixar a mensagem histórica como está. Mas para os dados reais em tempo real, melhoraremos a formatação dessa mensagem Então, na parte inferior, vou definir uma nova função chamada formatar dados de alergia. E é apenas uma função em minúsculas aqui porque não precisamos exportá-la Ele só será usado neste arquivo. Vou passar a carga média escalonada que temos, que é um int, e retornaremos uma string O que temos atualmente é nossa mensagem formatada e ela se parece com esta A carga média de pólen de hoje e passamos essa carga média escalonada Mas vamos prefixar e sufixar essa mensagem para torná-la um pouco mais Podemos fazer isso com uma caixa de comutação e o que vou fazer é ativar a carga média escalonada E, por um lado, esse é um caso meio moderado. Então, vamos prefixá-lo com esse emoji de círculo amarelo e colocar Ok, depois um espaço e, em seguida, a mensagem existente que temos E talvez queiramos colocar limites em um nível baixo ou moderado Então, no caso de serem dois, podemos aumentar a cor para uma cor de aviso laranja e dizer algo como cuidado novamente com nossa mensagem formatada E nesse caso, isso é médio, e vamos terminar com aquele emoji laranja Depois, quatro ou três. Colocaremos vermelho e avisaremos novamente com mensagem formatada e mencionaremos que está alto e terminaremos com o emoji vermelho Agora, se for o nível mais alto, que é quatro, colocaremos três desses emojis vermelhos e colocaremos desses emojis vermelhos e um alerta com nossa mensagem formatada E coloque muita ênfase nesses casos mais altos aqui. E também concluiremos isso com três desses círculos emogi vermelhos Então, se for o caso, se for zero, falharemos e também usaremos o padrão e retornaremos esse emogi verde e, em seguida, ficaremos também usaremos o padrão e retornaremos esse emogi verde e , em seguida, bem com a mensagem formatada, Só para tornar a pontuação consistente aqui, podemos fechar o colchete da nossa caixa de distribuição Então, agora, em vez de nosso formato aqui, vamos nos livrar disso, pois ele já está inativo em nossa nova função, chamaremos a função de formatação de dados de alergia e passaremos essa carga média escalonada Agora, se salvarmos isso, podemos testar nosso aplicativo. Então, agora é 318. Vamos aumentar nosso cron para 319. Então, acho que serão 15 e 19. E podemos emitir para executar o Dotco principal. E, de fato, logo após 319 aqui, recebemos uma cópia do que enviamos pelo Slack com nossa nova mensagem agradável E hoje, está meio quente e seco, então eu tenho que cuidar um pouco. O nível está alto hoje. Então, como uma revisão desta lição, acessamos nosso arquivo de API de alergia e substituímos a primeira mensagem que enviamos por essa nova função de dados de alergia de formato. E adicionamos um texto extra aqui, bem como alguns emojis que refletem melhor o sentimento das informações que estamos enviando E, no geral, acho que parece muito bom e é mais fácil determinar a natureza da mensagem imediatamente. Então, faltam apenas algumas aulas. Na próxima lição, veremos como mover todos esses valores codificados, como o URL e o fuso horário do Cron, bem como o intervalo Cron, e colocá-los em um arquivo M. E depois de fazer isso e garantir que nosso aplicativo ainda esteja funcionando, usaremos o CircleCI para criar um pipeline CICD que testará, criará e implantará automaticamente nosso 17. Movendo segredos e valores codificados para um arquivo ENV: Na última lição, escrevemos essa função de formatação de dados de alergia para melhorar a formatação e tornar as mensagens do Slack um pouco mais coloridas Nesta lição, vamos pegar todos esses valores codificados, como o URL da API, bem como a localização do cron e o cronograma do cron, bem como a localização do cron e o cronograma do cron e colocá-los em um Então, para começar, vou criar um arquivo N, então ponto N. E imediatamente, queremos criar um arquivo Get Ignore e adicionar esse arquivo N ao G Ignore. Essa é uma prática comum, pois normalmente você terá pelo menos um ou possivelmente mais valores secretos que não deseja verificar no seu repositório Git Então, vou criar esse Get Ignore e vou adicionar o arquivo M. Então, o que realmente temos para nossas variáveis de ambiente? Temos o URL raiz da API Allergy aqui. Também temos nosso URL do web hook do Slack e temos nosso fuso horário Cron, e temos nosso fuso horário Cron bem como a string de programação Então, vamos adicionar tudo isso ao nosso arquivo de ambiente. Então, temos nosso URL do webhook do Slack. Pode colar isso. Tenho a raiz do URL da nossa API de alergia, vou chamá-la. Esse é esse cara. Temos nosso fuso horário cron Isso está aqui. E o cronograma do cron. E esse é esse. E enquanto eu estiver aqui, vou reverter isso volta para o valor original que tínhamos às 8:00 da manhã. valor original que Agora, para que o tempo de execução do Gang realmente veja ou tenha esses valores no ambiente, precisamos garantir que esse arquivo de ambiente seja carregado no tempo de execução. Para fazer isso, podemos usar o popular pacote Johogo dot Nv. Então isso é github.com, Joho e go dot v. E podemos recuperar E logo no topo da nossa função principal, podemos carregar isso. Isso retorna um erro e é apenas carregar pontos N pontos. E não precisamos passar nenhum parâmetro. Por padrão , ele procurará nosso arquivo ponto N. Claro, queremos verificar se o erro não é Nil, então teremos uma mensagem fatal aqui Erro ao carregar o arquivo. Agora, precisamos realmente obter o valor dessas variáveis de ambiente. Isso pode ser feito com a chamada s.gn. Então, nós os carregamos logo de cara, e eles devem estar disponíveis em nosso ambiente. Então, temos o OS GNV. E esse será o fuso horário Cron. E para este, temos o OS GNN. Este é o Cron Schedule. E da mesma forma, aqui na API OSG N você também precisa adicioná-la abaixo, eu acredito, ou acima e também em nossa função slack Este é o OSG N. E nosso URL do webhook do Slack. Agora, também precisaremos adicionar esse carregamento do ambiente em nosso teste. Como agora que refatoramos o código, o código executado nesses testes também espera ter essas variáveis de Portanto, é um pouco diferente no teste porque não estamos na raiz, não podemos simplesmente chamar a carga padrão, mas precisamos passar explicitamente o caminho de volta para o ambiente na raiz Vou copiar isso para o topo de nossos dois testes. E só precisamos passar explicitamente por esse caminho. E importe os pacotes Godot end e log aqui. E a mesma coisa para o outro teste. Importe-os. E nós já definimos o erro agora, então é apenas o normal igual E isso deve bastar para os testes. Então, para revisar rapidamente, criamos um arquivo de ponto N para todos os vários valores codificados que estávamos usando em nosso aplicativo Também criamos um arquivo get Ignore para ter certeza de que estamos ignorando o ponto N porque, de fato, existem segredos Nesse caso, o mais importante é esse URL do webhook. Não queremos que ninguém entenda isso, senão eles poderiam postar em nosso canal. Examinamos nosso código e substituímos esses valores codificados por seus respectivos nomes de ambiente E também adicionamos aos nossos testes a forma de carregar a variável de ambiente. Portanto, no caso de nosso teste passar explicitamente o caminho para o nosso lado, que está nas pastas superiores Então, usamos a notação Unix de pontos para chegar à pasta raiz da nossa pasta de teste Em última análise, esse é um padrão muito bom porque, nesse arquivo M, você vê imediatamente alguns dos valores-chave mais importantes de como nosso aplicativo funciona, seja, o fuso horário e a programação, mas também se o URL mudar ou se você encontrar um fornecedor diferente, poderá alterar esse URL e escrever um cliente diferente para essa API Além disso, por exemplo, se você alterasse URL do webhook para um canal diferente ou se a equipe mudasse, você também poderia substituí-lo rapidamente de vez em quando, sabendo que ele está sendo usado em sua base de código, onde quer que seja Então, agora que encaixamos nosso aplicativo, limpamos as mensagens do Slack e também limpamos os valores codificados Finalmente, chegou a hora da próxima lição de criarmos um pipeline CICD completo e completo para criar nosso aplicativo e implantá-lo no Docker E finalmente encerraremos o curso retirando esse contêiner recém-criado do Docker Hub e executando-o uma última vez para ver se tudo ainda está 18. Criando um pipeline de CI CD com Circle CI: Na última lição, criamos um arquivo de ambiente para armazenar todos os valores e segredos codificados em todo nosso aplicativo e substituímos esses valores codificados pelos nomes das variáveis de ambiente do E essa foi realmente a etapa final para estarmos prontos para empacotar e automatizar a forma como construímos nosso contêiner Portanto, nesta lição, criaremos um pipeline completo de CD de CI que criará e testará nosso aplicativo com os testes que escrevemos. Então, se esses testes passarem, ele implantará ou carregará nosso contêiner no Docker Hub Então, no final, retiraremos esse contêiner e executaremos como um teste final para ver se tudo está funcionando. Então, para começar com o CircleCI, precisamos primeiro criar uma pasta que seja Circle CI e, dentro dessa pasta, um arquivo config Agora, a primeira coisa que você precisa fazer em seu arquivo Yamal de ponto de configuração, semelhante ao Docker compose, é fornecer a Atualmente, essa versão ou a versão mais recente é 2.1. E também listaremos um orbe. Agora, orbs são comandos ou trabalhos pré-empacotados que são muito comuns Por exemplo, eles têm uma esfera nodal. Eles têm uma esfera frouxa, e isso só economiza seu tempo. Em vez de escrever comandos bash explícitos para realizar tarefas, eles têm Por exemplo, envie uma mensagem do Slack e você só precisa passar a mensagem de string Você não precisa emitir essa declaração curl ou coisas assim No nosso caso, o único orbe de que precisamos é o hub do Docker, e isso pode ser feito especificando o Docker, e usaremos a versão mais recente desse orbe do Docker, que é precisamos é o hub do Docker, e isso pode ser feito especificando o Docker, e usaremos a versão mais recente desse orbe do Docker, que é 2.2 0.0. Tudo o que resta agora são duas partes principais de um arquivo config dot yaml. Existem trabalhos e fluxos de trabalho. Os trabalhos são várias etapas que você pode usar uma ou mais vezes em seus fluxos de trabalho Assim, você pode pensar neles como blocos de construção individuais, e os fluxos de trabalho realmente se combinam e dizem em que ordem e como esses trabalhos devem ser executados Então, normalmente, os fluxos de trabalho são listados mais acima no ponto de configuração yam Mas, como vamos passo a passo aqui, primeiro escreveremos os trabalhos e depois escreveremos os fluxos de trabalho Faz um pouco mais de sentido do ponto de vista passo a passo. Então, começaremos definindo nossos empregos. E, por enquanto, nós realmente só temos um trabalho, que é testar nosso aplicativo. Então, vou chamá-lo de teste, temos que especificar um diretório de trabalho. E no mundo do Circle CI, esse repositório é o significante especial para o repositório local E vamos usar uma imagem do Docker e vamos usar a imagem GO Então, podemos definir nossas etapas do que realmente queremos que seja feito nesse trabalho. Então, primeiro, vamos, é claro, verificar o código e podemos armazenar em cache nosso arquivo go sum. Isso tornará as compilações subsequentes mais rápidas. E vamos verificar algumas de nossas opções e também instalaremos dependências a partir delas. verificar algumas de nossas opções e também instalaremos dependências a partir É necessário emitir o GGet e, em seguida, salvaremos esse cache. Então, caso mais tarde, se instalarmos novos pacotes ou alterarmos as versões deles, isso será refletido com precisão nessa chave que definimos para nosso cache. E também precisamos definir em qual caminho isso está. Portanto, a maior parte disso foi retirada de um exemplo que a CircleCI tem em seu site sobre as práticas recomendadas e recomendadas para um E vou colocar um link para isso nos recursos da lição. Agora também precisamos criar nosso arquivo de ambiente porque sabemos que nosso aplicativo não pode ser executado sem essas variáveis de ambiente. Então, teremos outra etapa de corrida aqui. O nome é criar arquivo ponto N. O comando pode usar o pipe para executar várias etapas ou vários comandos. Primeiro, vamos criar esse arquivo. Em seguida, usaremos o Echo para ecoar todas as variáveis de ambiente de que precisamos Para escapar para o ambiente CircleCI, usamos essa sintaxe, os colchetes com o cifrão, e usaremos os mesmos nomes que temos Veremos como defini-los posteriormente na interface do usuário do CircleCI. E vamos apenas acrescentar a esse novo arquivo. Então, vou copiar isso algumas vezes e sabemos que temos a raiz do URL da API de alergia. Também temos nosso fuso horário cron e também temos aquela string de programação cron e, com ela completa , emitiremos testes Então, vou chamar isso de testes de execução. E o comando que conhecemos da lição anterior é ir testar. Vamos definir esse sinalizador paralelo e também o sinalizador Verbose, e queremos executá-lo na pasta de testes Então, definimos nosso único teste de trabalho e agora precisamos definir os fluxos de trabalho Portanto, o padrão normal, como mencionei, é que os fluxos de trabalho superam os trabalhos, então voltaremos aqui e também especificaremos nossos fluxos de trabalho Portanto, também temos apenas um fluxo de trabalho, que será o fluxo de trabalho de produção, e precisamos especificar os trabalhos. E temos nosso trabalho de teste e também vamos filtrar no galho. E queremos apenas a filial principal. E então, o segundo trabalho que queremos é usar esse orbe Docker E isso será o Docker Publish. E a imagem será nosso nome de usuário e nome do repositório, que também definiremos posteriormente no CircleCI WebUI junto Então, chegaremos a isso em alguns instantes. Agora, também precisamos definir a ordem desses trabalhos. Se não especificarmos nenhuma ordem, CircleCI, vamos executá-las Isso pode ser útil dependendo do que você está fazendo. Mas é claro que, em nosso caso, queremos garantir que esses testes sejam aprovados antes de publicarmos em nosso contêiner. A maneira de fazer isso é com a diretiva de requisitos, e exigimos, é claro, que o trabalho de teste seja concluído. E também queremos filtrar na ramificação principal. Agora, há muito código Yamil nesse arquivo e não está claro se temos algum erro ou problema de sintaxe, mas, felizmente, CircleCI fornece uma ferramenta CLI na qual podemos verificar esse arquivo de configuração e não está claro se temos algum erro ou problema de sintaxe, mas, felizmente, o CircleCI fornece uma ferramenta CLI na qual podemos verificar esse arquivo de configuração. Adicionarei nos recursos da lição o link para a documentação oficial sobre como você pode instalá-la. Eu já o tenho instalado no meu sistema e a forma de verificar a configuração é com o CircleCI Config com o CircleCI Podemos ver aqui que eu esqueci que parece o ponto e vírgula E vou executar novamente essa verificação, e também esqueci um S. E, finalmente, parece que temos uma configuração válida aqui Então, obtemos que o é válido. Portanto, já podemos ver que é bastante prático encontrar qualquer tipo de erro de digitação ou problemas de formatação em nosso arquivo de configuração Agora, neste ponto do seu código , provavelmente faria sentido ramificar e criar uma ramificação desenvolvida. Primeiro, é claro, exigindo que você tenha inicializado o repositório Git e assumindo que talvez você ainda esteja na ramificação principal ou principal, você, é claro , emitiria, verificaria B develop e confirmaria tudo nessa ramificação Então, o que você faria seria mesclar quando estiver pronto, mesclar com sua ramificação principal ou master, e então isso iniciaria este caso, teria que ser a ramificação principal ou então o CircleCI não faria nada CircleCI não Ele está aguardando confirmações para essa ramificação principal , conforme especificamos Mas se você, por exemplo, adotou a convenção de nomenclatura master, precisaria alterá-la para master para que o CircleCI fizesse qualquer coisa nessa ramificação No meu caso, já estou aqui no repositório específico do curso e tenho um nome de ramificação personalizado Então, por enquanto, vou deixar isso como está e vamos entrar nos aplicativos web Docker Hub e CircleCI e configurar o que precisamos Então, dentro do doctor Hubb, faça login ou crie uma conta Se você não tiver um, eles são gratuitos. E vamos clicar em Criar repositório aqui, e eu chamarei o meu Allergy Cron Podemos simplesmente clicar em Criar aqui. E agora temos um repositório para o qual podemos enviar. Em seguida, acessaremos circleci.com e clicaremos E na página de login aqui, como o repositório, no meu caso, está no Github, vou fazer login com Se você decidiu acompanhar o Bitbucket, por exemplo, você pode fazer login com o Bitbucket Então, estou em várias organizações, mas o repositório em que estamos programando está na minha conta pessoal Então, vou selecionar isso e você verá todos os seus repositórios no seu perfil do GitHub. E, claro, eu quero que este curso vá para aplicativos do mundo real, e podemos clicar em Configurar projeto. Então, antes que o CircleCI possa encontrar o arquivo Arc fig, eu tenho que voltar aqui no código e confirmar Então, vou adicionar tudo. Vou confirmar algo como se o CircleCI Config terminasse. Vou insistir que tenho que definir o nome da lição com o nome da ramificação. Então, aqui eu deveria ser capaz de especificar a ramificação da Lição 18, e vemos que o CircleCI até examinará nosso código e encontrará Então, é um serviço muito, muito bom. Eu realmente gosto de usar o CircleCI. Eles tornam isso muito fácil. Portanto, no seu caso, dependendo de onde você fez o push, se você o enviou para a ramificação desenvolvida, se você o enviou para a ramificação principal ou para a ramificação master, você pode especificar isso aqui, e espero que o CircleCI encontre seu ponto de configuração YamoFle encontre seu Então, depois de descobrir isso, basta clicar em Configurar projeto. E até tentará iniciar o primeiro fluxo de trabalho. Mas é claro que, como o commit foi para a ramificação da Lição 18, ele vê na configuração: Ok, não há nada a fazer com a Lição 18, e ela simplesmente dirá que não há fluxo Então, agora que temos nosso projeto CircleCI configurado, devemos adicionar todas essas variáveis de ambiente ao ambiente CircleCI real Para fazer isso, podemos ir até aqui para as configurações do projeto e aqui para as variáveis de ambiente. E podemos adicionar nossos pares de variáveis de ambiente de valor-chave. E sabemos que temos nosso URL do webhook do Slack. E podemos continuar adicionando todas as variáveis que sabemos que precisamos para nosso aplicativo. Tenho fuso horário. Eu tenho o cronograma do cron. E agora também precisamos adicionar alguns para nossa integração com o Docker Hub Portanto, precisamos adicionar o nome de usuário do Docker, o login do Docker, que na verdade são os mesmos, a senha do Docker e o nome do repositório do Docker Então, no meu caso, meu Docker Hub é a conta da nossa empresa, Full Stack Craft Então, vou usar isso para o nome de usuário do Docker. E também as variáveis de ambiente de login do Docker. O nome do repositório Docker é o nome que você forneceu para seu E no meu caso, isso é Allergy Cron. E, finalmente, a senha do Docker. Claro, eu não vou mostrar isso aqui. Então, agora definimos todas as variáveis de ambiente que precisamos para executar o pipeline CICD De volta ao código, como no meu caso, eu já tenho uma ramificação principal que não quero estragar, vou criar uma ramificação separada chamada Pipeline e também atualizar esse filtro de ramificação no arquivo Yam de pontos de configuração, e então poderemos testar o pipeline também atualizar esse filtro de ramificação no arquivo Yam de pontos de configuração, e então poderemos testar Então, vou apenas modificar isso para Pipeline. E lembre-se, é claro, no seu caso, você pode deixar isso para o Maine ou para qualquer filial em que queira que seu gasoduto CICD seja acionado Então, vou criar essa nova ramificação com G checkout B Pipeline De fato, posso ver que estamos no ramal do oleoduto. Vou adicionar tudo. E vou adicionar uma mensagem Algo como uma ramificação personalizada do pipeline, e podemos enviar. Agora, de volta ao CircleCI, devemos ver que o fluxo de trabalho de produção realmente começa porque o CircleCI vê aquele Podemos clicar aqui para ver nossos dois trabalhos. Portanto, temos nosso trabalho de teste e nosso trabalho publicado no Docker. E mesmo dentro dos trabalhos em si, você pode ver todas as etapas e a saída. Então, parece que nossos testes foram aprovados. Esse é o resultado familiar que vimos na lição anterior. Então, é claro, de volta ao fluxo de trabalho, ele passará para a publicação do Docker e veremos como isso acontece Parece que também foi um sucesso. E, de fato, no Docker Hub, vemos que ele foi publicado há alguns segundos, então nosso pipeline CICD funcionou perfeitamente Agora, embora nossa compilação e fluxo de trabalho pareçam estar funcionando, se realmente pegássemos nosso contêiner docker e tentássemos executá-lo, veríamos que G reclama que não consegue encontrar a variável de ambiente Esquecemos a etapa fundamental em nosso pipeline de CICD para manter essa variável de ambiente entre esses dois trabalhos Então, para fazer isso aqui no final do nosso trabalho de teste, podemos especificar esse comando persist espaço de trabalho e queremos especificar que a raiz está aqui, e vamos apenas persistir o arquivo dot m que criamos E então, em nosso comando de publicação do Docker, precisamos especificar que, quando estamos publicando ou construindo esse contêiner, queremos anexar a essa raiz atual E então, quando o Docker estiver sendo construído, ele terá esse arquivo de ambiente em seu espaço de trabalho de construção Então, uma coisa muito importante que eu quero enfatizar aqui é que isso é um pequeno risco de segurança. Portanto, observe aqui que, neste caso, este é um contêiner listado publicamente e o arquivo estará dentro do contêiner. Portanto, embora isso seja bom para variáveis públicas como o fuso horário do Cron e a string de programação do cron, não é adequado para segredos como nosso webhook do slack Nesse caso, sugiro que você crie um arquivo separado e o transmita ao executar seu contêiner Docker, onde quer que esteja No entanto, essas especificidades secretas de gerenciamento tendem a ser muito diferentes dependendo de organização para organização, então vou deixar isso fora do escopo deste curso Por enquanto, vamos apenas ilustrar como podemos incluir esse arquivo em nosso CICD Mas observe que é um possível problema de segurança. Uma pequena alteração final que precisamos fazer aqui em nosso arquivo amo configurado é escapar dessa variável de ambiente do cronograma cron Como temos esses asteriscos aqui, quando eles escapam pelo CircleCI, temos Então, para remediar isso, tudo o que precisamos fazer é colocar essa variável entre aspas duplas, e isso resolverá o problema de ecoar esse valor em nosso arquivo final Então, como teste final para nosso contêiner, vou mudar esse cronograma de coroas para algo nos próximos minutos, e então poderemos retirar nosso contêiner, executá-lo e garantir que tudo esteja funcionando e funcionando, de fato, no momento em que definimos nosso cronograma de cron Então, são cerca de 4:18 agora. Então, vou deletar isso e adicioná-lo novamente. Vamos fazer por 225. Então esse é o 25º minuto, a 14ª hora e depois os asteriscos para Pode adicionar isso de volta. E de volta ao projeto aqui, executarei novamente o último fluxo de trabalho para garantir que o contêiner seja reconstruído com essa nova variável Então, espere aqui até que o pipeline seja concluído, e então podemos entrar no Doctor Hub, obter nosso ID de contêiner e executar esse contêiner Então, o pipeline foi concluído e, se pularmos até aqui, para o Docker Hub, veremos que nossa nova imagem acabou de ser publicada Clicamos nisso. Podemos obter a identificação completa. Vou copiar isso. Então, para executá-lo, podemos emitir o Docker Run Em seguida, queremos desanexar esse ID completo do contêiner. Ele será baixado para nós e começará a executá-lo. Assim, podemos verificar se está sendo executado com P A. Vemos que está em execução e ainda não há registros, mas esperamos que às 2:25, recebamos uma cópia registrada da nossa mensagem do Slack e, claro, da própria mensagem do Ok, então 225 acabaram de passar. Vamos conferir nossa folga aqui. De fato, recebemos essa mensagem. Então, hoje está um pouco chuvoso. A carga de pólen é um pouco menor que a média. Algumas coisas boas para eu saber. E se voltarmos aqui para nossos registros do docker, obteremos aquela cópia da mensagem que foi enviada de volta daquela mensagem de registro que colocamos no ponto principal algumas lições atrás Então, parabéns. Você chegou ao final da última aula de codificação técnica deste curso Só resta uma lição, que é o tipo de lição de conclusão e recapitulação que aborda o que abordamos neste curso, além de discutir onde você pode encontrar o código, o livro e quaisquer outros recursos adicionais do curso 19. Conclusão: Então, parabéns. É isso mesmo. Esse é o fim deste curso de escolha de aplicativos do mundo real. Espero que você tenha gostado de tomá-lo tanto quanto eu gostei de fazer. Apenas um lembrete, há uma versão em livro em PDF deste curso Vou adicionar o link para isso nos recursos da lição. Há também o repositório GitHub para este curso, onde cada lição corresponde a tudo o que fizemos naquela Eles são nomeados por filial. Então isso é tudo que eu tenho do meu lado. Divirta-se escrevendo código G, e eu vou ver todos vocês na próxima vez. O.