No mundo em rápida evolução do desenvolvimento web, encontrar o framework certo pode ser desafiador. Você deseja algo rápido, leve e flexível o suficiente para funcionar em diferentes ambientes. Apresentamos o Hono – um framework web que está rapidamente ganhando força entre os desenvolvedores por sua velocidade impressionante, tamanho mínimo e design amigável para desenvolvedores.
Hono (que significa "chama" 🔥 em japonês) tem um nome apropriado – é incrivelmente rápido e ilumina sua experiência de desenvolvimento com sua elegância e simplicidade. Seja para construir APIs, microsserviços ou aplicações full-stack, o Hono oferece uma alternativa atraente a frameworks mais pesados.
Este guia irá guiá-lo por tudo o que você precisa saber para começar com o Hono.js, desde a instalação até a construção de sua primeira aplicação e a compreensão de seus conceitos principais.
Quer uma plataforma integrada, All-in-One para sua Equipe de Desenvolvedores trabalharem juntos com máxima produtividade?
Apidog entrega todas as suas demandas, e substitui o Postman por um preço muito mais acessível!
O que é Hono?

Hono é um framework web pequeno, simples e ultrarrápido construído sobre Padrões Web. Ele funciona em praticamente qualquer runtime JavaScript: Cloudflare Workers, Fastly Compute, Deno, Bun, Vercel, Netlify, AWS Lambda, Lambda@Edge e Node.js.
Em sua essência, o Hono adota as APIs de Padrões Web (como Request, Response e Fetch), o que lhe confere uma notável portabilidade entre plataformas. Isso significa que você pode escrever seu código uma vez e implantá-lo em quase qualquer lugar sem grandes modificações.
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hono!'))
export default app
Este exemplo simples demonstra a sintaxe limpa do Hono, inspirada no Express, mas modernizada para o ecossistema JavaScript atual.
Vamos mergulhar!
1. Instalar Hono.js com Bun e Configurar o Projeto
Bun é um runtime JavaScript moderno conhecido por sua velocidade e seu kit de ferramentas tudo-em-um, incluindo um gerenciador de pacotes, bundler e executor de testes. Configurar o Hono com o Bun é simples.
Pré-requisitos
Certifique-se de ter o Bun instalado. Caso contrário, você pode instalá-lo seguindo as instruções no site oficial do Bun.
Criando um Novo Projeto Hono com Bun
A maneira mais rápida de iniciar um novo projeto Hono com Bun é usando a ferramenta de scaffolding create-hono
:
bun create hono@latest my-hono-app
Este comando solicitará que você escolha um template. Para este guia, selecione o template bun
.
? Which template do you want to use? › - Use arrow keys. Return to submit.
❯ bun
cloudflare-workers
cloudflare-pages
deno
fastly
netlify
nodejs
vercel
Após selecionar o template, navegue até o diretório do seu novo projeto e instale as dependências:
cd my-hono-app
bun install
Adicionando Hono a um Projeto Bun Existente
Se você tiver um projeto Bun existente, pode adicionar o Hono como uma dependência:
bun add hono
2. Construindo uma Aplicação Básica com Hono.js: "Hello Hono!"
Vamos criar uma aplicação simples "Hello World" (ou melhor, "Hello Hono!").
Dentro do seu projeto, você deve ter um diretório src
. Crie ou abra src/index.ts
(ou index.js
se preferir JavaScript puro, embora TypeScript seja recomendado para aproveitar todos os benefícios do Hono).
// src/index.ts
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => {
return c.text('Hello Hono!')
})
export default app
Vamos analisar isso:
- Importamos a classe
Hono
do pacotehono
. - Criamos uma nova instância de
Hono
, tipicamente nomeadaapp
. - Definimos uma rota para requisições
GET
no caminho raiz (/
). - O manipulador de rota é uma função que recebe um objeto
Context
(convencionalmentec
) como argumento. c.text('Hello Hono!')
cria um objeto Response com o texto puro "Hello Hono!".- Finalmente, exportamos a instância
app
. Para o Bun, esta exportação padrão é suficiente para o servidor de desenvolvimento detectá-la.
Executando sua Aplicação
Para executar sua aplicação em modo de desenvolvimento, use o script dev
definido no seu package.json
(que o create-hono
configura para você):
bun run dev
Isso geralmente iniciará um servidor em http://localhost:3000
. Abra esta URL no seu navegador web e você deverá ver "Hello Hono!".
Alterando a Porta
Se você precisar executar sua aplicação em uma porta diferente, pode modificar a exportação em src/index.ts
:
// src/index.ts
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => {
return c.text('Hello Hono on port 8080!')
})
export default {
port: 8080, // Especifique a porta desejada
fetch: app.fetch,
}
Agora, ao executar bun run dev
, a aplicação será servida em http://localhost:8080
.
3. Construindo uma API Básica com Hono.js
Hono se destaca na construção de APIs. Vamos explorar roteamento e como lidar com requisições e criar respostas.
Roteamento
O roteamento no Hono é intuitivo. A instância app
possui métodos correspondentes aos verbos HTTP (.get()
, .post()
, .put()
, .delete()
, etc.).
Rota GET Básica
Já vimos uma rota GET básica:
app.get('/hello', (c) => {
return c.text('Hello, world!')
})
Parâmetros de Caminho (Path Parameters)
Você pode definir rotas com parâmetros de caminho usando a sintaxe :paramName
. Esses parâmetros podem ser acessados via c.req.param('paramName')
.
// Exemplo: /users/123
app.get('/users/:id', (c) => {
const userId = c.req.param('id')
return c.text(`User ID: ${userId}`)
})
Parâmetros de Consulta (Query Parameters)
Parâmetros de consulta da URL (por exemplo, /search?q=hono
) podem ser acessados usando c.req.query('queryName')
.
// Exemplo: /search?category=frameworks&limit=10
app.get('/search', (c) => {
const category = c.req.query('category')
const limit = c.req.query('limit')
return c.text(`Searching in category: ${category}, Limit: ${limit}`)
})
Você também pode obter todos os parâmetros de consulta como um objeto com c.req.query()
.
Lidando com Diferentes Métodos HTTP
Hono facilita o tratamento de vários métodos HTTP para o mesmo caminho:
// src/index.ts
import { Hono } from 'hono'
const app = new Hono()
// GET uma lista de posts
app.get('/posts', (c) => {
// Em uma aplicação real, você buscaria isso de um banco de dados
const posts = [
{ id: '1', title: 'Começando com Hono' },
{ id: '2', title: 'Técnicas Avançadas de Hono' },
];
return c.json(posts); // Retorna resposta JSON
})
// GET um único post por ID
app.get('/posts/:id', (c) => {
const id = c.req.param('id')
// Buscar post por ID de um banco de dados
const post = { id: id, title: `Post ${id}`, content: 'Este é o conteúdo...' };
if (!post) {
return c.notFound() // Helper embutido para 404
}
return c.json(post)
})
// CRIAR um novo post
app.post('/posts', async (c) => {
const body = await c.req.json() // Parseia o corpo JSON
// Em uma aplicação real, você salvaria isso em um banco de dados
console.log('Criando post:', body)
return c.json({ message: 'Post criado com sucesso!', data: body }, 201) // Responde com 201 Created
})
// ATUALIZAR um post existente
app.put('/posts/:id', async (c) => {
const id = c.req.param('id')
const body = await c.req.json()
// Atualizar post no banco de dados
console.log(`Atualizando post ${id}:`, body)
return c.json({ message: `Post ${id} atualizado com sucesso!`, data: body })
})
// DELETAR um post
app.delete('/posts/:id', (c) => {
const id = c.req.param('id')
// Deletar post do banco de dados
console.log(`Deletando post ${id}`)
return c.json({ message: `Post ${id} deletado com sucesso!` })
})
export default {
port: 3000,
fetch: app.fetch
}
Objeto Request (c.req
)
O objeto Context
(c
) fornece acesso aos detalhes da requisição via c.req
. Propriedades e métodos chave incluem:
c.req.url
: A string da URL completa.c.req.method
: O método HTTP (por exemplo, 'GET', 'POST').c.req.headers
: Um objeto Headers. Acesse headers comoc.req.header('Content-Type')
.c.req.param('name')
: Obtém um parâmetro de caminho.c.req.query('name')
: Obtém um parâmetro de consulta.c.req.queries('name')
: Obtém todos os valores para um parâmetro de consulta repetido como um array.c.req.json()
: Parseia o corpo da requisição como JSON. (Retorna uma Promise)c.req.text()
: Lê o corpo da requisição como texto puro. (Retorna uma Promise)c.req.arrayBuffer()
: Lê o corpo da requisição como um ArrayBuffer. (Retorna uma Promise)c.req.formData()
: Parseia o corpo da requisição como FormData. (Retorna uma Promise)c.req.valid('type')
: Acessa dados validados (usado com validadores, abordado posteriormente).
Objeto Response (c
) e Helpers
O objeto Context
(c
) também fornece helpers convenientes para criar objetos Response
:
c.text(text, status?, headers?)
: Retorna uma resposta de texto puro.c.json(object, status?, headers?)
: Retorna uma resposta JSON. OContent-Type
é automaticamente definido comoapplication/json
.c.html(html, status?, headers?)
: Retorna uma resposta HTML.c.redirect(location, status?)
: Retorna uma resposta de redirecionamento (status padrão 302).c.notFound()
: Retorna uma resposta 404 Not Found.c.newResponse(body, status?, headers?)
: Cria um novo objetoResponse
.body
pode sernull
,ReadableStream
,ArrayBuffer
,FormData
,URLSearchParams
oustring
.c.header(name, value)
: Define um header de resposta.
Exemplo: Definindo Headers Personalizados
app.get('/custom-header', (c) => {
c.header('X-Powered-By', 'HonoJS-Flame')
c.header('Cache-Control', 'no-cache')
return c.text('Verifique os headers da resposta!')
})
4. Trabalhando com Middleware em Hono.js
Funções de middleware são a base do Hono (e de muitos frameworks web). São funções que podem processar uma requisição antes que ela chegue ao manipulador de rota principal, ou processar uma resposta depois que o manipulador foi executado. Middleware é ótimo para tarefas como logging, autenticação, validação de dados, compressão, CORS e muito mais.
A assinatura básica de uma função de middleware é async (c, next) => { ... }
.
c
: O objeto Context.next
: Uma função a ser chamada para passar o controle para o próximo middleware na cadeia, ou para o manipulador de rota final. Você deve usarawait next()
se quiser que os middlewares subsequentes ou o manipulador sejam executados.
Usando Middleware Embutido
Hono vem com um rico conjunto de middleware embutido. Você pode importá-los de hono/middleware-name
(por exemplo, hono/logger
, hono/cors
).
Para aplicar middleware a todas as rotas, use app.use(middlewareFunction)
.
Para aplicar middleware a rotas específicas, forneça um padrão de caminho como primeiro argumento: app.use('/admin/*', authMiddleware)
.
Exemplo: Middleware Logger e ETag
// src/index.ts
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { etag } from 'hono/etag'
import { prettyJSON } from 'hono/pretty-json' // Para respostas JSON bem formatadas
const app = new Hono()
// Aplicar middleware a todas as rotas
app.use(logger()) // Registra informações de requisição e resposta no console
app.use(etag()) // Adiciona headers ETag para cache
app.use(prettyJSON()) // Formata respostas JSON com indentação
app.get('/', (c) => {
return c.text('Olá com Logger e ETag!')
})
app.get('/data', (c) => {
return c.json({ message: 'Estes são alguns dados.', timestamp: Date.now() })
})
export default app
Ao executar isso e acessar /
ou /data
, você verá logs no seu console e as respostas incluirão um header ETag
. As respostas JSON de /data
serão bem formatadas.
Outros Middleware Embutidos Úteis:
cors
: Lida com Cross-Origin Resource Sharing.basicAuth
: Implementa Autenticação Básica.jwt
: Autenticação JWT (JSON Web Token).compress
: Comprime corpos de resposta.cache
: Implementa cache usando a Cache API.secureHeaders
: Adiciona vários headers HTTP relacionados à segurança.bodyLimit
: Limita o tamanho do corpo da requisição.
Você pode encontrar uma lista completa e documentação nos docs do Hono em "Middleware".
Criando Middleware Personalizado
Você pode facilmente escrever seu próprio middleware.
Exemplo 1: Temporizador Simples de Requisição
// src/index.ts
import { Hono } from 'hono'
import { logger } from 'hono/logger'
const app = new Hono()
app.use(logger())
// Middleware personalizado para medir o tempo de processamento da requisição
app.use(async (c, next) => {
const start = Date.now()
console.log(`Requisição recebida em: ${new Date(start).toISOString()}`)
await next() // Chama o próximo middleware ou manipulador de rota
const ms = Date.now() - start
c.header('X-Response-Time', `${ms}ms`) // Adiciona header personalizado à resposta
console.log(`Requisição processada em ${ms}ms`)
})
app.get('/', (c) => {
return c.text('Olá do Hono com middleware de temporização personalizado!')
})
app.get('/slow', async (c) => {
// Simula uma operação lenta
await new Promise(resolve => setTimeout(resolve, 1500))
return c.text('Esta foi uma resposta lenta.')
})
export default app
Acesse /
e /slow
para ver os logs de temporização e o header X-Response-Time
.
Exemplo 2: Middleware Simples de Autenticação por Chave de API
Este é um exemplo muito básico para demonstração. Em uma aplicação real, use métodos de autenticação mais robustos como JWT ou OAuth, e armazene as chaves de API de forma segura.
// src/index.ts
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { HTTPException } from 'hono/http-exception' // Para lançar erros HTTP padrão
const app = new Hono()
app.use(logger())
const API_KEY = "supersecretapikey"; // Em uma aplicação real, armazene isso de forma segura (ex: variável de ambiente)
// Middleware personalizado de Autenticação por Chave de API
const apiKeyAuth = async (c, next) => {
const apiKeyHeader = c.req.header('X-API-KEY')
if (apiKeyHeader && apiKeyHeader === API_KEY) {
await next()
} else {
// Usando HTTPException para retornar uma resposta de erro padronizada
throw new HTTPException(401, { message: 'Não Autorizado: Chave de API Inválida' })
}
}
// Aplica este middleware a um grupo específico de rotas
app.use('/api/v1/*', apiKeyAuth)
app.get('/api/v1/me', (c) => {
return c.json({ user: 'Usuário Autenticado', email: 'user@example.com' })
})
app.get('/public/info', (c) => {
return c.text('Esta é informação pública, nenhuma chave de API é necessária.')
})
// Manipulador de erros para HTTPException
app.onError((err, c) => {
if (err instanceof HTTPException) {
return err.getResponse()
}
// Para outros erros
console.error('Erro não tratado:', err)
return c.text('Erro Interno do Servidor', 500)
})
export default app
Para testar isso:
curl http://localhost:3000/api/v1/me
(deve retornar 401 Não Autorizado)curl -H "X-API-KEY: supersecretapikey" http://localhost:3000/api/v1/me
(deve retornar dados do usuário)curl http://localhost:3000/public/info
(deve retornar informação pública)
Reutilizando Middleware Personalizado com createMiddleware
Para middleware mais complexo ou reutilizável, você pode defini-lo separadamente usando createMiddleware
de hono/factory
. Isso também ajuda com a inferência de tipo TypeScript.
// src/middlewares/timing.ts
import { createMiddleware } from 'hono/factory'
export const timingMiddleware = createMiddleware(async (c, next) => {
const start = Date.now()
await next()
const ms = Date.now() - start
c.res.headers.set('X-Response-Time', `${ms}ms`) // Nota: c.res.headers.set
console.log(` -> Processado em ${ms}ms`)
})
// src/middlewares/auth.ts
import { createMiddleware } from 'hono/factory'
import { HTTPException } from 'hono/http-exception'
const VALID_API_KEY = "anothersecretkey";
// Tipo para variáveis de ambiente se seu middleware precisar delas
type Env = {
Variables: {
user?: { id: string } // Exemplo: definir dados do usuário após a autenticação
}
// Bindings: { MY_KV_NAMESPACE: KVNamespace } // Exemplo para Cloudflare Workers
}
export const secureApiKeyAuth = createMiddleware<Env>(async (c, next) => {
const apiKey = c.req.header('Authorization')?.replace('Bearer ', '')
if (apiKey === VALID_API_KEY) {
// Opcionalmente, você pode definir variáveis no contexto para manipuladores subsequentes
c.set('user', { id: 'user123' })
await next()
} else {
throw new HTTPException(401, { message: 'Acesso Negado: Chave de API Segura Necessária.'})
}
})
// src/index.ts
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { timingMiddleware } from './middlewares/timing' // Assumindo que estão em uma pasta middlewares
import { secureApiKeyAuth } from './middlewares/auth'
const app = new Hono()
app.use(logger())
app.use(timingMiddleware) // Aplica a todas as rotas
app.get('/', (c) => {
return c.text('Olá do Hono com middleware fatorado!')
})
app.use('/secure/data/*', secureApiKeyAuth) // Aplica apenas a /secure/data/*
app.get('/secure/data/profile', (c) => {
// const user = c.get('user') // Acessa variável definida pelo middleware
return c.json({ profileData: 'Informação de perfil sensível', /*user: user*/ })
})
app.get('/public/data', (c) => {
return c.text('Estes são dados públicos, nenhuma chave é necessária.')
})
// Manipulador de erro geral
app.onError((err, c) => {
if (err instanceof HTTPException) {
return err.getResponse();
}
console.error('Erro:', err.message);
return c.json({ error: 'Erro Interno do Servidor', message: err.message }, 500);
});
export default app
Essa estrutura torna seu middleware mais modular e fácil de testar independentemente.
5. Testando suas Aplicações Hono.js
Hono é projetado para ser facilmente testável. Bun vem com seu próprio executor de testes, bun:test
, que funciona bem com Hono. Você também pode usar outros executores de testes como Vitest.
Usando bun:test
(Básico)
A documentação bun.md
fornece um exemplo básico de teste com bun:test
:
Crie um arquivo de teste, por exemplo, src/index.test.ts
:
// src/index.test.ts
import { describe, expect, it } from 'bun:test'
import app from '.' // Importa sua aplicação de src/index.ts
describe('Testes da Aplicação Hono', () => {
it('Deve retornar 200 OK para GET /', async () => {
const req = new Request('http://localhost/') // A URL base não importa muito aqui
const res = await app.fetch(req)
expect(res.status).toBe(200)
expect(await res.text()).toBe('Hello Hono!') // Ou o que sua rota raiz retornar
})
it('Deve retornar JSON para GET /posts', async () => {
const req = new Request('http://localhost/posts')
const res = await app.fetch(req)
expect(res.status).toBe(200)
const json = await res.json()
expect(json).toBeArray() // Assumindo que /posts retorna um array
// Adicione asserções mais específicas sobre o conteúdo JSON, se necessário
})
it('Deve criar um post para POST /posts', async () => {
const postData = { title: 'Post de Teste', content: 'Este é um teste.' };
const req = new Request('http://localhost/posts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(postData),
});
const res = await app.fetch(req);
expect(res.status).toBe(201); // Espera 201 Created
const jsonResponse = await res.json();
expect(jsonResponse.message).toBe('Post criado com sucesso!');
expect(jsonResponse.data.title).toBe(postData.title);
});
})
Para executar seus testes:
bun test
Ou, se quiser executar um arquivo específico:
bun test src/index.test.ts
Usando o Helper app.request()
Hono fornece um método conveniente app.request()
que simplifica os testes, permitindo que você passe diretamente um caminho e opções, em vez de construir um objeto Request
completo a cada vez. Isso é mostrado em docs/guides/testing.md
.
// src/index.test.ts
import { describe, expect, it } from 'bun:test' // Ou importe de 'vitest'
import app from '.' // Sua instância da aplicação Hono
describe('Aplicação Hono com app.request()', () => {
it('GET / deve retornar "Hello Hono!"', async () => {
const res = await app.request('/')
expect(res.status).toBe(200)
expect(await res.text()).toBe('Hello Hono!') // Ajuste para a sua resposta raiz real
})
it('GET /posts/:id deve retornar um post específico', async () => {
// Assumindo que sua aplicação tem uma rota como app.get('/posts/:id', ...)
// e para este teste, pode retornar { id: '123', title: 'Test Post 123' }
const res = await app.request('/posts/123')
expect(res.status).toBe(200)
const data = await res.json()
expect(data.id).toBe('123')
// expect(data.title).toBe('Post 123') // Ou baseado na lógica da sua aplicação
})
it('POST /posts deve criar um novo post', async () => {
const newPost = { title: 'Meu Novo Post', content: 'Conteúdo incrível aqui.' }
const res = await app.request('/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(newPost),
})
expect(res.status).toBe(201) // Assumindo que seu POST /posts retorna 201
const responseData = await res.json()
expect(responseData.message).toBe('Post criado com sucesso!')
expect(responseData.data.title).toBe(newPost.title)
})
it('GET /api/v1/me sem chave de API deve ser 401', async () => {
// Assumindo que o middleware de chave de API do exemplo anterior está ativo nesta rota
const res = await app.request('/api/v1/me')
expect(res.status).toBe(401)
})
it('GET /api/v1/me com chave de API correta deve ser 200', async () => {
const res = await app.request('/api/v1/me', {
headers: {
'X-API-KEY': 'supersecretapikey' // Use a chave do seu middleware
}
})
expect(res.status).toBe(200)
const data = await res.json();
expect(data.user).toBe('Usuário Autenticado')
})
})
Usando o Helper testClient()
para Teste com Segurança de Tipo
Para uma segurança de tipo ainda melhor, especialmente se você estiver usando as capacidades RPC do Hono ou tiver esquemas de rota bem definidos, Hono fornece um helper testClient
(de hono/testing
). Este cliente é tipado com base nas rotas da sua aplicação Hono, oferecendo autocompletar e verificação de tipo nos seus testes.
Nota Importante para Inferência de Tipo do testClient
:
Para que o testClient
infira os tipos corretamente, você deve definir suas rotas usando métodos encadeados diretamente na instância Hono
(por exemplo, const app = new Hono().get(...).post(...)
) ou exportar o tipo da rota se estiver usando RPC. Se você definir as rotas separadamente (por exemplo, const app = new Hono(); app.get(...)
), a inferência de tipo para testClient
pode ser limitada.
// src/app-for-test-client.ts
// Para demonstrar o testClient, vamos definir uma aplicação com rotas encadeadas
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator' // Exemplo para query params tipados
import { z } from 'zod'
const appWithChainedRoutes = new Hono()
.get('/search',
zValidator('query', z.object({ q: z.string(), limit: z.coerce.number().optional() })),
(c) => {
const { q, limit } = c.req.valid('query')
return c.json({ query: q, limit: limit || 10, results: [`resultado para ${q} 1`, `resultado para ${q} 2`] })
}
)
.post('/submit',
zValidator('json', z.object({ name: z.string(), email: z.string().email() })),
async (c) => {
const data = c.req.valid('json')
return c.json({ message: `Dados recebidos para ${data.name}`, data }, 201)
}
);
export default appWithChainedRoutes;
// src/app-for-test-client.test.ts
import { describe, expect, it } from 'bun:test'
import { testClient } from 'hono/testing'
import appWithChainedRoutes from './app-for-test-client' // Importa a aplicação
describe('Aplicação Hono com testClient', () => {
const client = testClient(appWithChainedRoutes)
it('GET /search deve retornar resultados tipados', async () => {
const res = await client.search.$get({
query: { q: 'hono rocks' }
})
expect(res.status).toBe(200)
const data = await res.json()
expect(data.query).toBe('hono rocks')
expect(data.results.length).toBeGreaterThan(0)
})
it('GET /search com limite deve respeitá-lo', async () => {
const res = await client.search.$get({
query: { q: 'hono com limite', limit: '5' } // Query params são strings inicialmente
})
expect(res.status).toBe(200)
const data = await res.json()
expect(data.limit).toBe(5) // O validador Zod o coagiu para número
})
it('POST /submit deve aceitar dados válidos', async () => {
const payload = { name: 'Usuário de Teste', email: 'test@example.com' }
// Para POST, PUT, etc. com corpo JSON, é client.path.$post({ json: payload })
const res = await client.submit.$post({
json: payload
})
expect(res.status).toBe(201)
const responseData = await res.json()
expect(responseData.message).toBe(`Dados recebidos para ${payload.name}`)
expect(responseData.data.email).toBe(payload.email)
});
it('POST /submit com headers', async () => {
const payload = { name: 'Usuário de Teste Headers', email: 'testheaders@example.com' }
const res = await client.submit.$post({
json: payload
}, {
headers: {
'X-Custom-Test-Header': 'Testing123'
}
})
expect(res.status).toBe(201)
// Você normalmente teria uma rota/middleware que lê este header para verificar
});
})
Para executar este teste, assumindo que você tem @hono/zod-validator
e zod
instalados (bun add @hono/zod-validator zod
):
bun test src/app-for-test-client.test.ts
Este testClient
proporciona uma experiência de desenvolvedor muito mais agradável para testes, especialmente para APIs com esquemas definidos.
Conclusão
Hono oferece uma abordagem nova para o desenvolvimento web com sua combinação de velocidade, design leve e recursos amigáveis para desenvolvedores. Este guia cobriu o básico para você começar, mas há muito mais a explorar:
- Técnicas avançadas de roteamento
- Padrões de middleware mais complexos
- Renderização do lado do servidor com JSX
- Integração com bancos de dados
- APIs estilo RPC com segurança de tipo usando Hono Client
- Implantação em várias plataformas
Ao continuar sua jornada com Hono, consulte a documentação oficial e o repositório de exemplos para informações mais aprofundadas e inspiração.
O cenário do desenvolvimento web está em constante evolução, e Hono representa uma abordagem moderna que abraça os Padrões Web, prioriza o desempenho e funciona em todo o crescente ecossistema de runtimes JavaScript. Seja construindo APIs simples ou aplicações complexas, Hono fornece as ferramentas necessárias sem overhead desnecessário.
Comece pequeno, experimente e veja suas aplicações crescerem com Hono – o framework web leve e ultrarrápido que faz jus ao seu nome flamejante. 🔥
Quer uma plataforma integrada, All-in-One para sua Equipe de Desenvolvedores trabalharem juntos com máxima produtividade?
Apidog entrega todas as suas demandas, e substitui o Postman por um preço muito mais acessível!