Nuxt3 — установить соединение с базой данных в промежуточном программном обеспечении сервера

Я учусь использовать Nuxt и в настоящее время пробую nuxt-bridge, который поставляется с большинством функций Nuxt3, сохраняя при этом модуль nuxt-auth-next, который мне нужен. На данный момент я работаю над своим API, используя Nuxt3./server/apiи/server/middlewareкаталоги. Все работаетnuxi/nitro.

Это небольшой пример маршрута API (/server/api/me.get.ts: получает информацию о пользователе из токена JWT, код здесь упрощен):

      // /server/api/me.get.ts
import mysql, { RowDataPacket } from 'mysql2/promise'
import { defineEventHandler, getRequestHeader } from 'h3' // Needed since nuxt-bridge wont auto import dependencies in /server/...
import { useRuntimeConfig } from '#imports' // fails but code still works... ESM absolute path needed

export default defineEventHandler(async (event) => {
  const config = useRuntimeConfig()

  try {
    const db = await mysql.createPool(config.mysql)
    // ... Core route logic : getting user info from token and sending it back
  } catch (e) {
    // Managing error
}
})

Это действительно работает так, как задумано. Моя проблема в том, что я использую один и тот же код для установления соединения MySQL на каждом маршруте (login.post.ts,register.post.ts...), что излишне и не совсем элегантно. Затем я хотел бы использовать serverMiddleware для установления соединения для каждого маршрута.Итак, прежде всего, это правильная практика/использование serverMiddleware?

Затем у меня возникают проблемы с поиском того , как правильно этого добиться. я создал/server/middleware/database.tsкоторый запускается каждый раз, когда делается вызов API. Но я понятия не имею, как установить с него соединение mysql и передать его на фактически вызываемый маршрут. Я попытался возиться с запросом/ответом следующим образом (см. в учебнике):

      // /server/middleware/database.ts
import type { IncomingMessage, ServerResponse } from 'http'
import mysql from 'mysql2/promise'
import { defineHandler } from 'h3' // Needed since nuxt-bridge wont auto import dependencies
import { useRuntimeConfig } from '#imports' // fails but code still works... ESM absolute path needed

export default defineHandler(
  async (req: IncomingMessage, res: ServerResponse) => {
    const config = useRuntimeConfig()

    try {
      req['db'] = await mysql.createPool(config.mysql)
    } catch (e) {
      console.log('error')
    }
  }
)

А затем использовать его так:

      // /server/api/test.get.ts
import type { IncomingMessage, ServerResponse } from 'http'
import { defineHandler } from 'h3' // Needed since nuxt-bridge wont auto import dependencies
import { useRuntimeConfig } from '#imports' // fails but code still works... ESM absolute path needed

export default defineHandler(
  async (req: IncomingMessage, res: ServerResponse) => {
    const [test] = req['db'].query('SELECT * FROM users')
    // Core logic
  }
)

Но это не работает. Я застрял :). Обратите внимание, что с тех пор, как я использовал Javascript, прошло довольно много времени, и это мои первые шаги в Typescript.

Любая помощь будет принята с благодарностью.

1 ответ

У меня та же проблема, и вот мое первое рабочее решение:

Создайте файл /server/middleware/database.ts.

      import mysql from 'mysql2/promise'

export default defineEventHandler(async (event) => {
   event.context.db = await mysql.createConnection({
      host: '127.0.0.1',
      port: 3306,
      user: 'root',
      password: 'xxxx',
      database: 'STATS'
   })
});

И конечная точка API:

      export default defineEventHandler(async (event) => {

   const [rows, fields] = await event.context.db.execute('select * from tests');
   return {
        rows,
        fields
   }
})

Надеюсь, это решит вашу проблему.

Другие вопросы по тегам