generated from isoppp/remix-starter
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from isoppp/hono
Hono basics
- Loading branch information
Showing
19 changed files
with
1,522 additions
and
2,880 deletions.
There are no files selected for viewing
This file contains 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
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
APP_ENV=local | ||
WEBAPP_URL=http://localhost:3000 | ||
|
||
# POSTGRES | ||
POSTGRES_USER=postgres | ||
POSTGRES_PASSWORD=postgres | ||
POSTGRES_DB=mydb | ||
|
||
# `openssl rand -base64 32` | ||
SESSION_SECRET="your-secret" | ||
|
||
DATABASE_URL="postgresql://postgres:postgres@localhost:5455/mydb?schema=public" | ||
|
||
# GCP trace, error, logging | ||
#GOOGLE_CLOUD_PROJECT="experimental-436413" | ||
#GOOGLE_APPLICATION_CREDENTIALS="./src/config/google-credentials.json" |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# dev | ||
.yarn/ | ||
!.yarn/releases | ||
.vscode/* | ||
!.vscode/launch.json | ||
!.vscode/*.code-snippets | ||
.idea/workspace.xml | ||
.idea/usage.statistics.xml | ||
.idea/shelf | ||
|
||
# deps | ||
node_modules/ | ||
|
||
# env | ||
.env | ||
.env.production | ||
|
||
# logs | ||
logs/ | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
pnpm-debug.log* | ||
lerna-debug.log* | ||
|
||
# misc | ||
.DS_Store | ||
|
||
src/config/google-credentials.json |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
save-exact=true |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
``` | ||
npm install | ||
npm run dev | ||
``` | ||
|
||
``` | ||
open http://localhost:3000 | ||
``` |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
{ | ||
"$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", | ||
"files": { | ||
"ignore": ["dist"] | ||
}, | ||
"json": { | ||
"parser": { | ||
"allowComments": true | ||
} | ||
}, | ||
"formatter": { | ||
"enabled": true, | ||
"formatWithErrors": false, | ||
"indentStyle": "space", | ||
"indentWidth": 2, | ||
"lineEnding": "lf", | ||
"lineWidth": 120, | ||
"attributePosition": "auto" | ||
}, | ||
"javascript": { | ||
"formatter": { | ||
"semicolons": "asNeeded", | ||
"quoteStyle": "single", | ||
"jsxQuoteStyle": "single" | ||
} | ||
}, | ||
"organizeImports": { | ||
"enabled": true | ||
}, | ||
"linter": { | ||
"enabled": true, | ||
"rules": { | ||
"recommended": true, | ||
"correctness": { | ||
"noUnusedImports": "error", | ||
"noUnusedVariables": { | ||
"level": "error", | ||
"fix": "none" | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"name": "api-hono", | ||
"scripts": { | ||
"dev": "dotenv -e .env.local -- tsx watch src/index.ts" | ||
}, | ||
"dependencies": { | ||
"@google-cloud/logging-winston": "6.0.0", | ||
"@google-cloud/opentelemetry-cloud-trace-exporter": "2.3.0", | ||
"@hono/node-server": "1.13.1", | ||
"@opentelemetry/api": "1.9.0", | ||
"@opentelemetry/instrumentation-http": "0.53.0", | ||
"@opentelemetry/instrumentation-pino": "0.42.0", | ||
"@opentelemetry/instrumentation-winston": "0.40.0", | ||
"@opentelemetry/sdk-node": "0.53.0", | ||
"@prisma/instrumentation": "5.19.1", | ||
"chalk": "5.3.0", | ||
"dotenv-cli": "7.4.2", | ||
"hono": "4.6.3", | ||
"hono-rate-limiter": "0.4.0", | ||
"tsx": "4.19.1", | ||
"winston": "3.14.2" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "22.6.1" | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { factory } from '@/lib/hono' | ||
import { generalRateLimit } from '@/middlewares/general-rate-limit' | ||
import { httpRedirect } from '@/middlewares/http-redirect' | ||
import { requestSpan } from '@/middlewares/request-span' | ||
import { serve } from '@hono/node-server' | ||
import { compress } from 'hono/compress' | ||
import { cors } from 'hono/cors' | ||
import { logger as requestLogger } from 'hono/logger' | ||
import { requestId } from 'hono/request-id' | ||
import { secureHeaders } from 'hono/secure-headers' | ||
import { logger } from './lib/logger' | ||
import { initOpenTelemetry } from './lib/open-telemetry' | ||
|
||
initOpenTelemetry() | ||
|
||
const newApp = () => { | ||
const app = factory.createApp() | ||
app.use(requestSpan) | ||
app.use( | ||
requestLogger((message: string, ...rest: string[]) => { | ||
logger.info(message, ...rest) | ||
}), | ||
) | ||
app.use(httpRedirect) | ||
app.use(requestId()) | ||
app.use(generalRateLimit) | ||
app.use(cors()) | ||
app.use(secureHeaders({ removePoweredBy: true })) | ||
app.use(compress()) | ||
|
||
app.get('/', (c) => { | ||
return c.text('Hello Hono!') | ||
}) | ||
|
||
return app | ||
} | ||
|
||
const app = newApp() | ||
const port = 3033 | ||
logger.info(`Server is running on port ${port}`) | ||
serve({ | ||
fetch: app.fetch, | ||
port, | ||
}) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import type { EnvHono } from '@/types/hono-context' | ||
import { createFactory } from 'hono/factory' | ||
|
||
export const factory = createFactory<EnvHono>() |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import winston from 'winston' | ||
|
||
// Imports the Google Cloud client library for Winston | ||
import { LoggingWinston } from '@google-cloud/logging-winston' | ||
|
||
const pinoLikeFormat = winston.format.printf(({ level, message, timestamp, ...metadata }) => { | ||
const pid = process.pid | ||
const formattedMessage = `[${timestamp}] ${level.toUpperCase()} (${pid}): ${message}` | ||
return formattedMessage | ||
}) | ||
|
||
export const logger = winston.createLogger({ | ||
level: 'debug', | ||
transports: [ | ||
new winston.transports.Console({ | ||
format: winston.format.combine( | ||
// winston.format.colorize(), | ||
winston.format.timestamp({ | ||
format: 'HH:mm:ss.SSS', | ||
}), | ||
// winston.format.cli(), | ||
pinoLikeFormat, | ||
), | ||
}), | ||
process.env.GOOGLE_APPLICATION_CREDENTIALS | ||
? new LoggingWinston({ | ||
keyFile: process.env.GOOGLE_APPLICATION_CREDENTIALS, | ||
}) | ||
: null, | ||
].filter((v) => !!v), | ||
}) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { TraceExporter } from '@google-cloud/opentelemetry-cloud-trace-exporter' | ||
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http' | ||
import { PinoInstrumentation } from '@opentelemetry/instrumentation-pino' | ||
import { WinstonInstrumentation } from '@opentelemetry/instrumentation-winston' | ||
import { NodeSDK } from '@opentelemetry/sdk-node' | ||
import { PrismaInstrumentation } from '@prisma/instrumentation' | ||
|
||
export const initOpenTelemetry = () => { | ||
if (process.env.GOOGLE_APPLICATION_CREDENTIALS) { | ||
const sdk = new NodeSDK({ | ||
traceExporter: new TraceExporter({ | ||
keyFile: process.env.GOOGLE_APPLICATION_CREDENTIALS, | ||
}), | ||
instrumentations: [ | ||
new HttpInstrumentation(), | ||
new PinoInstrumentation(), | ||
new WinstonInstrumentation(), | ||
new PrismaInstrumentation(), | ||
], | ||
}) | ||
|
||
sdk.start() | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { logger } from '@/lib/logger' | ||
import type { EnvHono } from '@/types/hono-context' | ||
import { getConnInfo } from '@hono/node-server/conninfo' | ||
import { rateLimiter } from 'hono-rate-limiter' | ||
|
||
/** | ||
* rateLimit middleware | ||
* limit 10 req per second per IP address | ||
*/ | ||
export const generalRateLimit = rateLimiter<EnvHono>({ | ||
windowMs: 1000, | ||
limit: 10, | ||
standardHeaders: 'draft-6', | ||
keyGenerator: (c) => { | ||
const info = getConnInfo(c) | ||
const key = [info.remote.address].filter((v) => !!v).join('') || 'unknown' | ||
logger.debug(`Rate limit key: ${key}`) | ||
return key | ||
}, | ||
skipFailedRequests: true, | ||
}) | ||
|
||
// TODO protect auth apis with stronger rate limit |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { factory } from '@/lib/hono' | ||
|
||
export const httpRedirect = factory.createMiddleware(async (c, next) => { | ||
if (c.req.method !== 'GET') return next() | ||
|
||
const proto = c.req.header('X-Forwarded-Proto') | ||
if (proto === 'http') { | ||
const url = new URL(c.req.url) | ||
url.protocol = 'https' | ||
const newUrl = url.href | ||
return c.redirect(newUrl) | ||
} | ||
|
||
await next() | ||
}) |
Oops, something went wrong.