O pacote net/http

Você provavelmente já ouviu falar que Go é fantástico para a construção de aplicações web de todas as formas e tamanhos. Isto é em parte devido ao fantástico trabalho que tem sido colocado em fazer a biblioteca padrão limpa, consistente e fácil de usar.

Talvez um dos pacotes mais importantes para qualquer desenvolvedor web Go novato é o pacote net/http. Este pacote permite que você construa servidores HTTP em Go com as suas poderosas construções composicionais. Antes de começar a codificação, vamos fazer uma visão geral extremamente rápida sobre HTTP.

HTTP Básico

Quando nós falamos sobre aplicações web, geralmente significa que estamos construindo servidores HTTP. HTTP é um protocolo que foi originalmente concebido para transportar documentos HTML de um servidor para um cliente navegador web. Hoje em dia, HTTP é usado para transportar muito mais do que HTML.

A coisa importante a notar neste diagrama é os dois pontos de interação entre a Server e Navegador. O Navegador faz uma solicitação HTTP com algumas informações, o Server, em seguida, processa esse pedido e retorna uma Resposta.

Este padrão de requisição-resposta é um dos pontos chave focais na contrução de aplicações web em Go. Na verdade, a peça mais importante do pacote net/http é a Interface http.Handler.

A Interface http.Handler

Quando você se tornar mais familiar com Go, você irá notar o quanto interfaces criam impacto no design de seus programas. A interface net/http encapsula o padrão de requisição-resposta em um método:

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

Implementadores desta interface são esperados para inspecionar e processar dados vindos do objeto http.Request e escrever uma resposta para o objeto http.ResponseWriter.

A interface http.ResponseWriter parece com isso:

type ResponseWriter interface {
    Header() Header
    Write([]byte) (int, error)
    WriteHeader(int)
}

Compondo Web Services

Como grande parte do pacote net/http é construído fora de tipos de uma interface bem definida nós podemos (e devemos) construir nossa aplicação web com esta composição em mente. Cada implementação http.Handler pode ser pensada como seu próprio servidor web.

Muitos padrões podem ser achados nesta simples mas poderosa suposição. Ao longo deste livro, vamos cobrir alguns desses padrões e como podemos usá-los para resolver problemas do mundo real.

Exercício: 1 Line File Server

Vamos resolver um problema do mundo real em uma linha de código.

Há muito tempo pessoas precisavam servir apenas arquivos estáticos. Pode ser que você tenha uma landing page estática em HTML e quer apenas servir HTML, imagens, e CSS e chamar isto um dia. Verdade, você poderia colocar no Apache ou no SimpleHTTPServer do Python, mas Apache é muito para este pequeno site e SimpleHTTPServer é, assim, muito lento.

Nós iremos iniciar criando um novo projeto em nosso GOPATH.

cd GOPATH/src
mkdir fileserver && cd fileserver

Crie um main.go com nosso típico padrão go.

package main

import "net/http"

func main() {
}

Todos nós precisamos importar o pacote net/http para este trabalho. Lembre-se que tudo isto faz parte da biblioteca padrão em Go

Vamos escrever nosso código fileserver:

http.ListenAndServe(":8080", http.FileServer(http.Dir(".")))

A função http.ListenAndServe é usada para iniciar o servidor, ele se ligará ao endereço que nós demos (:8080) e quando este receber uma requisição HTTP, ele vai entregá-lo ao http.Handler que nós fornecemos como segundo argumento. Em nosso caso é o http.FileServer.

A função http.FileServer constrói uma http.Handler que irá servir um diretório inteiro de arquivos e descobrir qual arquivo para saque com base no caminho da solicitação. Nós dissemos para o FileServer servir o diretório de trabalho atual com http.Dir(".").

O programa completo fica assim:

package main

import "net/http"

func main() {
    http.ListenAndServe(":8080", http.FileServer(http.Dir(".")))
}

Vamos construir e rodar nosso programa fileserver:

go build
./fileserver

Se visitar localhost:8080/main.go devemos ver o conteúdo do nosso arquivo main.go em nosso navegador web. Podemos executar este programa a partir de qualquer diretório e servir a árvore como um servidor de arquivo estático. Tudo em uma linha de código Go.