#node.js #postgresql #next.js #serverless #node-postgres
#node.js #postgresql #next.js #без сервера #узел-postgres
Вопрос:
Я использую Next.js для моего сайд-проекта. У меня есть база данных PostrgeSQL, размещенная на ElephantSQL. Внутри Next.js проект, у меня настроен GraphQL API, использующий пакет apollo-server-micro.
Внутри файла, в котором настроен API GraphQL (/api/graphql), я импортирую вспомогательный модуль базы данных. Внутри этого я настраиваю соединение с пулом и экспортирую функцию, которая использует клиента из пула для выполнения запроса и возврата результата. Это выглядит примерно так:
// import node-postgres module
import { Pool } from 'pg'
// set up pool connection using environment variables with a maximum of three active clients at a time
const pool = new Pool({ max: 3 })
// query function which uses next available client to execute a single query and return results on success
export async function queryPool(query) {
let payload
// checkout a client
try {
// try executing queries
const res = await pool.query(query)
payload = res.rows
} catch (e) {
console.error(e)
}
return payload
}
Проблема, с которой я сталкиваюсь, заключается в том, что кажется, что Next.js API не (всегда) поддерживает соединение, а скорее открывает новое (либо для каждого подключенного пользователя, либо, возможно, даже для каждого запроса API), что приводит к быстрому исчерпанию соединений в базе данных.
Я считаю, что то, чего я пытаюсь достичь, возможно, например, в AWS Lambda (установив для context.callbackWaitsForEmptyEventLoop значение false).
Очень возможно, что у меня нет правильного понимания того, как работают бессерверные функции, и это может быть вообще невозможно, но, возможно, кто-то может предложить мне решение.
Я нашел пакет под названием serverless-postgres, и мне интересно, сможет ли это решить проблему, но я бы предпочел использовать пакет node-postgres, поскольку он имеет гораздо лучшую документацию. Другим вариантом, вероятно, было бы полностью отказаться от интегрированной функциональности API и создать выделенный серверный сервер, который поддерживает соединение с базой данных, но, очевидно, это будет последнее средство.
Комментарии:
1. хороший вопрос, есть какое-нибудь хорошее решение? Br
2. @user1665355 к сожалению, нет. существует бессерверный модуль mysql, который должен решить эту проблему для соединений с базой данных MySQL, но, к сожалению, для Postgres нет аналогичного модуля. я действительно надеюсь, что кто-нибудь создаст его в будущем, но до тех пор нам придется использовать второй выделенный сервер подключения к БД.
Ответ №1:
Я еще не проводил стресс-тестирование, но похоже, что mongodb next.js например, решает эту проблему путем подключения к базе global
данных в вспомогательной функции. Важный момент в их примере здесь.
Поскольку pg
соединение немного более абстрактно, чем mongodb
, похоже, этот подход занимает всего несколько строк для нас pg
, энтузиастов:
// eg, lib/db.js
const { Pool } = require("pg");
if (!global.db) {
global.db = { pool: null };
}
export function connectToDatabase() {
if (!global.db.pool) {
console.log("No pool available, creating new pool.");
global.db.pool = new Pool();
}
return global.db;
}
тогда, например, в нашем маршруте API мы можем просто:
// eg, pages/api/now
export default async (req, res) => {
const { pool } = connectToDatabase();
try {
const time = (await pool.query("SELECT NOW()")).rows[0].now;
res.end(`time: ${time}`);
} catch (e) {
console.error(e);
res.status(500).end("Error");
}
};