Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Junte-se a nós no Amazon Web Services re:Invent 2024! Saiba como usar o MongoDB para casos de uso de AI .
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Idiomaschevron-right
Gochevron-right

Noções básicas de HTTP com Go 1.22

Jorge D. Ortiz-Fuentes7 min read • Published Apr 17, 2024 • Updated Apr 23, 2024
Go
APLICATIVO COMPLETO
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty

Noções básicas de HTTP com Go 1.22

Go é uma linguagem de programação bonita, muito produtivo e com muitos recursos. Esta série de artigos foi criada para oferecer a você um passo a passo dos recursos da linguagem, enquanto criamos um programa realista do zero.
Para que isso funcione, há algumas coisas com as quais devemos concordar:
  • Esta não é uma explicação abrangente da sintaxe Go. Explicarei apenas as partes estritamente necessárias para escrever o código desses artigos.
  • Digitar o código é melhor do que apenas copiar e colar, mas faça como quiser.
  • Os materiais estão disponíveis para serem testados por você mesmo, no seu próprio ritmo, mas é recomendável jogar junto se você fizer isso em uma sessão ao vivo.
  • Se você é um novato no Golang, digite e confie. Se você escreveu algum Go, faça qualquer pergunta. Se você tiver experiência com a Golang, há comentários sobre as melhores práticas -vamos consultá-las. Em resumo: perguntar sobre a sintaxe, perguntar sobre a milagrosidade, fale sobre os tópicos avançados ou Go para a barra.
  • Finalmente, embora abordemos apenas as partes essenciais, o produto desta série é a semente para um back-end de anotações, onde lidaremos com as notas e seus metadados. Espero que você goste.

Olá, mundo

  1. Vamos começar criando um diretório para nosso projeto e inicializando o projeto. Crie um diretório e entre nele. Inicialize o projeto como um módulo Go com o identificador “github.com/jdortiz/go-intro,”, que você deve alterar para algo exclusivo e de sua propriedade.
    1go mod init github.com/jdortiz/go-intro
  2. No gerenciador de arquivos do VSCode, adicione um novo arquivo chamado main.go com o seguinte conteúdo:
    1package main
    2
    3import "fmt"
    4
    5func main() {
    6 fmt.Println("Hola Caracola")
    7}
  3. Go juntos percorrer o conteúdo desse arquivo para entender o que estamos fazendo aqui.
    1. Cada arquivo de origem deve pertencer a um package. Todos os arquivos em um diretório devem pertencer ao mesmo pacote. O pacote main é onde você deve criar sua funçãomain.
    2. func é a palavra-chave para declarar funções e main é onde seu programa começa a ser executado.
    3. fmt.Println() é uma função da biblioteca padrão (stdlib) para imprimir algum texto na saída padrão. Pertence ao pacotefmt .
    4. Ter a instrução importnos permite usar o pacote fmtno código, como estamos fazendo com a funçãofmt.Println().
  4. O ambiente está configurado para que possamos executar o programa a partir do VS Code. Use "Executar e depurar" na barra esquerda e execute o programa. A mensagem "Hola caracola" aparecerá no console de depuração.
  5. Você também pode executar o programa a partir do terminal incorporado usando
    1go run main.go

