Last active
June 9, 2025 06:43
-
-
Save hivelogic2018/dfec552efeb3df1bdca33499d7932094 to your computer and use it in GitHub Desktop.
Hono
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// Project Structure for Option 1 (Hono as Entry Point with Nuxt as SSR Client) | |
| // | |
| // This structure supports: | |
| // - Hono as the API Gateway and Orchestration Layer | |
| // - Nuxt as an SSR Vue frontend (deployed as a separate client or proxied route) | |
| // - MongoDB + Mongoose integration | |
| // - GraphQL endpoint | |
| // - Temporal or message queue support via orchestration hooks | |
| // Updated File Structure: | |
| // hono-api-platform/ | |
| // ├── api/ | |
| // │ ├── controllers/ | |
| // │ │ └── todoController.ts | |
| // │ ├── db/ | |
| // │ │ └── mongoose.ts | |
| // │ ├── graphql/ | |
| // │ │ ├── resolvers.ts | |
| // │ │ └── schema.ts | |
| // │ ├── models/ | |
| // │ │ └── Todo.ts | |
| // │ ├── orchestration/ | |
| // │ │ └── temporalClient.ts | |
| // │ ├── routes/ | |
| // │ │ └── index.ts | |
| // │ ├── server.ts | |
| // │ ├── swagger.json | |
| // ├── web/ (Nuxt SSR frontend project) | |
| // ├── docker-compose.yml | |
| // ├── package.json (root-level for both Hono + Nuxt workspace) | |
| // Explanation: | |
| // - "api/" houses your Hono server, GraphQL, DB, and orchestration logic. | |
| // - "web/" is your Nuxt SSR project — this fetches data from /api endpoints. | |
| // - Requests from the client go through Hono first. If they're SSR routes, Hono proxies them to Nuxt. | |
| // - Temporal hooks are invoked inside Hono controllers or service layers. | |
| // --- Diagram --- | |
| // | |
| // [Browser] ──────> [Hono (API Gateway)] ─────> [REST Controllers] ─────> [MongoDB] | |
| // │ │ └──> [Temporal Workflows] | |
| // │ ├──────> [GraphQL Resolvers] ─────> [MongoDB] | |
| // │ └──────> [SSR Proxy to Nuxt App] | |
| // │ │ | |
| // └────────────────────────<── SSR HTML page from Nuxt | |
| // --- Layman Explanation --- | |
| // Think of Hono as your smart receptionist: | |
| // - It handles all client requests: "Are you booking? Want to see appointments? Want UI?" | |
| // - If it's a REST or GraphQL question, it answers from its backend logic (MongoDB, workflows). | |
| // - If it’s a request to render a page, it asks Nuxt to render that SSR Vue page. | |
| // - This setup lets Hono manage complex operations (like Temporal flows) while Nuxt just builds pages. | |
| // --- Project Scaffold --- | |
| // This is already partially implemented in the current canvas (Hono setup). | |
| // You’ll need to add: | |
| // 1. Create a `web/` folder and scaffold a Nuxt 3 SSR app. | |
| // 2. Inside Hono, proxy `/app/*` to Nuxt (if Nuxt runs on localhost:3001). | |
| // 3. Add docker-compose.yml to orchestrate services. | |
| // Example: api/server.ts (proxy to Nuxt) | |
| // app.get('/app/*', async (c) => { | |
| // const res = await fetch(`http://localhost:3001${c.req.url}`) | |
| // return new Response(await res.text(), res) | |
| // }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// Project Structure: | |
| // hono-mongo-graphql-api/ | |
| // ├── src/ | |
| // │ ├── controllers/ | |
| // │ │ └── todoController.ts | |
| // │ ├── db/ | |
| // │ │ └── mongoose.ts | |
| // │ ├── graphql/ | |
| // │ │ ├── resolvers.ts | |
| // │ │ └── schema.ts | |
| // │ ├── models/ | |
| // │ │ └── Todo.ts | |
| // │ ├── routes/ | |
| // │ │ └── index.ts (auto-generated) | |
| // │ ├── server.ts | |
| // ├── dist/ (generated) | |
| // ├── tsoa.json | |
| // ├── tsconfig.json | |
| // ├── package.json | |
| // --- src/db/mongoose.ts --- | |
| import mongoose from 'mongoose' | |
| export const connectDB = async () => { | |
| await mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost:27017/todos') | |
| console.log('MongoDB connected') | |
| } | |
| // --- src/models/Todo.ts --- | |
| import mongoose from 'mongoose' | |
| const TodoSchema = new mongoose.Schema({ | |
| title: { type: String, required: true }, | |
| completed: { type: Boolean, default: false }, | |
| }) | |
| export const TodoModel = mongoose.model('Todo', TodoSchema) | |
| // --- src/controllers/todoController.ts --- | |
| import { Controller, Get, Post, Put, Patch, Delete, Route, Tags, Body, Path } from 'tsoa' | |
| import { TodoModel } from '../models/Todo' | |
| interface TodoInput { | |
| title: string | |
| } | |
| @Route('todos') | |
| @Tags('Todo') | |
| export class TodoController extends Controller { | |
| @Get('/') | |
| async getTodos() { | |
| return TodoModel.find() | |
| } | |
| @Post('/') | |
| async createTodo(@Body() body: TodoInput) { | |
| return TodoModel.create(body) | |
| } | |
| @Put('{id}') | |
| async replaceTodo(@Path() id: string, @Body() body: TodoInput) { | |
| return TodoModel.findByIdAndUpdate(id, body, { new: true, overwrite: true }) | |
| } | |
| @Patch('{id}') | |
| async updateTodo(@Path() id: string, @Body() body: Partial<TodoInput>) { | |
| return TodoModel.findByIdAndUpdate(id, body, { new: true }) | |
| } | |
| @Delete('{id}') | |
| async deleteTodo(@Path() id: string) { | |
| return TodoModel.findByIdAndDelete(id) | |
| } | |
| } | |
| // --- src/graphql/schema.ts --- | |
| import { gql } from 'graphql-tag' | |
| export const typeDefs = gql` | |
| type Todo { | |
| id: ID! | |
| title: String! | |
| completed: Boolean! | |
| } | |
| type Query { | |
| todos: [Todo!]! | |
| } | |
| type Mutation { | |
| createTodo(title: String!): Todo | |
| } | |
| ` | |
| // --- src/graphql/resolvers.ts --- | |
| import { TodoModel } from '../models/Todo' | |
| export const resolvers = { | |
| Query: { | |
| todos: async () => await TodoModel.find(), | |
| }, | |
| Mutation: { | |
| createTodo: async (_: any, { title }: { title: string }) => await TodoModel.create({ title }), | |
| }, | |
| } | |
| // --- src/server.ts --- | |
| import { Hono } from 'hono' | |
| import { serve } from '@hono/node-server' | |
| import { RegisterRoutes } from './routes' | |
| import { swaggerUI } from '@hono/swagger-ui' | |
| import { connectDB } from './db/mongoose' | |
| import { graphqlServer } from '@hono/graphql-server' | |
| import { typeDefs } from './graphql/schema' | |
| import { resolvers } from './graphql/resolvers' | |
| import 'dotenv/config' | |
| const app = new Hono() | |
| RegisterRoutes(app) | |
| app.get('/docs', swaggerUI({ url: '/swagger.json' })) | |
| app.route('/graphql', graphqlServer({ typeDefs, resolvers })) | |
| connectDB().then(() => { | |
| serve(app) | |
| }) | |
| // --- tsoa.json --- | |
| { | |
| "entryFile": "src/server.ts", | |
| "noImplicitAdditionalProperties": "throw-on-extras", | |
| "controllerPathGlobs": ["src/controllers/*.ts"], | |
| "spec": { | |
| "outputDirectory": "dist", | |
| "specVersion": 3, | |
| "basePath": "/", | |
| "outputFile": "swagger.json" | |
| }, | |
| "routes": { | |
| "routesDir": "src/routes", | |
| "middleware": "hono" | |
| } | |
| } | |
| // --- tsconfig.json --- | |
| { | |
| "compilerOptions": { | |
| "target": "ES2020", | |
| "module": "CommonJS", | |
| "moduleResolution": "node", | |
| "outDir": "dist", | |
| "rootDir": "src", | |
| "esModuleInterop": true, | |
| "strict": true | |
| }, | |
| "include": ["src"] | |
| } | |
| // --- package.json --- | |
| { | |
| "name": "hono-mongo-graphql-api", | |
| "type": "module", | |
| "scripts": { | |
| "dev": "ts-node src/server.ts", | |
| "build": "npx tsc && npx tsoa routes && npx tsoa spec" | |
| }, | |
| "dependencies": { | |
| "@hono/graphql-server": "^1.0.0", | |
| "@hono/node-server": "^1.0.0", | |
| "@hono/swagger-ui": "^1.0.0", | |
| "dotenv": "^16.0.0", | |
| "graphql": "^16.0.0", | |
| "graphql-tag": "^2.12.6", | |
| "hono": "^3.0.0", | |
| "mongoose": "^7.0.0", | |
| "tsoa": "^4.0.0" | |
| }, | |
| "devDependencies": { | |
| "@types/node": "^20.0.0", | |
| "ts-node": "^10.0.0", | |
| "typescript": "^5.0.0" | |
| } | |
| } |
Author
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://github.com/unjs/jiti
Seamless TypeScript and ESM syntax support for Node.js
Seamless interoperability between ESM and CommonJS
Asynchronous API to replace import()
Synchronous API to replace require() (deprecated)
Super slim and zero dependency
Custom resolve aliases
Smart syntax detection to avoid extra transforms
Node.js native require.cache integration
Filesystem transpile with hard disk caches
ESM Loader support
JSX support (opt-in)
Source: https://eslint.org/docs/latest/use/configure/configuration-files