Skip to content

Instantly share code, notes, and snippets.

@kkeeth
Created August 14, 2025 05:34
Show Gist options
  • Save kkeeth/aeb5402c8423ca67e21acd03ad78387e to your computer and use it in GitHub Desktop.
Save kkeeth/aeb5402c8423ca67e21acd03ad78387e to your computer and use it in GitHub Desktop.
hello hono
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { logger } from 'hono/logger';
import { serve } from '@hono/node-server';
const app = new Hono();
// ミドルウェア設定
app.use('*', logger());
app.use('*', cors());
// バリデーション用のヘルパー関数
const validateRequestBody = (body) => {
if (!body || typeof body !== 'object') {
return { isValid: false, error: 'Request body must be a JSON object' };
}
if (!body.name || typeof body.name !== 'string') {
return { isValid: false, error: 'Name field is required and must be a string' };
}
if (body.name.trim() === '') {
return { isValid: false, error: 'Name cannot be empty' };
}
return { isValid: true, name: body.name.trim() };
};
// ヘルスチェック用エンドポイント
app.get('/', (c) => {
return c.json({
message: 'Greeting API Server is running!',
endpoints: {
greet: 'POST /greet',
goodbye: 'POST /goodbye'
},
timestamp: new Date().toISOString()
});
});
// greet ハンドラ
app.post('/greet', async (c) => {
try {
const body = await c.req.json();
const validation = validateRequestBody(body);
if (!validation.isValid) {
return c.json(
{ error: validation.error },
400
);
}
const greeting = `Hello ${validation.name}`;
return c.json({
greet: greeting
});
} catch (error) {
console.error('Error in /greet handler:', error);
// JSONパースエラーの場合
if (error instanceof SyntaxError) {
return c.json(
{ error: 'Invalid JSON in request body' },
400
);
}
return c.json(
{ error: 'Internal server error' },
500
);
}
});
// goodbye ハンドラ
app.post('/goodbye', async (c) => {
try {
const body = await c.req.json();
const validation = validateRequestBody(body);
if (!validation.isValid) {
return c.json(
{ error: validation.error },
400
);
}
const farewell = `Goodbye ${validation.name}`;
return c.json({
goodbye: farewell
});
} catch (error) {
console.error('Error in /goodbye handler:', error);
// JSONパースエラーの場合
if (error instanceof SyntaxError) {
return c.json(
{ error: 'Invalid JSON in request body' },
400
);
}
return c.json(
{ error: 'Internal server error' },
500
);
}
});
// 404エラーハンドラ
app.notFound((c) => {
return c.json(
{
error: 'Not Found',
message: 'The requested endpoint does not exist',
availableEndpoints: ['/greet', '/goodbye']
},
404
);
});
// グローバルエラーハンドラ
app.onError((err, c) => {
console.error('Unhandled error:', err);
return c.json(
{ error: 'Internal Server Error' },
500
);
});
// サーバー起動と継続実行
const port = 8000;
console.log(`🚀 Starting server on port ${port}...`);
// Honoサーバーを継続起動
serve({
fetch: app.fetch,
port: port,
}, (info) => {
console.log(`✅ Server is running on http://localhost:${info.port}`);
console.log('Available endpoints:');
console.log(' GET / - Health check');
console.log(' POST /greet - Greeting message');
console.log(' POST /goodbye - Farewell message');
console.log('Press Ctrl+C to stop the server');
});
// Graceful shutdown
process.on('SIGINT', () => {
console.log('\n👋 Received SIGINT. Gracefully shutting down...');
process.exit(0);
});
process.on('SIGTERM', () => {
console.log('\n👋 Received SIGTERM. Gracefully shutting down...');
process.exit(0);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment