-
-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: Ability to build for zeit/now serverless functions #16
Comments
@enisdenjo mentioned on Discord that there's a bug in the Zeit Not sure if that's relevant or not. I am a serverless newbie myself so I'm not sure how hard it would be to support Now. |
Since lambda functions do just one task and then die, the related Through my personal experience the server was occasionally entering an invalid state which caused lots of Maybe use a different node compiler? nexe? |
AWS lambda has a |
Is Now lambda-compatible or does it have it's own way of running? We use the aws-serverless-express stub (it doesn't and we don't use express itself, I think the name of this package is much like the "Java" in "JavaScript" - a play on popularity) to expose an HTTP middleware as a serverless function. postgraphile-lambda-example/src/index.js Line 65 in 2b1a9fb
|
It's lambda-compatible, but they run node apps through pkg to bundle your whole app into a single file, for smaller (tree-shaken) file-sizes and ES7 syntax, among other things. I think it also simplifies & speeds up the compilation step, as it uses a fast AST-aware cache. It's totally possible to build the graphile cache in the "build phase" and then import the cache, in the code: const { createPostGraphileSchema } = require('postgraphile')
const { Pool } = require('pg')
const schemas = process.env.DATABASE_SCHEMAS
? process.env.DATABASE_SCHEMAS.split(',')
: ['app_public']
async function main () {
console.log('Generating cache')
const pgPool = new Pool({
connectionString: process.env.DATABASE_URL
})
await createPostGraphileSchema(pgPool, schemas, {
writeCache: `${__dirname}/../src/postgraphile_cache.json`
})
await pgPool.end()
}
main().then(null, e => {
console.error(e)
process.exit(1)
}) then use it like this: import { postgraphile } from 'postgraphile'
// this works, but how do I actually use the cache?
import cache from '../src/postgraphile_cache.json'
// yours go here...
const options = {}
const handler = postgraphile(process.env.DATABASE_URL, schemas, {
...options,
// not this, but what should I do here?
// readCache: `${__dirname}/../src/postgraphile_cache.json`
}) The problem here is that
I think there are some options in now for including asset sort of files (non-imported) in the bundle that gets run on lambda (and pkg does interesting things to include compiled native node-libs, similar to this.) There may also be a hacky way to do it, by putting the JSON file in the public static files, then making a web-request to grab it, but I hate that. It would be ideal if I could just import the JSON directly (it would be inside the bundle) as this would simplify the end-users configuration, and work more reliably. Does anyone know a way to inject the cache directly into postgraphile? |
Looks like just requiring the JSON should work: import { postgraphile } from 'postgraphile'
// this works, but how do I actually use the cache?
import cache from '../src/postgraphile_cache.json'
// yours go here...
const options = {}
const handler = postgraphile(process.env.DATABASE_URL, schemas, {
...options,
readCache: require(`${__dirname}/../src/postgraphile_cache.json`)
}) (If you're in TypeScript you might need an |
Hmm, no, that is a JSON object, not a filename (as |
|
That is awesome, thanks @benjie and @enisdenjo I'd be happy to make a demo that deploys to now. If that's the case, then I think in the above example I should be able to just pass it cache directly: import { postgraphile } from 'postgraphile'
import readCache from '../src/postgraphile_cache.json'
// yours go here...
const options = {readCache}
const handler = postgraphile(process.env.DATABASE_URL, schemas, options) |
Oh, wait, there already is one at bottom of readme. doh! https://github.com/ggascoigne/now-postgraphile But weirdly, it uses a file. I'm pretty sure that wouldn't work: |
I assume it must work since there's a demo of it: https://now-postgraphile.now.sh/ |
I couldn't get it to work. Maybe I am doing something wrong. Here is what I did: First, there is a catch-22 with secrets. You can't setup secrets without a project, and you can't link it to a project without a deploy (which in this case, doesn't work without secrets.) I removed the To get stuff to run (I was getting path errors), I changed this in makeCache.js: const pgPool = getPool('./shared/') to this: const pgPool = getPool(`${__dirname}/../`) and set this in env-file:
Next, I made a script that looked like this, in shared/createSchema.js: const { getSchemas, getPool } = require('./config')
const db = getPool()
const { options: { user } } = db
const [schemaName] = getSchemas()
const run = async () => {
await db.query(`CREATE SCHEMA IF NOT EXISTS ${schemaName} AUTHORIZATION ${user};`)
await db.query(`CREATE TABLE ${schemaName}.thing(
id INT primary key,
stritem TEXT,
intitem INT
);`)
}
run() After this, I ran Then I run https://now-postgraphile.dkonsumer.now.sh/ Note, there are no schemas, but it seems to run graphiql ok. I checked console to see what was up with Error 502 on introspection query:
On now, the function-log has this:
If injecting the object works, directly, I can make a lighter example that is a bit simpler, and it should work fine. This code doesn't do that (it uses the file-location of the JSON cache) which didn't work for me in my tests, at least a month or so ago, or in my own test project, 3 days ago, when I first commented on this issue. |
I made this which works with undocumented |
It could be that the cache was generated with a different version, or that the |
I tried with pinned versions of postgraphile between my box and remote, and also has there been new published of postgraphile in the last 3 days? Would those minor changes effect the cache-writing portion? If so, then there would be a much bigger problem of breaking changes happening on minor version updates of postgraphile, but neither of those things are the case. Last release was 16 days ago (
I disagree. Importing vs I made a test project to explore these claims, and see how now handles various ways of "load JS object from this JSON file": https://github.com/konsumer/test-now-json https://test-now-json.now.sh/api/require All 3 API routes should do the same thing, and it illustrates a recent change for now. It's been a pain-point for lots people since now 2.0 that you can't dynamically read a JSON file. You'll notice "bad_import" is working, which is closest to what you proposed above. Until very recently, only the require api-route would have actually worked. Pkg doesn't actually include the files, from the real filesystem location that are imported, it bundles them and points to the inlined object (similar to what babel/requirejs/browserify/etc do) and until recently, it didn't include any files that were not directly required/imported, before runtime, unless the builder told it to (through options in now.json.)
Since I wrote a now-graphile-demo that actually works out of the box with no fussing, I'm not really into following along anymore with that non-functioning code, as it's a bit less organized, and convoluted in parts, and mine seems to work great. I think there is probably some other minor little thing that needs to be fixed, but why would I bother when I have a better, actually working code-example, I wrote myself? Due to the path changes I had to make to get it to run at all, I suspect the code that is deployed on the other demo isn't exactly what's in it's repo, which makes it even harder to troubleshoot. My main point above was "a JS object is not the same as a string filename" and we have cleared up that there is an undocumented way to load an object directly, which is exactly what I was looking for. I tested & verified this by making a working project that uses it. |
I guess only the deploy script would have to be modified?
But I am a complete backend noob so just asking.
The text was updated successfully, but these errors were encountered: