Menu
Coddy logo textTech

Interface http.Handler

Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy — lição 77 de 107.

A interface http.Handler é a base da arquitetura do servidor web de Go. Ela define como as requisições HTTP são processadas, e qualquer tipo que a implemente pode atender a requisições web.

A interface é notavelmente simples:

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

Qualquer tipo com um método ServeHTTP pode lidar com requisições HTTP. Aqui está um manipulador personalizado:

type GreetHandler struct {
    Greeting string
}

func (h GreetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%s, visitor!", h.Greeting)
}

Você pode usar este handler diretamente com um servidor:

handler := GreetHandler{Greeting: "Welcome"}
http.Handle("/greet", handler)

Para casos mais simples, o Go fornece o http.HandlerFunc, um tipo que permite converter uma função comum em um handler:

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello!")
}

http.Handle("/hello", http.HandlerFunc(hello))

O poder desta interface torna-se claro quando você percebe que handlers podem envolver outros handlers. Isso possibilita padrões de middleware onde você adiciona logging, autenticação ou outras preocupações transversais sem modificar a lógica original do handler.

challenge icon

Desafio

Fácil

Vamos construir um sistema simples de manipulador HTTP que simula como as requisições web são processadas! Como não podemos executar um servidor HTTP real neste ambiente, você criará manipuladores que implementam a interface http.Handler e demonstrará como eles processam requisições trabalhando com objetos simulados (mock) de requisição/resposta.

Você organizará seu código em dois arquivos:

  • handlers.go: Defina seus manipuladores HTTP personalizados.

    Crie uma struct MockResponseWriter que capture o que seria gravado em uma resposta HTTP. Ela deve armazenar o corpo da resposta como uma string e implementar um método Write(data []byte) (int, error) que anexa dados ao corpo. Adicione um método Body() string para recuperar a resposta acumulada.

    Crie uma struct MockRequest com os campos de string Path e Method para simular uma requisição HTTP.

    Agora crie duas structs de manipulador que implementem o padrão da interface http.Handler (com um método ServeHTTP que recebe um *MockResponseWriter e um *MockRequest):

    • WelcomeHandler com um campo Message - escreve a mensagem seguida pelo caminho da requisição
    • MethodHandler - escreve diferentes respostas com base no método da requisição: "Fetching data" para GET, "Creating resource" para POST, e "Method not supported" para qualquer outra coisa
  • main.go: Processe as requisições através dos seus manipuladores.

    Leia um tipo de manipulador (welcome ou method) e, em seguida, leia os detalhes da requisição. Para o manipulador de boas-vindas, leia também a mensagem de boas-vindas.

    Crie o manipulador apropriado, construa uma requisição simulada e chame ServeHTTP para processá-la. Imprima o corpo da resposta.

As seguintes entradas serão fornecidas:

  • Linha 1: Tipo de manipulador (welcome ou method)
  • Linha 2: Caminho da requisição
  • Linha 3: Método da requisição
  • Linha 4 (apenas para welcome): Mensagem de boas-vindas

Por exemplo, dado:

welcome
/home
GET
Hello from

Sua saída deve ser:

Hello from /home

E dado:

method
/api/users
POST

Sua saída deve ser:

Creating resource

E dado:

method
/api/data
GET

Sua saída deve ser:

Fetching data

E dado:

method
/api/items
DELETE

Sua saída deve ser:

Method not supported

Este desafio demonstra o conceito central da interface http.Handler—qualquer tipo com um método ServeHTTP pode manipular requisições. Em aplicações reais, o http.ResponseWriter e o *http.Request vêm da biblioteca padrão do Go, mas o padrão de implementação dos manipuladores permanece exatamente o mesmo.

Folha de consulta

A interface http.Handler é a base da arquitetura do servidor web de Go:

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

Qualquer tipo com um método ServeHTTP pode processar requisições HTTP:

type GreetHandler struct {
    Greeting string
}

func (h GreetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%s, visitor!", h.Greeting)
}

Registre um handler no servidor:

handler := GreetHandler{Greeting: "Welcome"}
http.Handle("/greet", handler)

Para casos mais simples, use http.HandlerFunc para converter uma função em um handler:

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello!")
}

http.Handle("/hello", http.HandlerFunc(hello))

Handlers podem envolver outros handlers, permitindo padrões de middleware para logging, autenticação ou outras preocupações transversais.

Experimente você mesmo

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Ler o tipo de handler
	scanner.Scan()
	handlerType := scanner.Text()
	
	// Ler o caminho da requisição
	scanner.Scan()
	path := scanner.Text()
	
	// Ler o método da requisição
	scanner.Scan()
	method := scanner.Text()
	
	// Criar requisição simulada (mock)
	request := &MockRequest{
		Path:   path,
		Method: method,
	}
	
	// Criar gravador de resposta simulado (mock)
	response := &MockResponseWriter{}
	
	// TODO: Com base no handlerType, criar o handler apropriado
	// Se handlerType for "welcome", ler a mensagem de boas-vindas e criar WelcomeHandler
	// Se handlerType for "method", criar MethodHandler
	// Chamar ServeHTTP no handler com response e request
	
	if handlerType == "welcome" {
		scanner.Scan()
		message := scanner.Text()
		// TODO: Criar WelcomeHandler com a mensagem e chamar ServeHTTP
		_ = message // Remova esta linha ao implementar
	} else if handlerType == "method" {
		// TODO: Criar MethodHandler e chamar ServeHTTP
	}
	
	// Imprimir o corpo da resposta
	fmt.Println(response.Body())
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos