Skip to content

Instantly share code, notes, and snippets.

@olragon
Last active January 29, 2024 11:29
Show Gist options
  • Save olragon/03fcf7d68e087a6bf03cf82b6d5550f1 to your computer and use it in GitHub Desktop.
Save olragon/03fcf7d68e087a6bf03cf82b6d5550f1 to your computer and use it in GitHub Desktop.
Postgraphile plugin for Elysia

Install

  • bun add postgraphile

Temporary fix as of 2023-07-28

Issues: Bun resolve to incorect graphql package oven-sh/bun#3857

  • save file postgraphile+4.13.0.patch to patches/postgraphile+4.13.0.patch
  • bun add patch-package
  • bunx patch-package

Usages

Update code

app
  // use postgraphile
  .use(postgraphilePlugin({
    prefix: '/api', 
    dbUrl: 'postgresql://postgres:password@localhost:5432/somedb?schema=public'
  }))
  .listen(process.env.PORT || 3000)

GraphiQL Console

diff --git a/node_modules/postgraphile/build/postgraphile/http/createPostGraphileHttpRequestHandler.js b/node_modules/postgraphile/build/postgraphile/http/createPostGraphileHttpRequestHandler.js
index 73bc159..1b1d23d 100644
--- a/node_modules/postgraphile/build/postgraphile/http/createPostGraphileHttpRequestHandler.js
+++ b/node_modules/postgraphile/build/postgraphile/http/createPostGraphileHttpRequestHandler.js
@@ -717,7 +717,14 @@ function createPostGraphileHttpRequestHandler(options) {
operationName,
}, (graphqlContext) => {
pgRole = graphqlContext.pgRole;
- const graphqlResult = graphql_1.execute(gqlSchema, queryDocumentAst, null, graphqlContext, variables, operationName);
+ const graphqlResult = graphql_1.execute({
+ schema: gqlSchema,
+ document: queryDocumentAst,
+ variableValues: variables,
+ rootValue: graphqlContext.rootValue,
+ operationName: operationName,
+ contextValue: graphqlContext,
+ });
if (typeof graphqlContext.getExplainResults === 'function') {
return Promise.resolve(graphqlResult).then(async (obj) => (Object.assign(Object.assign({}, obj), {
// Add our explain data
import { Elysia } from "elysia";
import { postgraphile, PostGraphileOptions } from "postgraphile";
import { IncomingMessage, ServerResponse } from "node:http";
export const postgraphilePlugin =
({
prefix = "/api",
dbUrl = process.env.DATABASE_URL || "",
schema = "public",
options,
}: {
prefix?: string;
dbUrl?: string;
schema?: string;
options?: PostGraphileOptions;
}) =>
(app: Elysia) => {
if (!dbUrl) return app;
const parsedUrl = new URL(dbUrl);
if (parsedUrl.protocol != "postgresql:") {
console.log(`[postgraphile] Error! DB must be Postgres. dbUrl =`, dbUrl);
return app;
}
const graphql = dbUrl
? postgraphile(dbUrl, schema, {
externalUrlBase: prefix,
watchPg: true,
graphiql: true,
enhanceGraphiql: true,
appendPlugins: [],
...options,
})
: undefined;
if (!graphql) return app;
app.group(prefix, (app) =>
app.all("*", async (context) => {
const bunRequest = context.request;
// postgraphile auto handles the prefix
const internalUrl = bunRequest.url.replace(prefix, "");
const nodeRequest = new IncomingMessage({
method: bunRequest.method,
url: internalUrl,
headers: bunRequest.headers,
body: bunRequest.body,
});
return new Promise((resolve, reject) => {
const nodeResponse = new ServerResponse({
req: nodeRequest,
reply: (resp: Response) => {
resolve(resp);
},
});
graphql(nodeRequest, nodeResponse);
});
})
);
return app;
};
@coopbri
Copy link

coopbri commented Dec 2, 2023

Thank you for this @olragon! Have you considered publishing this as a community plugin?

EDIT: I did see your question asked here: https://discord.com/channels/1044804142461362206/1044807567022493766/1134407859736678430

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment