Giter VIP home page Giter VIP logo

apollo-local-query's People

Contributors

af avatar digigarlab avatar dimitrydushkin avatar xzyfer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

apollo-local-query's Issues

How about dataIdFromObject?

Great library! However, an apollo client has the option of giving an dataIdFromObject option which is for caching in the browser. But this library has no such option, so when rehydrating the store everything gets the wrong ID's in the store. Is there a simple fix I am overlooking?

Use graphql library by default

Currently, we need to pass graphql library to createLocalInterface, why do we need this?

Apollo is using it by default, is it possible to use it by default too so we have to provide only the schema or what is the use-case for this?

How to use for Apollo Client 2.0

The ApolloClient object in the new 2.0 version requires that both link and cache be passed in. How is this library supposed to be used in 2.0?

Installation problem: Dependencies not available after installing the package (context: Nextjs / Redux / Apollo / Koa)

Hi, Apollo-local-query looks to be a great package for me to avoid go out and back through the networking stack, before I'm looking to gain some speed to render the data of my queries.

Unfortunately, I'm facing some troubles to install it in my context:

After doing the installation as presented in the readme, I'm getting the following error, which says that the dependencies related to the Koa server:

ERROR  Failed to compile with 18 errors
                                                                                             
These modules were not found:
* child_process in ./node_modules/stripe/lib/stripe.js, ./node_modules/os-locale/index.js
* net in ./node_modules/forever-agent/index.js, ./node_modules/tunnel-agent/index.js and 2 others
* tls in ./node_modules/forever-agent/index.js, ./node_modules/tunnel-agent/index.js and 1 other
* module in ./node_modules/require_optional/node_modules/resolve-from/index.js
* fs in ./node_modules/nconf/lib/nconf.js, ./node_modules/y18n/index.js and 6 others

To install them, you can run: npm install --save child_process net tls module fs

My working code before the installation was looking like this:

import { ApolloClient, createNetworkInterface } from 'react-apollo';
import fetch from 'isomorphic-fetch';

let apolloClient = null;

// Polyfill fetch() on the server (used by apollo-client)
if (!process.browser) {
  global.fetch = fetch;
}

function create() {
  return new ApolloClient({
    ssrMode: !process.browser, // Disables forceFetch on the server (so queries are only run once)
    networkInterface: createNetworkInterface({
      uri: '/graphql',
      opts: {
        credentials: 'include'
      }
    })
  });
}

export default function initApollo() {
  // Make sure to create a new client for every server-side request so that data
  // isn't shared between connections (which would be bad)
  if (!process.browser) {
    return create();
  }

  // Reuse client on the client-side
  if (!apolloClient) {
    apolloClient = create();
  }

  return apolloClient;
}

After the installation of apollo-local-query, it was looking like this:

import { ApolloClient, createNetworkInterface } from 'react-apollo';
//  >>I've tried with it too import fetch from 'isomorphic-fetch';
import { createLocalInterface } from 'apollo-local-query';
import * as graphql from 'graphql'; >> // I've also tried with: import graphql from 'graphql';
import schema from '../../server/graphql/schema';

const isServer = !process.browser;
const options = { credentials: 'include' };

if (isServer) {
  options.networkInterface = createLocalInterface(graphql, schema);
  options.ssrMode = true;
}

const myClient = new ApolloClient(options)

export default function initApollo() {
  return myClient;
}

For information, my schema.js is looking like this:

const { makeExecutableSchema } = require('graphql-tools');

const resolvers = require('./resolvers');
const Schemas = require('./schemas');
const { User, Service } = require('./types');

const Queries = `
  type Query {
    ${User.queries}
    ${Service.queries}
  }
`;

const Mutations = `
  type Mutation {
    ${User.mutations}
    ${Service.mutations}
  }
`;

const Scalars = `
  scalar Date
`;

const Inputs = `
  input TranslationInput {
    en: String
    es: String
    ca: String
    fr: String
  }
// ... With others inputs
`;

module.exports = makeExecutableSchema({
  typeDefs: [Queries, Mutations, Scalars, Inputs, ...Schemas],
  resolvers
});

The file where I call the "initApollo" function to pass the ApolloClient to the Apollo Provider is looking like this:

import React from 'react'
import PropTypes from 'prop-types'
import { ApolloProvider, getDataFromTree } from 'react-apollo'
import Head from 'next/head'
import initApollo from './apollo'
import initRedux from './store'

// Gets the display name of a JSX component for dev tools
function getComponentDisplayName (Component) {
  return Component.displayName || Component.name || 'Unknown'
}

