跳至主要内容

Nuxt API 路由

Grafserv 处理许多 API 路由,因此您应该为每个您关心的内容定义一个路由。确保路径与 Graphile 配置中使用的路径一致至关重要,否则资产将无法正确提供/引用,这可能会在 Ruru 和 GraphQL 之间通信时造成问题。

创建 grafserv

server/grafserv/serv.ts
import { grafserv } from "grafserv/h3/v1";
import preset from "./graphile.config";
import schema from "./schema.mjs";

// Create a shared Grafserv instance
export const serv = grafserv({ schema, preset });

以及 API 路由

server/api/graphql.ts
import { serv } from "@/server/grafserv/serv";

// Create and export the `/api/graphql` route handler
export default eventHandler((event) => serv.handleGraphQLEvent(event));
pages/routes/ruru.ts
import { serv } from "@/server/grafserv/serv";

// Create and export the `/ruru` route handler
export default eventHandler((event) => serv.handleGraphiqlEvent(event));
pages/api/graphql/stream.ts
import { serv } from "@/server/grafserv/serv";

// Create and export the `/api/graphql/stream` route handler
export default eventHandler((event) => serv.handleEventStreamEvent(event));

实验性

WebSocket 支持

Nitro 和 h3 尚未支持 WebSocket。

一个非官方的实验性解决方法是创建一个 nuxt 模块

modules/grafserv/index.ts
// nuxt auto-register modules located in `modules/*.ts` or `modules/*/index.ts`

import { defineNuxtModule, addServerPlugin } from "@nuxt/kit";

import httpProxy from "http-proxy";

export default defineNuxtModule({
async setup(options, nuxt) {
/**
* Register websockets in DEVELOPMENT mode.
*/
if (nuxt.options.dev) {
// hook called in development only
nuxt.hook("listen", (devServer) => {
// create a proxy for routing ws to runtime server created in dev plugin
const proxy = httpProxy.createProxy({
target: {
host: "localhost",
port: 3100,
},
});
// registering ws on devServer
devServer.on("upgrade", (req, socket, head) => {
// routing ws by path
switch (req.url) {
case "/api/graphql":
// proxy websocket to runtime server created in dev plugin
proxy.ws(req, socket, head);
break;
default:
socket.destroy();
}
});
});
// Registering runtime plugin for dev
addServerPlugin("@/modules/grafserv/ws-dev");
}

/**
* Register websockets in PRODUCTION mode.
*/
if (!nuxt.options.dev)
// Registering runtime plugin for production
addServerPlugin("@/modules/grafserv/ws");
},
});

以及两个 Nitro 插件(一个用于开发,一个用于生产)

modules/grafserv/ws-dev.ts
import { Server } from "http";
import { serv } from "@/server/grafserv/serv";

// plugin running in DEVELOPMENT (runtime)
export default defineNitroPlugin(async (nitroApp) => {
// Create a server for handling websockets
const server = new Server().listen({ port: 3100 }, () =>
console.log("Runtime server listening on port 3100"),
);
// Cleanly close server (on leave or HMR before plugin reload)
nitroApp.hooks.hookOnce("close", () => {
server.closeAllConnections();
server.close((err) =>
err
? console.warn("Runtime server wrongly closed", err)
: console.log("Runtime server stopped"),
);
});
// Attaching ws to server
serv.attachWebsocketsToServer_experimental(server);
});
modules/grafserv/ws.ts
import { serv } from "@/server/grafserv/serv";

// plugin running in PRODUCTION (runtime)
export default defineNitroPlugin(async (nitroApp) => {
// this hook will be called only once at first http request
nitroApp.hooks.hookOnce("request", (event: H3Event) => {
const server = event.node.req.socket.server;
if (server) {
// Attaching ws to server
serv.attachWebsocketsToServer_experimental(server);
}
});
});