https://github.com/refinist/hono-json-response
🔥 A Hono middleware for standardized JSON responses
https://github.com/refinist/hono-json-response
api framework hono http json middleware response typescript web
Last synced: 3 months ago
JSON representation
🔥 A Hono middleware for standardized JSON responses
- Host: GitHub
- URL: https://github.com/refinist/hono-json-response
- Owner: refinist
- License: mit
- Created: 2025-06-07T16:03:59.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2025-06-08T05:27:40.000Z (4 months ago)
- Last Synced: 2025-07-08T10:37:31.399Z (3 months ago)
- Topics: api, framework, hono, http, json, middleware, response, typescript, web
- Language: TypeScript
- Homepage:
- Size: 59.6 KB
- Stars: 23
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
#
Hono jsonResponse Middleware [](https://npmjs.com/package/hono-json-response) [](https://codecov.io/github/refinist/hono-json-response)
A Hono middleware for standardized JSON responses
## Why Choose This Middleware?
### ❌ Traditional Approach: Repetitive and Error-Prone
```typescript
return c.json({ code: 2000, data: users, msg: 'Operation successful' });
return c.json({ code: 2000, data: roles, msg: 'Operation successful' });
return c.json({ code: 5000, data: null, msg: 'Username already exists' });
return c.json({ code: 5100, data: null, msg: 'System error' });
```### ✅ Using Middleware: Semantic and Concise
```typescript
return c.ok(users, 'Operation successful');
return c.ok(roles); // No need to pass "Operation successful" every time, as it's the default
return c.bizerr(null, 'Username already exists');
return c.syserr();
```## Features
- 🚀 **Unified JSON Response Format** - Standardized API response structure
- 🎯 **Semantic Response Methods** - `c.ok()` is more intuitive than `c.json({code: 2000})`
- 🔧 **Eliminate Boilerplate Code** - Say goodbye to repetitive `c.json({code: xxx, data: xxx, msg: xxx})` patterns
- 📝 **Predefined Common Scenarios** - ok(success), unauth(unauthorized), bizerr(business error), syserr(system error)
- 🛠️ **Flexible Extension** - Support for custom response methods and status codes
- 💪 **Type Safety** - Complete TypeScript support and intelligent hints## Install
```bash
# npm
npm install hono-json-response# yarn
yarn add hono-json-response# pnpm
pnpm add hono-json-response# bun
bun add hono-json-response
```## Basic Usage
```typescript
import { Hono } from 'hono';
import { jsonResponse } from 'hono-json-response';const app = new Hono();
app.use('*', jsonResponse());
app.get('/getUserList', c => {
return c.ok(
{
list: [{ name: 'John' }, { name: 'Jane' }],
totals: 100
},
'Get user list successfully'
);
});
```## Response Format
### Default Format
All responses follow a unified JSON format (code, data, msg):
```json
{
"code": 2000,
"data": null,
"msg": ""
}
```### Custom Field Names
Support custom response field names to adapt to different project API specifications:
```ts
app.use(
'*',
jsonResponse(null, {
code: 'status', // code -> status
data: 'result', // data -> result
msg: 'message' // msg -> message
})
);
```## Predefined Methods
### `c.ok(data?, msg?)`
Success response
- **Status Code**: 2000
- **Usage**: When operation is successful```ts
app.get('/getUserList', c => {
return c.ok(
{
list: [{ name: 'John' }, { name: 'Jane' }],
totals: 100
},
'Get user list successfully'
);
});
```### `c.unauth(data?, msg?)`
Unauthorized response
- **Status Code**: 4000
- **Usage**: When user is not logged in or token is invalid```ts
app.post('/login', c => {
return c.unauth();
});
```### `c.bizerr(data?, msg?)`
Business error response
- **Status Code**: 5000
- **Usage**: Business logic errors (such as duplicate accounts, insufficient inventory, etc.)```ts
app.post('/register', async c => {
const { name } = await c.req.json();
return c.bizerr({ name }, `Username ${name} already exists`);
});
```### `c.syserr(data?, msg?)`
System error response
- **Status Code**: 5100
- **Usage**: System-level errors (such as database connection failure, processing exceptions, etc.)```ts
app.post('/foo', c => {
try {
// do something
} catch (error) {
return c.syserr(error);
}
});
```### `c.jr(code, data?, msg?)`
Custom response code
- **Parameter**: code - Custom status code
- **Usage**: Some complex interfaces may need to return more status codes to represent different business logic```ts
app.get('/orders/:id', async c => {
const orderId = c.req.param('id');try {
const order = await getOrderById(orderId);// Order not found
if (!order) {
return c.jr(5000, null, 'Order not found');
}// No permission to access other user's order
if (order.userId !== userId) {
return c.jr(5001, null, 'No permission to access this order');
}// Order has been deleted
if (order.status === 'deleted') {
return c.jr(5002, null, 'Order has been deleted');
}
// More business logic...return c.ok(order, 'Get order details successfully');
} catch (error) {
return c.syserr(null, 'Failed to get order details');
}
});
```## Custom Configuration
### Override Default Configuration
```typescript
app.use(
'*',
jsonResponse({
ok: { code: 20000, defaultMsg: 'Override ok' },
unauth: { code: 40000, defaultMsg: 'Override unauth' }
})
);
```### Add Custom Methods
```typescript
import type { JSONResponseHandler } from 'hono-json-response';// Don't forget to use TypeScript module augmentation to extend Context type
declare module 'hono' {
interface Context {
warning: JSONResponseHandler;
forbidden: JSONResponseHandler;
}
}app.use(
'*',
jsonResponse({
warning: { code: 2001, defaultMsg: 'Warning message' },
forbidden: { code: 4001, defaultMsg: 'Access forbidden' }
})
);app.get('/warning', c => {
return c.warning(data, 'API will be deprecated');
});
```### Handle Status Code Conflicts
When custom method status codes conflict with default methods, default methods will be automatically removed:
```typescript
app.use(
'*',
jsonResponse({
mySuccess: { code: 2000 } // Conflicts with default ok method
})
);// At this point, c.ok method is no longer available, only c.mySuccess is available
```## License
[MIT](./LICENSE)
Copyright (c) 2025-present, Zhifeng (Jeff) Wang