export default ComposedComponent => {
  return class WithData extends React.Component {
    static displayName = `WithData(${getComponentDisplayName(ComposedComponent)})`
    static propTypes = {
      serverState: PropTypes.object.isRequired
    }

    static async getInitialProps (ctx) {
      let serverState = {}

      // Evaluate the composed component's getInitialProps()
      let composedInitialProps = {}
      if (ComposedComponent.getInitialProps) {
        composedInitialProps = await ComposedComponent.getInitialProps(ctx)
      }

      // Run all GraphQL queries in the component tree
      // and extract the resulting data
      if (!process.browser) {
        const apollo = initApollo()
        const redux = initRedux(apollo, { test: { also: 'this' } })
        // Provide the `url` prop data in case a GraphQL query uses it
        const url = {query: ctx.query, pathname: ctx.pathname}

        try {
          // Run all GraphQL queries
          await getDataFromTree(
            // No need to use the Redux Provider
            // because Apollo sets up the store for us
            <ApolloProvider client={apollo} store={redux}>
              <ComposedComponent url={url} {...composedInitialProps} />
            </ApolloProvider>
          )
        } catch (error) {
          // Prevent Apollo Client GraphQL errors from crashing SSR.
          // Handle them in components via the data.error prop:
          // http://dev.apollodata.com/react/api-queries.html#graphql-query-data-error
        }
        // getDataFromTree does not call componentWillUnmount
        // head side effect therefore need to be cleared manually
        Head.rewind()

        // Extract query data from the store
        const state = redux.getState()

        // No need to include other initial Redux state because when it
        // initialises on the client-side it'll create it again anyway
        serverState = {
          apollo: { // Only include the Apollo data state
            data: state.apollo.data
          }
        }
      }

      return {
        serverState,
        ...composedInitialProps
      }
    }

    constructor (props) {
      super(props)
      this.apollo = initApollo()
      this.redux = initRedux(this.apollo, this.props.serverState)
    }

    render () {
      return (
        // No need to use the Redux Provider
        // because Apollo sets up the store for us
        <ApolloProvider client={this.apollo} store={this.redux}>
          <ComposedComponent {...this.props} />
        </ApolloProvider>
      )
    }
  }
}

And my server.js with Koa is looking like this:

const IntlPolyfill = require('intl');
const Koa = require('koa');
const convert = require('koa-convert');
const router = require('./routes.js');
const session = require('koa-generic-session');
const passport = require('koa-passport');
const bodyParser = require('koa-bodyparser');
const accepts = require('accepts');
const next = require('next');
const { graphqlKoa, graphiqlKoa } = require('graphql-server-koa');
const { basename } = require('path');
const glob = require('glob');
const { readFileSync } = require('fs');
const en = require('../helpers/intl/messages/en.js');
const es = require('../helpers/intl/messages/en.js');
const ca = require('../helpers/intl/messages/en.js');
const fr = require('../helpers/intl/messages/en.js');

const messages = { en, es, ca, fr };
// const compression = require('compression');

require('./auth');

const { Company } = require('./models');
const schema = require('./graphql/schema');
const nconf = require('../env/nconf');

Intl.NumberFormat = IntlPolyfill.NumberFormat;
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;


const port = process.env.PORT || nconf.get('PORT');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

const languages = glob.sync('./helpers/intl/messages/*.js').map(f => basename(f, '.js'));
const localeDataCache = new Map();
const getLocaleDataScript = (locale) => {
  // const lang = locale.split('-')[0]
  const lang = locale;
  if (!localeDataCache.has(lang)) {
    const localeDataFile = require.resolve(`react-intl/locale-data/${lang}`);
    const localeDataScript = readFileSync(localeDataFile, 'utf8');
    localeDataCache.set(lang, localeDataScript);
  }
  return localeDataCache.get(lang);
};

const getMessages = (locale, companyMessages) =>
  Object.assign({}, messages[locale], companyMessages);


app.keys = [nconf.get('APP_KEYS')];

app.prepare()
.then(() => {
  const server = new Koa();

  server
  .use(bodyParser())
  .use(convert(session()))
  .use(passport.initialize())
  .use(passport.session())
  .use(router.routes())
  .use(router.allowedMethods());
  // .use(compression())

  router.post('/graphql', graphqlKoa(async (ctx) => {
    const host = ctx.req.headers.host;
    const company = await Company.findOne({ website_url: host.replace('www.', '') });
    return ({
      schema,
      context: {
        ctx,
        user: ctx.state.user,
        company
      }
    });
  }));

  router.get('/graphiql', graphiqlKoa({ endpointURL: '/graphql' }));

  router.get('*', async (ctx) => {
    const host = ctx.req.headers.host;
    const accept = accepts(ctx.req);
    const locale = accept.language(languages);
    const company = await Company.findOne({ website_url: host.replace('www.', '') });
    ctx.req.company = company;
    ctx.req.locale = locale;
    ctx.req.localeDataScript = getLocaleDataScript(locale);
    ctx.req.messages = getMessages(locale, company.website[locale]);
    await handle(ctx.req, ctx.res);
    ctx.respond = false;
  });

  server.listen(port, (err) => {
    if (err) throw err;
    console.log(`> Ready on http://localhost:${port}`);
  });
});

Does anyone have an idea how to fix this issue?
If someone succeed to give me some hint about how to fix it, I'm proposing myself to produce some extra documentation for apollo-local-query to illustrate the setup for this context! ;)

Thank for your help!

Doesn't work

W20161217-12:43:23.389(1)? (STDERR) const createLocalInterface = (graphql, schema, {rootValue = null, context = null} = {}) => {
W20161217-12:43:23.390(1)? (STDERR)                                                ^
W20161217-12:43:23.390(1)? (STDERR)           
W20161217-12:43:23.390(1)? (STDERR) ReferenceError: Invalid left-hand side in assignment

just wanted to let you know

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.