crystal
crystal copied to clipboard
How to run postgraphile with https
What is the easiest way to set up a local hosted postgraphile server running with https ?
It seems running with a simple https server isn't simple.
// server.js
import app from 'express';
import https from 'https';
import fs from 'fs';
import {postgraphile} from 'postgraphile';
import {PostGraphileAmberPreset} from "postgraphile/presets/amber";
import {makePgService, PgSubscriber} from "postgraphile/adaptors/pg";
/** @type {GraphileConfig.Preset} */
const preset = {
extends: [PostGraphileAmberPreset],
pgServices: [makePgService({ connectionString: "postgresql://xxxxxxxxxxx:5432/appname",
schemas: "healthkiosk",
port: 5679
})],
grafserv: { watch: false }
// ,
// schema: {
// /* options for the schema build phase, e.g.: */
// retryOnInitFail: true,
// exportSchemaSDLPath: `${process.cwd()}/latestSchema.graphql`,
// exportSchemaIntrospectionResultPath: `${process.cwd()}/latestSchema.json`,
// sortExport: true,
// }
};
const options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
}
https.createServer(options, postgraphile(preset))
.listen(443);
And this is the resulting output
The GRAPHILE_ENV environmental variable is not set; Grafast will run in production mode. In your development environments, it's recommended that you set GRAPHILE_ENV=development to opt in to additional checks that will provide guidance and help you to catch issues in your code earlier, and other changes such as formatting to improve your development experience.
node:internal/errors:496
ErrorCaptureStackTrace(err);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "listener" argument must be of type function. Received an instance of Object at checkListener (node:events:267:3) at _addListener (node:events:547:3) at Server.addListener (node:events:606:10) at new Server (node:https:79:10) at Object.createServer (node:https:112:10) at file:///Users/XXXXXXXXXXXXXXXXX/postgraphile/https-server.js:34:7 at ModuleJob.run (node:internal/modules/esm/module_job:194:25) { code: 'ERR_INVALID_ARG_TYPE' }
Node 18.17.1
Well that proved to be ridiculous but I eventually found this which worked and was super easy. // On a Mac sudo npm install -g local-ssl-proxy local-ssl-proxy --source 5677 --target 5678 --cert cert.pem --key key.pem
copy cert.pem into keychain Login certificates and set trust to always.
now run npx postrgraphile on port 5678.
too easy
// ⚠️ THIS WILL NOT WORK WITH V5!
https.createServer(options, postgraphile(preset)).listen(443);
This would not work because postgraphile(preset) doesn't return a middleware, so it can't be mounted in this way. You're likely looking at the documentation for an older version of PostGraphile.
Instead; I would take the example from the documentation for node:http as a starting point, and then adjust it for HTTPS, something like:
-import { createServer } from "node:http";
+import { createServer } from "node:https";
+import { readFile } from "node:fs/promises";
import { grafserv } from "postgraphile/grafserv/node";
import { pgl } from "./pgl.js";
+const key = await readFile('key.pem');
+const cert = await readFile('cert.pem');
const serv = pgl.createServ(grafserv);
-const server = createServer();
+const server = createServer({ key, cert });
server.on("error", (e) => {
console.error(e);
});
serv.addTo(server).catch((e) => {
console.error(e);
process.exit(1);
});
server.listen(5678);
-console.log("Server listening at http://localhost:5678");
+console.log("Server listening at https://localhost:5678");
I've not tried this though, would be good to have a tested example 👍