Skip to content
This repository has been archived by the owner on Jan 15, 2020. It is now read-only.

Suggestion: Use the DDP connection as a network interface #39

Closed
jamiter opened this issue Sep 29, 2016 · 5 comments
Closed

Suggestion: Use the DDP connection as a network interface #39

jamiter opened this issue Sep 29, 2016 · 5 comments

Comments

@jamiter
Copy link

jamiter commented Sep 29, 2016

Meteor supplies us with a great websocket implementation with authentication, retries and more. We could simply leverage this power by making a network interface that calls a DDP method:

Client

// ddp-network-interface.js
class DDPNetworkInterface {
    constructor({
        connection,
        noRetry = true,
        method = '/graphql' } = {}
    ) {
        this.connection = connection;
        this.noRetry = noRetry;
        this.method = method;
    }

    query(request) {
        return new Promise((resolve, reject) => {
            this.connection.apply(this.method, [request], { noRetry: this.noRetry }, (err, data) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(data);
                }
            });
        });
    }
}

export { DDPNetworkInterface };
// client.js
import ApolloClient from 'apollo-client';
import { DDPNetworkInterface } from './ddp-network-interface';

export const client = new ApolloClient ({
  networkInterface: new DDPNetworkInterface({ connection: Meteor.connection })
})

Server

import { schema } from './schema';
import { runQuery } from 'apollo-server';

export const methods = {
    '/graphql'({ query, variables }) {
        this.unblock();

        const { userId } = this;

        return runQuery({
            schema,
            query,
            variables,
            context: {
                userId
            }
        }).await();
    }
};

Meteor.methods(methods);

I'm testing this for our own app and it's seems to work perfectly so far.

If people are interested in this I would love to make a PR for it. What do you think @lorensr?

@jamiter jamiter mentioned this issue Sep 29, 2016
@lorensr
Copy link
Contributor

lorensr commented Sep 29, 2016

Nice! @stubailo ? Are there any downsides?

Maybe this could be the default connection for meteor clients, for network efficiency's sake, and then we could also keep the /graphql rest endpoint with current auth logic to support graphiql (on by default in dev) and prod rest API (off by default in prod)?

@markudevelop
Copy link

that is a really cool way of thinking, that will also make apollo subscriptions easier to manage with meteor :)

@stubailo
Copy link
Contributor

stubailo commented Oct 6, 2016

Honestly I'm not a big fan of this because there's a huge risk that the Meteor-specific transport will fall behind new features in the "standard" one. For example, if Meteor is doing retries under the hood and Apollo gets retry functionality, things are going to get weird.

@jamiter
Copy link
Author

jamiter commented Oct 11, 2016

@stubailo, thanks for the feedback. I understand the hesitation.

For websockets there isn't a good standard yet though (is there?), but we require a websocket connection for our specific app. So for me it looked like needless work to create a new websocket connection and implement authentication and everything, while I get it for free in Meteor. subscriptions-transport-ws is still WIP, so this seems like a safe bet until it's ready.

For who's interested in using this, we open-sourced the above implementation: https://github.com/Swydo/ddp-apollo

meteor add swydo:ddp-apollo

@lorensr
Copy link
Contributor

lorensr commented Oct 11, 2016

Thanks for open-sourcing!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants