Skip to content

Commit

Permalink
Merge pull request #3 from isoppp/api-fastify
Browse files Browse the repository at this point in the history
Api fastify
  • Loading branch information
isoppp authored Sep 24, 2024
2 parents 2e05c71 + f04781f commit 58f4a12
Show file tree
Hide file tree
Showing 24 changed files with 1,432 additions and 45 deletions.
65 changes: 65 additions & 0 deletions apps/api-fastify/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
jspm_packages

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history

# 0x
profile-*

# mac files
.DS_Store

# vim swap files
*.swp

# webstorm
.idea

# vscode
.vscode
*code-workspace

# clinic
profile*
*clinic*
*flamegraph*

# generated code
examples/typescript-server.js
test/types/index.js

# compiled app
dist
23 changes: 23 additions & 0 deletions apps/api-fastify/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Getting Started with [Fastify-CLI](https://www.npmjs.com/package/fastify-cli)
This project was bootstrapped with Fastify-CLI.

## Available Scripts

In the project directory, you can run:

### `npm run dev`

To start the app in dev mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

### `npm start`

For production mode

### `npm run test`

Run the test cases.

## Learn More

To learn Fastify, check out the [Fastify documentation](https://fastify.dev/docs/latest/).
43 changes: 43 additions & 0 deletions apps/api-fastify/biome.jsonc
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"
}
}
}
}
}
52 changes: 52 additions & 0 deletions apps/api-fastify/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"name": "api-fastify",
"version": "1.0.0",
"description": "This project was bootstrapped with Fastify-CLI.",
"main": "app.ts",
"directories": {
"test": "test"
},
"type": "module",
"scripts": {
"test": "npm run build:ts && tsc -p test/tsconfig.json && c8 node --test -r ts-node/register \"test/**/*.ts\"",
"start": "tsx src/app.ts",
"build:ts": "tsc",
"watch:ts": "tsc -w",
"dev": "tsx --watch src/app.ts",
"lint-fix": "pnpm biome check --fix --unsafe"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@fastify/autoload": "^6.0.0",
"@fastify/compress": "8.0.1",
"@fastify/helmet": "12.0.1",
"@fastify/rate-limit": "10.0.1",
"@fastify/sensible": "^6.0.0",
"@google-cloud/logging-winston": "6.0.0",
"@google-cloud/opentelemetry-cloud-trace-exporter": "2.3.0",
"@opentelemetry/instrumentation-fastify": "0.39.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",
"fastify": "^5.0.0",
"fastify-cli": "^7.0.1",
"fastify-plugin": "^5.0.0",
"fastify-winston": "1.0.8",
"helmet": "7.1.0",
"tsx": "4.19.0",
"winston": "3.14.2"
},
"devDependencies": {
"@types/node": "^22.1.0",
"c8": "^10.1.2",
"concurrently": "^9.0.0",
"fastify-tsconfig": "^2.0.0",
"ts-node": "^10.4.0",
"typescript": "^5.2.2"
}
}
54 changes: 54 additions & 0 deletions apps/api-fastify/src/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { logger } from '@/lib/logger'
import type { AutoloadPluginOptions } from '@fastify/autoload'
import chalk from 'chalk'
import type { FastifyPluginAsync, FastifyServerOptions } from 'fastify'
export interface AppOptions extends FastifyServerOptions, Partial<AutoloadPluginOptions> {}
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import AutoLoad from '@fastify/autoload'
import Fastify from 'fastify'
import { initOpenTelemetry } from './lib/open-telemetry'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

// Pass --options via CLI arguments in command to enable these options.
const options: AppOptions = {
logger: false,
}

const app: FastifyPluginAsync<AppOptions> = async (fastify, opts): Promise<void> => {
// Place here your custom code!
initOpenTelemetry()

// Do not touch the following lines
void fastify.register(AutoLoad, {
dir: join(__dirname, 'plugins'),
options: opts,
})

void fastify.register(AutoLoad, {
dir: join(__dirname, 'routes'),
options: opts,
})
}

// アプリケーションを起動する関数
const start = async () => {
const fastify = Fastify(options)
await fastify.register(app)
try {
fastify.listen({ port: 3000, host: '127.0.0.1' }, (err, address) => {
if (err) {
logger.error(err)
} else {
logger.info(chalk.blueBright(`Server listening on ${address}`))
}
})
} catch (err) {
logger.error(err)
process.exit(1)
}
}

await start()
34 changes: 34 additions & 0 deletions apps/api-fastify/src/lib/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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}`
// if (Object.keys(metadata).length > 0) {
// formattedMessage += JSON.stringify(metadata)
// }
return formattedMessage
})

export const logger = winston.createLogger({
level: 'info',
transports: [
new winston.transports.Console({
format: winston.format.combine(
winston.format.timestamp({
format: 'HH:mm:ss.SSS',
}),
winston.format.splat(),
pinoLikeFormat,
),
}),
process.env.GOOGLE_APPLICATION_CREDENTIALS
? new LoggingWinston({
keyFile: process.env.GOOGLE_APPLICATION_CREDENTIALS,
})
: null,
].filter((v) => !!v),
})
26 changes: 26 additions & 0 deletions apps/api-fastify/src/lib/open-telemetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { TraceExporter } from '@google-cloud/opentelemetry-cloud-trace-exporter'
import { FastifyInstrumentation } from '@opentelemetry/instrumentation-fastify'
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 p 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 FastifyInstrumentation(),
new HttpInstrumentation(),
new PinoInstrumentation(),
new WinstonInstrumentation(),
new p.PrismaInstrumentation(),
],
})

sdk.start()
}
}
16 changes: 16 additions & 0 deletions apps/api-fastify/src/plugins/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Plugins Folder

Plugins define behavior that is common to all the routes in your
application. Authentication, caching, templates, and all the other cross
cutting concerns should be handled by plugins placed in this folder.

Files in this folder are typically defined through the
[`fastify-plugin`](https://github.com/fastify/fastify-plugin) module,
making them non-encapsulated. They can define decorators and set hooks
that will then be used in the rest of your application.

Check out:

* [The hitchhiker's guide to plugins](https://fastify.dev/docs/latest/Guides/Plugins-Guide/)
* [Fastify decorators](https://fastify.dev/docs/latest/Reference/Decorators/).
* [Fastify lifecycle](https://fastify.dev/docs/latest/Reference/Lifecycle/).
10 changes: 10 additions & 0 deletions apps/api-fastify/src/plugins/compress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import fastifyCompress from '@fastify/compress'
import type { FastifyPluginAsync } from 'fastify'
// plugins/compress.ts
import fp from 'fastify-plugin'

const compressPlugin: FastifyPluginAsync = async (fastify, opts) => {
fastify.register(fastifyCompress, opts)
}

export default fp(compressPlugin)
15 changes: 15 additions & 0 deletions apps/api-fastify/src/plugins/http-redirect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { FastifyPluginAsync } from 'fastify'
// plugins/httpsRedirect.ts
import fp from 'fastify-plugin'

const httpsRedirectPlugin: FastifyPluginAsync = async (fastify) => {
fastify.addHook('onRequest', (request, reply, done) => {
if (request.headers['x-forwarded-proto'] === 'http') {
reply.redirect(`https://${request.hostname}${request.url}`)
} else {
done()
}
})
}

export default fp(httpsRedirectPlugin)
8 changes: 8 additions & 0 deletions apps/api-fastify/src/plugins/rate-limit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { FastifyPluginAsync } from 'fastify'
import fp from 'fastify-plugin'

const rateLimitPlugin: FastifyPluginAsync = async () => {
// TODO
}

export default fp(rateLimitPlugin)
Loading

0 comments on commit 58f4a12

Please sign in to comment.