Servidor web mais simples

  1. A biblioteca padrão do Go inclui todas as peças necessárias para criar um servidor HTTP completo. Até a versão 1.22, usando pacotes de terceiros para funcionalidades adicionais, como rotear facilmente solicitações com base no verbo HTTP, era muito comum. Go 1.22 adicionou a maioria das funcionalidades desses pacotes de forma compatível com versões anteriores.
  2. Os servidores da web escutam solicitações feitas para um determinado endereço IP e porta. Vamos definir isso em uma constante dentro da função principal:
    1const serverAddr string = "127.0.0.1:8081"
  3. Se quisermos responder às solicitações enviadas ao diretório raiz do nosso servidor web, devemos dizer a ele que estamos interessados nesse caminho de URL e no que queremos que aconteça quando uma solicitação for recebida. Fazemos isso usando http.HandleFunc() na parte inferior da função principal, com dois parâmetros: um padrão e uma função. O padrão indica o caminho em que estamos interessados (como em "/" ou "/customers" ) mas, como Go 1.22, o padrão também pode ser usado para especificar o verbo HTTP, restringir a um determinado nome de host e/ou extrair parâmetros da URL. Usaremos "GET /", o que significa que estamos interessados em solicitações GET para a raiz. A função usa dois parâmetros: um http.ResponseWriter, usado para produzir a resposta e um http.Request que contém os dados da solicitação. Usaremos uma função anônima (também conhecida como lambda) que inicialmente não faz nada. Você precisará importar o pacote "net/http" e o VS Code pode fazer isso automaticamente usando seus recursosde correção rápida.
    1http.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) {
    2})
  4. Dentro de nossa lambda, podemos usar o escritor de resposta para adicionar uma mensagem à nossa resposta. Usamos o métodoWrite() do escritor de resposta que usa uma fatia de bytes (ou seja, uma "visualização" de uma array), portanto, precisamos converter a string. HTML pode ser adicionado aqui.
    1w.Write([]byte("HTTP Caracola"))
  5. Diga ao servidor para aceitar conexões com o endereço IP e a porta com a funcionalidade que acabamos de configurar. Faça isso após toda a invocação para http.HandleFunc().
    1http.ListenAndServe(serverAddr, nil)
  6. http.ListenAndServe() retorna um erro ao terminar. É uma boa ideia envolvê-lo com outra função que registrará a mensagem quando isso acontecer. log também precisa ser importado: faça você mesmo se o VSCode não cuidou disso.
    1log.Fatal(http.ListenAndServe(serverAddr, nil))
  7. Compile e execute. O codespace oferecerá o uso de um navegador ou a abertura da porta. Você pode ignorar isso por enquanto.
  8. Se você executar o programa a partir do terminal, abra um segundo terminal usando o endereço ".
    1curl -i localhost:8081/

(De)Serialização

Tarefa de descarregamento e desserialização
  1. Os manipuladores de HTTP também podem ser implementados como funções regulares, ou seja, não anônimas, e são realmente mais fáceis de manter. Vamos definir um para um endpoint que pode ser usado para criar uma nota após a funçãomain.
    1func createNote(w http.ResponseWriter, r *http.Request) {
    2}
  2. Antes de implementarmos esse manipulador, precisamos definir um tipo que conterá os dados de uma nota. A nota mais simples poderia ter um título e um texto. Colocaremos esse código antes da funçãomain.
    1type Note struct {
    2 Title string
    3 Text string
    4}
  3. Mas podemos ter mais alguns dados, como uma lista de categorias, que em Go é representada como uma fatia de cadeias de caracteres ([]string), ou um campo que usa outro tipo que define o escopo dessa nota como uma combinação de um projeto e uma área. A definição completa desses tipos seria:
    1type Scope struct {
    2 Project string
    3 Area string
    4}
    5
    6type Note struct {
    7 Title string
    8 Tags []string
    9 Text string
    10 Scope Scope
    11}
  4. Observe que os nomes dos tipos e dos campos começam com uma letra maiúscula. Essa é a maneira de dizer no Go que algo é exportado e também se aplica aos nomes das funções. É semelhante ao uso de um atributopublic em outras linguagens de programação.
  5. Além disso, observe que as declarações de campo têm o nome do campo primeiro e seu tipo depois. O campo mais recente é chamado " Scope, " porque é exportado, e seu tipo, definido algumas linhas acima, também é chamado de Scope. Não há problema aqui — Go entenderá a diferença com base na posição.
  6. Dentro do nosso manipuladorcreateNote(), agora podemos definir uma variável para esse tipo. A ordem também é primeiro nome da variável e segundo tipo. note é uma variável válida daqui em diante, mas no momento todos os campos estão vazios.
    1var note Note
  7. Os dados são trocados entre servidores e clientes HTTP usando algum formato de serialização. Um dos mais comuns atualmente é o JSON. Após a linha anterior, vamos criar um decodificador que possa converter bytes do fluxo de solicitação HTTP em um objeto real. O pacoteencoding/json da biblioteca padrão fornece o que precisamos. Observe que eu não declarei a variáveldecoder . Eu uso a "declaração de variável curta" ( :=), que declara e atribui valor à variável. Nesse caso, o Go também está fazendo inferência de tipo.
    1decoder := json.NewDecoder(r.Body)
  8. Este decodificador agora pode ser utilizado na próxima linha para desserializar os dados na solicitação HTTP. Esse método retorna um erro, que será nil (sem valor) se tudo correu bem, ou algum valor (erro) de outra forma. Observe que usamos & para passar uma referência à variável, para que o método possa alterar seu valor.
    1err := decoder.Decode(&note)
  9. A expressão pode ser agrupada para ser usada como condição em uma instrução if. É perfeitamente normal em Go obter algum valor e depois comparar em uma expressão após um ponto e vírgula. Não há parênteses ao redor da expressão condicional.
    1if err := decoder.Decode(&note); err != nil {
    2}
  10. Se algo der errado, queremos informar ao cliente HTTP que há um problema e encerrar a função. Essa saída antecipada é muito comum quando você lida com erros em Go. A funçãohttp.Error() é fornecida pelo pacotenet/http, grava no gravador de resposta a mensagem de erro fornecida e define o status HTTP.
    1http.Error(w, err.Error(), http.StatusBadRequest)
    2return
  11. Se tudo correr bem, apenas imprimimos o valor da nota que foi enviada pelo cliente. Aqui, usamos outra função do pacotefmt que grava em um gravador os dados fornecidos, usando uma string de formato. As strings de formato são semelhantes às usadas em C, mas com algumas opções extras e mais segurança. "%+v" significa imprimir o valor em um formato padrão e incluir os nomes dos campos (% para indicar que este é um especificador de formato, v para imprimir o valor, o + para incluir os nomes dos campos).
    1fmt.Fprintf(w, "Note: %+v", note)
  12. Vamos adicionar este manipulador ao nosso servidor. Ele será usado quando uma solicitação POST for enviada para o caminho/notes .
    1http.HandleFunc("POST /notes", createNote)
  13. Execute esta nova versão.
  14. Vamos primeiro testar o que acontece quando não é possível desserializar os dados. Devemos receber um código de status 400 e a mensagem de erro no corpo.
    1curl -iX POST localhost:8081/notes
  15. Finalmente, vamos ver o que acontece quando passamos alguns dados bons. Os dados desserializados serão impressos na saída padrão do programa.
    1curl -iX POST -d '{ "title": "Master plan", "tags": ["ai","users"], "text": "ubiquitous AI", "scope": {"project": "world domination", "area":"strategy"} }' localhost:8081/notes

Conclusão

Neste artigo, ensinamos:
  • Como iniciar e inicializar um projeto Go.
  • Como escrever um servidor HTTP básico do zero usando apenas a funcionalidade de biblioteca padrão Go.
  • Como adicionar endpoints ao nosso servidor HTTP que fornecem solicitações diferentes para diferentes verbos HTTP na solicitação do cliente.
  • Como desserializar dados JSON da solicitação e usá-los em nosso programa.
Desenvolver esse tipo de programa no Go é muito fácil e não requer pacotes externos ou, pelo menos, não muitos. Se este foi seu primeiro passo no mundo da programação Go, espero que tenha aproveitado e que, se teve alguma experiência anterior com Go, tivesse algo de valor para você.
No próximo artigo desta série, Go e persistiremos os dados que trocamos com o cliente HTTP. Este repositório com todo o código deste artigo e dos próximos para que você possa acompanhar.
Mantenha-se atento. Hackeie seu código. Até a próxima!
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.
Iniciar a conversa

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
{Parte de uma série
Implementando sua API REST no Golang
Mais nesta série
    Relacionado
    Início rápido

    Transações ACID multidocumento no MongoDB com Go


    Apr 03, 2024 | 6 min read
    Tutorial

    Como construir um aplicativo web Go com Gi, MongoDB e AI


    Aug 30, 2024 | 11 min read
    Tutorial

    Criptografia no nível do campo do lado do cliente (CSFLE) no MongoDB com Golang


    Feb 03, 2023 | 15 min read
    Tutorial

    Desenvolvendo skills da Alexa com MongoDB e Golang


    Apr 03, 2024 | 10 min read
    Sumário
    • Noções básicas de HTTP com Go 1.22