graphql-pouch icon indicating copy to clipboard operation
graphql-pouch copied to clipboard

Refactor as a PouchDB plugin

Open a-s-o opened this issue 9 years ago • 4 comments

Hi Mike,

Carrying the discussion from the NPM issue to here. Here is what I meant that instead of creating a db for the user, we can instead use the pouch db plugins API.

Sample usage for the use as a npm module scenario:

import PouchDB from 'pouchdb';
import Express from 'express';
import GraphQLPlugin from 'pouch-graphql/express';   // Here user imports our plugin

PouchDB.plugin(GraphQLPlugin);

const MY_SCHEMA_DEFINITION = ``;
const CUSTOM_FUNCTIONS = { /* ... */ };
const MY_CONTEXT = { /* ... */ };

// User creates and has complete control of the db; the db
// instance will just have a few extra methods added
const db = new PouchDB('mydb', { adapter: 'websql' });

// Then they call our special methods
const middleware = db.graphqlExpress({
  schema: MY_SCHEMA_DEFINITION,
  resolvers: CUSTOM_FUNCTIONS,
  context: MY_CONTEXT,
  graphiql: true
});

// User mounts the returned interface to their app
const app = Express();
app.use('/graphql', middleware);
app.listen(3000, err => console.log(err || 'Listening'));

Internally, the code for pouch-graphql/express would be structured like this:

import expressGraphQl from 'express-graphql';
import graphqlPouch from './lib/pouch-graphql';

export default {
  graphqlExpressMiddleware (config = {}) {
    const db = this;  // We get access to the db instance

    // Instead of passing ENVIRONMENT to our schema function,
    // and then using pouch.createDB(ENVIRONMENT) throughout the
    // codebase, we just hold the reference to the db instance 
    const schema = graphqlPouch(db, config.schema, config.resolvers)

    return expressGraphQL({ ...config, schema });
  }
};

So just to highlight, the main difference is that instead of doing createPouchDB everytime we need the db reference, we simply use the db to which the user attaches our plugin.

Hope that make sense. Let me know if you like this approach and I can make a pull request.

a-s-o avatar Jul 30 '16 10:07 a-s-o

Hi Amandeep,

yes, looks good. How to get a specific instance (e.g. from another module)? Passthrough/DI? I thought memoize (https://github.com/MikeBild/graphql-pouch/blob/master/lib/pouch-graphql/pouchdb.js#L9) would be useful.

MikeBild avatar Jul 30 '16 15:07 MikeBild

Yup, any option will work. We can hold onto a reference or we can attach some properties and methods directly to db instance if needed.

Basically, whatever we do to hold onto a reference of ENVIRONMENT string, we can do that but instead hold the full db instance.

a-s-o avatar Jul 30 '16 17:07 a-s-o

Hi, just a quick update -- very sorry to disappear on you. I plan on getting back to this and making a PR but have been sidetracked by some other work. Thanks again for publishing to npm so quickly after my request.

a-s-o avatar Aug 14 '16 22:08 a-s-o

Great! I'm looking at your PR.

MikeBild avatar Aug 19 '16 19:08 MikeBild