Skip to content

Filosofia

O design do Kori é guiado por um conjunto pequeno de princípios. Entendê-los ajuda a explicar por que a API tem a forma que tem e quais tradeoffs foram feitos deliberadamente.

Explícito ao invés de mágico

O net/http do Go é explícito por design. O Kori preserva isso.

Todo handler Kori tem a mesma assinatura:

go
func(w http.ResponseWriter, r *http.Request) error

Não há injeção de contexto, nenhum tipo Context customizado, nenhum wrapper de requisição/resposta. O w e o r que você já conhece continuam sendo a única forma de ler a requisição e escrever a resposta.

Isso significa que qualquer desenvolvedor Go pode ler um handler Kori sem aprender novas abstrações, e qualquer ferramenta compatível com net/http — middlewares, test helpers, bibliotecas de tracing — continua funcionando sem alterações.

Construído sobre padrões

O Kori não reinventa o que já existe. Ele conecta peças existentes e bem mantidas:

CamadaFornecida por
Servidor HTTP e interface de handlernet/http (stdlib)
Roteamento e middlewareChi
Validação de structsgo-playground/validator
Geração de spec OpenAPI 3.1kori/openapi

Cada dependência foi escolhida por ser estável, idiomática e já amplamente usada no ecossistema Go. O trabalho do Kori é conectá-las de forma limpa, não substituí-las.

Pequeno e focado

O Kori evita deliberadamente se tornar um framework full-stack.

Ele não é:

  • um ORM ou camada de banco de dados
  • um container de injeção de dependência
  • um carregador de configuração
  • um runtime HTTP customizado
  • um framework monolítico que controla o ciclo de vida da aplicação

A superfície de API é intencionalmente pequena. Um toolkit menor é mais fácil de entender, mais fácil de atualizar e mais fácil de abandonar caso seus requisitos mudem.

Composável

Cada feature do Kori pode ser adotada de forma independente. Não há etapa de inicialização obrigatória nem estado global que precise ser configurado antes de o restante funcionar.

Você pode usar:

  • Apenas bindingBindJSON, BindQuery, BindPath em qualquer *http.Request
  • Apenas validação — a validação roda automaticamente dentro de cada chamada Bind*
  • Apenas helpers de respostaJSON, Text, NoContent em qualquer http.ResponseWriter
  • Apenas helpers de erroNotFound, BadRequest, Conflict e o tipo HTTPError funcionam de forma independente
  • Apenas OpenAPIkori/openapi é um módulo separado; ele só adiciona o que você importar
  • Apenas SSENewSSEWriter funciona com qualquer handler

Você não é obrigado a adotar uma estrutura de projeto específica nem a inicializar um objeto de aplicação central. As funções do Kori são funções simples — chame as que precisar.

Extensível via Options

O ponto de extensão do Kori é o tipo Option:

go
type Option func(*RouteInfo)

Uma Option recebe o método e o padrão da rota sendo registrada. É assim que o kori/openapi anexa metadados OpenAPI — como uma Option passada no momento do registro da rota — sem nenhuma etapa de registro separada.

Você pode escrever sua própria Option para logging de rotas, metadados de permissão ou qualquer outra preocupação transversal:

go
func LogRoute(log *slog.Logger) kori.Option {
    return func(ri *kori.RouteInfo) {
        log.Info("route registered",
            "method", ri.Method,
            "pattern", ri.Pattern,
        )
    }
}

kori.GET(r, "/users", listUsers, LogRoute(log))

Options se compõem naturalmente — passe quantas precisar, em qualquer ordem.