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 de servidores web do Go. Ela define como as solicitações HTTP são processadas, e qualquer tipo que a implemente pode atender a solicitações da web.

A interface é extremamente simples:

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

Qualquer tipo com um método ServeHTTP pode lidar com solicitaçõ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 manipulador diretamente com um servidor:

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

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

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

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

O poder dessa interface fica claro quando você percebe que os handlers podem envolver outros handlers. Isso possibilita padrões de middleware nos quais você adiciona registro em log, autenticação ou outras preocupações transversais sem modificar a lógica original do handler.

challenge icon

Desafio

Fácil

Vamos criar um sistema simples de manipuladores HTTP que simula como as solicitaçõ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 solicitações trabalhando com objetos simulados de solicitaçã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 escrito 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 os dados ao corpo. Adicione um método Body() string para recuperar a resposta acumulada.

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

    Agora crie duas structs de manipuladores 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 solicitação
    • MethodHandler — escreve respostas diferentes com base no método da solicitação: "Fetching data" para GET, "Creating resource" para POST e "Method not supported" para qualquer outra opção
  • main.go: Processe solicitações por meio dos seus manipuladores.

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

    Crie o manipulador apropriado, construa uma solicitaçã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 solicitação
  • Linha 3: Método da solicitação
  • Linha 4 (somente para welcome): Mensagem de boas-vindas

Por exemplo, considerando:

welcome
/home
GET
Hello from

Sua saída deve ser:

Hello from /home

E considerando:

method
/api/users
POST

Sua saída deve ser:

Creating resource

E considerando:

method
/api/data
GET

Sua saída deve ser:

Fetching data

E considerando:

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 lidar com solicitaçõ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.

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 mock
	request := &MockRequest{
		Path:   path,
		Method: method,
	}
	
	// Criar escritor de resposta mock
	response := &MockResponseWriter{}
	
	// TODO: Com base em handlerType, crie o handler apropriado
	// Se handlerType for "welcome", leia a mensagem de boas-vindas e crie WelcomeHandler
	// Se handlerType for "method", crie MethodHandler
	// Chame ServeHTTP no handler com response e request
	
	if handlerType == "welcome" {
		scanner.Scan()
		message := scanner.Text()
		// TODO: Crie WelcomeHandler com a mensagem e chame ServeHTTP
		_ = message // Remova esta linha ao implementar
	} else if handlerType == "method" {
		// TODO: Crie MethodHandler e chame ServeHTTP
	}
	
	// Imprime 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

Pratique por conta própria: Compilador de Go online