Giter Site home page Giter Site logo

apollographql / apollo-server Goto Github PK

View Code? Open in Web Editor NEW
13.7K 207.0 2.0K 133.38 MB

๐ŸŒ ย Spec-compliant and production ready JavaScript GraphQL server that lets you develop in a schema-first way. Built for Express, Connect, Hapi, Koa, and more.

Home Page: https://www.apollographql.com/docs/apollo-server/

License: MIT License

TypeScript 55.80% JavaScript 43.78% Shell 0.41%
graphql graphql-server express-graphql express koa hapi node restify apollographql graphql-schema resolvers

apollo-server's Introduction

@apollo/server

This @apollo/server package is new with Apollo Server 4. Previous major versions of Apollo Server used a set of package names starting with apollo-server, such as apollo-server, apollo-server-express, apollo-server-core, etc.

npm version Build Status Join the community Join our Discord server

A TypeScript/JavaScript GraphQL server

Apollo Server is an open-source, spec-compliant GraphQL server that's compatible with any GraphQL client, including Apollo Client. It's the best way to build a production-ready, self-documenting GraphQL API that can use data from any source.

You can use Apollo Server as:

Apollo Server provides a simple API for integrating with any Node.js web framework or serverless environment. The @apollo/server package itself ships with a minimally-configurable, standalone web server which handles CORS and body parsing out of the box. Integrations with other environments are community-maintained.

Apollo Server provides:

  • Straightforward setup, so your client developers can start fetching data quickly
  • Incremental adoption, enabling you to add features as they're needed
  • Universal compatibility with any data source, any build tool, and any GraphQL client
  • Production readiness, enabling you to confidently run your graph in production

Documentation

Full documentation for Apollo Server is available on our documentation site. This README shows the basics of getting a server running (both standalone and with Express), but most features are only documented on our docs site.

Getting started: standalone server

You can also check out the getting started guide in the Apollo Server docs for more details, including examples in both TypeScript and JavaScript.

Apollo Server's standalone server lets you get a GraphQL server up and running quickly without needing to set up an HTTP server yourself. It allows all the same configuration of GraphQL logic as the Express integration, but does not provide the ability to make fine-grained tweaks to the HTTP-specific behavior of your server.

First, install Apollo Server and the JavaScript implementation of the core GraphQL algorithms:

npm install @apollo/server graphql

Then, write the following to server.mjs. (By using the .mjs extension, Node lets you use the await keyword at the top level.)

import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';

// The GraphQL schema
const typeDefs = `#graphql
  type Query {
    hello: String
  }
`;

// A map of functions which return data for the schema.
const resolvers = {
  Query: {
    hello: () => 'world',
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

const { url } = await startStandaloneServer(server);
console.log(`๐Ÿš€ Server ready at ${url}`);

Now run your server with:

node server.mjs

Open the URL it prints in a web browser. It will show Apollo Sandbox, a web-based tool for running GraphQL operations. Try running the operation query { hello }!

Getting started: Express middleware

Apollo Server's built-in Express middleware lets you run your GraphQL server as part of an app built with Express, the most popular web framework for Node.

First, install Apollo Server, the JavaScript implementation of the core GraphQL algorithms, Express, and two common Express middleware packages:

npm install @apollo/server graphql express cors body-parser

If using Typescript you may also need to install additional type declaration packages as development dependencies to avoid common errors when importing the above packages (i.e. Could not find a declaration file for module 'cors'):

npm install --save-dev @types/cors @types/express @types/body-parser

Then, write the following to server.mjs. (By using the .mjs extension, Node lets you use the await keyword at the top level.)

import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer'
import express from 'express';
import http from 'http';
import cors from 'cors';
import bodyParser from 'body-parser';

// The GraphQL schema
const typeDefs = `#graphql
  type Query {
    hello: String
  }
`;

// A map of functions which return data for the schema.
const resolvers = {
  Query: {
    hello: () => 'world',
  },
};

const app = express();
const httpServer = http.createServer(app);

// Set up Apollo Server
const server = new ApolloServer({
  typeDefs,
  resolvers,
  plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});
await server.start();

app.use(
  cors(),
  bodyParser.json(),
  expressMiddleware(server),
);

await new Promise((resolve) => httpServer.listen({ port: 4000 }, resolve));
console.log(`๐Ÿš€ Server ready at http://localhost:4000`);

Now run your server with:

node server.mjs

Open the URL it prints in a web browser. It will show Apollo Sandbox, a web-based tool for running GraphQL operations. Try running the operation query { hello }!

apollo-server's People

Contributors

abernix avatar addityasingh avatar cheapsteak avatar dxcx avatar freiksenet avatar github-actions[bot] avatar glasser avatar greenkeeper[bot] avatar greenkeeperio-bot avatar helfer avatar ivangoncharov avatar jakedawkins avatar jsegaran avatar martijnwalraven avatar mayakoneval avatar meschreiber avatar michael-watson avatar nicolaslopezj avatar nnance avatar peggyrayzis avatar renovate-bot avatar renovate[bot] avatar rkoron007 avatar sachindshinde avatar smyrick avatar trevor-scheer avatar trevorblades avatar unicodeveloper avatar urigo avatar zionts 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  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  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  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

apollo-server's Issues

Koa: Cannot read property 'body' of undefined

When I use apolloKoa with koa-router like this:

const app = koa();
const router = new Router();
const apolloMiddleware = apolloKoa({ schema });

app.use(koaBody());

router.post('/api', apolloMiddleware);

app.use(router.routes());
app.use(router.allowedMethods());

I get the following error:

  TypeError: Cannot read property 'body' of undefined
      at /home/voodooattack/dev/foxls/node_modules/apollo-server/dist/integrations/koaApollo.js:35:25
      at undefined.next (native)
      at fulfilled (/home/voodooattack/dev/foxls/node_modules/apollo-server/dist/integrations/koaApollo.js:4:58)
      at run (/home/voodooattack/dev/foxls/node_modules/core-js/modules/es6.promise.js:87:22)
      at /home/voodooattack/dev/foxls/node_modules/core-js/modules/es6.promise.js:100:28
      at flush (/home/voodooattack/dev/foxls/node_modules/core-js/modules/_microtask.js:18:9)
      at _combinedTickCallback (internal/process/next_tick.js:67:7)
      at process._tickCallback (internal/process/next_tick.js:98:9)

package.json:

  "dependencies": {
    "apollo-client": "^0.4.11",
    "apollo-server": "^0.2.3",
  }

Readme.md missing resolvers

In https://github.com/apollostack/apollo-server#options it missing resolvers:

schema: the GraphQLSchema to be used
context: the context value passed to resolvers during GraphQL execution
rootValue: the value passed to the first resolve function
formatError: a function to apply to every error before sending the response to clients
validationRules: additional GraphQL validation rules to be applied to client-specified queries
formatParams: a function applied for each query in a batch to format parameters before execution
formatResponse: a function applied to each response after execution

It actually be like this in the GitHunt example:

    graphiql: true,
    pretty: true,
    resolvers,  // ไธบ Schema ๅ–ๆ•ฐๆฎ็š„็ง˜ไนฆ
    schema,    // ๅฎšไน‰ๆ•ฐๆฎ็š„ๅคงไฝฌ
    context: {
      ...
    },

seems missing something?

Defining queries using structured data

I'm just exploring graphql and see existing way of doing requests from client is using string based queries. I see such approach as kinda error prone and unstructured. What are the advantages of this? Do you see any advantages (or maybe obvious disadvantages) if there would be a way in defining queries using json object instead of string?

Kind of:

user: {
  query: {id: 32423},
  fields: [
     'id', `name`, 
     {`profilePicture`: {
        query: {size: '50'}, 
        fields: ['uri', 'weigh', 'height']
     }}
  ]
}

Also I see thy way of defining schema using string based approach is too kind of error prone.

Error with `typings.json` when behind a firewall

I'm trying to install apollo-server in my project, but the installation happens in a corporate network that won't let me see type typings repository. The output that I get:

typings ERR! message Unable to connect to "https://api.typings.org/entries/npm/chai/tags/3.5.0%2B20160415060238"
typings ERR! caused by getaddrinfo ENOTFOUND api.typings.org api.typings.org:443

I haven't the foggiest how to fix this one, and the answer may be that I'm out of luck because of the weirdness of our networking stuff, but I figured I'd report it anyway. This one seems somewhat related to #54 in that the typings stuff is run post-install.

Meteor/Node version related issue I believe

Hi, I'm having an issue when I import apollo-server into my meteor project.

Below is the error:

/Users/davidyoung/Dev/gobeyond/.meteor/local/build/programs/server/packages/modules.js:41096 const graphql = require('graphql'); ^^^^^ SyntaxError: Use of const in strict mode. at /Users/davidyoung/Dev/gobeyond/.meteor/local/build/programs/server/boot.js:292:30 at Array.forEach (native) at Function._.each._.forEach (/Users/davidyoung/.meteor/packages/meteor-tool/.1.3.5_1.1fnktti++os.osx.x86_64+web.browser+web.cordova/mt-os.osx.x86_64/dev_bundle/server-lib/node_modules/underscore/underscore.js:79:11) at /Users/davidyoung/Dev/gobeyond/.meteor/local/build/programs/server/boot.js:133:5

Any way of sorting this?

GraphiQL endpoint broken after migrating to 0.2? "Apollo Server supports only POST requests"

Hi guys. Thanks for the great work!
My small Apollo server example was working fine at 0.1, but after following the exact migration path to 0.2 and double checking against the Apollo Server GraphiQL docs page, the server no longer seems to serve GraphiQL correctly.

The page: localhost:9090/graphql always returns Apollo Server supports only POST requests and the GraphiQL GUI never shows up.
Now it's unclear to me if both can be at the same endpoint, as stated in both examples in the doc:

graphQLServer.use('/graphql', bodyParser.json(), apolloExpress({
  schema: executableSchema,
}));
graphQLServer.use('/graphiql', graphiqlExpress({
  endpointURL: '/graphql',
}));

but changing the GraphiQL endpoint to '/graphiql' will bring the UI back, but executing any GraphQL example there will still fail.
Thanks

Simple mutation throw error "Can't wait without a fiber"

RootQuery :{
  ...
// works well 
    async oneFeedback(root, {feedbackId}, context) {
      const feedback = DB.Feedback.findOne({_id: feedbackId})
      return await feedback
    },
}

// mutate nothing but just for test , will throw an error
RootMutation: {
    async changeFeedbackText(root, {feedbackId, text}, context) {
      const feedback = DB.Feedback.findOne({_id: feedbackId})
      return await feedback
    }
// so does this one
   async changeFeedbackText(root, {feedbackId, text}, context) {
      DB.Feedback.update(feedbackId, {$set:{text: text}})
      return DB.Feedback.findOne(feedbackId)
    }
  }

Why same code in query don't throw an error?

Real-time / streaming / live query / RethinkDB support

Hey, I know this isn't on the near term radar, but I thought it would be helpful to have a single issue that we could always refer back to on this. Feel free to edit this first post as useful. I guess the main things are:

  • Ability to maintain an open websocket
    • Would be cool to (optionally) only open the websocket if active live queries are running, and disconnect after a configurable amount of time after all live queries have stopped.
  • Server API to invalidate queries / push new results
  • Client/server protocol for live query style add/update/change

Rough ETA: 2017 (expectation management :))

Related issues:

  • #18 - Support for deferred/partial responses
  • facebook/relay#541 - Support real-time updates via event subscriptions

Multiple types per field in schema?

Hello guys, I'm making a live music app that shows you who's playing, where and when. I want to enable a field to have two possible types.

There are two types of users that can post "events". Is this type thing possible? If yes, how would you make it work? I have an owner_type column in my database that can be 'artist' or 'venue', but I don't know how I can use it to set the type in Apollo.

type Event {
    owner: Artist || Venue,  // I want to set the type based on a value read from the DB using knex
    venue: Venue,
    artists: [Artist],
}

type Artist {
    events: [Event],
}

type Venue {
    events: [Event],
}

Currently I'm working around this by setting it like this:

type Event {
    owner_id: Int,
    owner_type: String,
    venue: Venue,
    artists: [Artist],
}

How to split schemas into separate files?

userSchema: (author schema like the same)

export const schema = [`
type Email {
address: String
verified: Boolean
}

type User {
emails: [Email]
username: String
randomString: String
}
`];

rootSchema:

import { schema as userSchema, resolvers as userResolver } from './user/schema';
const rootSchema = [`
type RootQuery {
author(name: String): Author
user: User
}

schema {
query: RootQuery
}
`]

export const schema = [...rootSchema, ...userSchema, ...authorSchema];


When I trying to contact schemas into 1 typedefinition in GitHunt way(seems its the only one example had separate schemas), I got this:
[ '\n type RootQuery {\n author(name: String): Author\n user: User\n }\n \n \n schema {\n query: RootQuery\n }\n', I20160704-11:08:53.149(8)? '\n type Email {\n address: String\n verified: Boolean\n }\n \n type User {\n emails: [Email]\n username: String\n randomString: String\n }\n', I20160704-11:08:53.149(8)? '\n# This uses the exact field names returned by the GitHub API for simplicity\ntype Author {\n name: String\n books: [Book]\n }\n \n type Book {\n name: String\n author: [Author]\n \n' ] { RootQuery: { user: [Function: user], author: [Function: author] }

Also I found the generateSchema in docs is deprecated. And I have no idea how to use the GraphQLSchema instance generated.

Typescript

Since the client is written in Typescript, I think it makes sense for server to be as well.

Ditching async

Guys, in all your examples you advocate using async with queries on server. Concerning that node 6.x can now run vanilla es2015 it is the only thing that requires transpilation. I tried not to use async call but I was running through poopstorm of problems with fibers and all. What would be a recommended strategy without asyns/await? Would you care to provide functioning example of e.g. a resolver or mutation without async call, for example based on Promises? I tried several startegies and none seems to work.

Measuring server performance

At some point it will be nice to be able to recommend a way for devs to measure server-side performance, whether it's a guide to using a 3rd party package or tool, or something built into in apollo server.

Meteor example case

When I switched from DO to Galaxy, my pageload subscriptions ready time jumped due to the CPU maxing out. It was due to some combination of:

  • number of subs
  • amount of publish-with-relations use
  • total amount of data

But I didn't have visibility into how much each was responsible. One thing I could have done was copied the database and run locally with the Kadira CPU profiler.

Apollo server

I guess the Apollo equivalent is queries and resolvers. Is there a way to instrument for CPU, or can you just start and stop the v8-profiler? Instrumenting latency is helpful for working on response time โ€“ eg this query took X ms, and it was due to these db queries that took however long, some of which were in series (perhaps @arunoda /Kadira will be doing this?). And then the other thing to measure is the memory and cpu usage of whatever does the reactive part, so people have the information needed to decide what data in their app is worth โ€“ from a server resources perspective โ€“ being instantly reactive vs polling vs non-updating. And ideally you'd be able to measure this in your production environment (unlike Kadira CPU server profiler).

Related: profiling issue in apollo-client

Improve logging function

Take a more TypeScript approach to logging

export enum LogAction {
request, parse, validation, execute
}

export enum LogStep {
start, end
}

export interface LogMessage {
action: LogAction;
step: LogStep;
data?: Object;
}

export interface LogFunction {
(message: LogMessage);
}

export interface QueryOptions {
...
logFunction?: LogFunction;
...
}

Then use it like this:
logFunction({action: LogAction.request, step: LogStep.start});

This is more verbose but avoids string matching / parsing and makes it much easier for the consumer.

Feature Request: graphql Server Chaining

With the current focus on small independent microservices in the REST world it would be good to be able to chain multiple apollo servers together.

For instance you may have a single user repository in the company. A apollo server would expose a graphql endpoint to query and mutate these users.

An app server then needs to query this database for user name and address etc. the app server would expose via proxy a subset of queries from the user repository server with the schema being read from their.

The graphql proxy connector could then have extension points to transform the incoming/outcoming queries and results from the chained server.

Facebook OAuth example?

Hello guys, noob here, I'm trying to figure out how to do this right. I'm getting authenticated by Facebook without a problem, but when I got to the part of using the actual data from Facebook I got stuck... I've been copying from here and there. How would you go about using the info received from the OAuth thing?

Here's my code, I've been referencing GitHunt and Jonas' auth article mainly.

import express from 'express';
import path from 'path';
import uuid from 'node-uuid';

// GraphQL
import { apolloServer } from 'apollo-server';
import schema from './postgres/schema';
import resolvers from './postgres/resolvers';

// Webpack
import webpack from 'webpack';
import webpackMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
import config from '../webpack.config.dev.js';

// Authentication
import bodyParser from 'body-parser';
import cookieParser from 'cookie-parser';
import session from 'express-session';
import passport from 'passport';
import { Strategy as FacebookStrategy } from 'passport-facebook';

import facebookStrategyOptions from './auth/config';


// Knex Session
import knex from './postgres/connectors';
const KnexSessionStore = require('connect-session-knex')(session);
const store = new KnexSessionStore({ knex });

import { User } from './postgres/models/User';
const userModel = new User();


// Routes
import routes from './routes';
import facebook from './routes/auth/facebook';
import local from './routes/auth/local';


const GRAPHQL_PORT = 3000;

const app = express();

const compiler = webpack(config);

app.use(webpackMiddleware(compiler, {
    hot: true,
    noInfo: true,
    publicPath: config.output.publicPath,
    stats: {
        colors: true,
        timings: true,
        modules: false
    }
}));

app.use(webpackHotMiddleware(compiler));

// React front end
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, '../client/index.html'));
});

app.get('/logout', (req, res) => {
    req.logout();
    res.redirect('/');
});

app.use('/graphql', apolloServer({
    graphiql: true, 
    pretty: true,
    schema,
    resolvers
}));


// Authentication
app.use(session({
    saveUninitialized: true,
    resave: true,
    genid: req => {
         return uuid.v4();
    },
    secret: 'Z3]GJW!?9uPโ€/Kpe',
    store
}));

app.use(passport.initialize());
app.use(passport.session());

app.get('/login/facebook',
    passport.authenticate('facebook', {
        scope: ['email']
    }));

app.get('/login/facebook/callback',
    passport.authenticate('facebook', {
        failureRedirect: '/bleh',
        successRedirect: '/'
    }),
    (req, res) => res.redirect('/')
);

// Parsing
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

passport.use(new FacebookStrategy(facebookStrategyOptions, (accessToken, refreshToken, profile, cb) => {
    console.log(profile); // The info I need is there, but I can't figure out how to use it
    userModel.findFacebook(profile)
        .then(user => {
            if(user) {
                return done(null, user)
            }

            else {
                userModel.createFacebook(profile)
                .then(newUser => {
                    return done(null, newUser)
                })
            }
        })
        .catch(error => console.log('Oh no...',error));

    cb(null, profile);
}));

passport.serializeUser((user, cb) => cb(null, user));
passport.deserializeUser((obj, cb) => cb(null, obj));

app.listen(GRAPHQL_PORT, () => console.log(
    `GraphQL Server is now running on http://localhost:${GRAPHQL_PORT}/graphql`
));

Is application/graphql supported?

I'm guessing that I'm doing something dumb here, but I can't see it :( Would appreciate some pointers!

Requesting via the JSON protocol works great:

> curl -H "Content-Type:application/json" -XPOST -d '{"query": "{ currentUser { id } }"}' http://localhost:3000/graphql
{
  "data": {
    "currentUser": {
      "id": "f9342aa2-7674-4050-9e6c-559f14c46b52"
    }
  }
}

But when I attempt to use the application/graphql protocol, I get:

> curl -H "Content-Type:application/graphql" -XPOST -d "{ currentUser { id } }" http://localhost:3000/graphql
{
  "errors": [
    {
      "message": "Must provide query string."
    }
  ]
}

Factor out core to support HAPI, Express, Koa and others

Add support for the HAPI web framework while continuing support for Express. The intent here is to offer support for both frameworks in a consistently or such that the API works well with each framework and detects which binding is being used.

I believe it is likely we will need an integration with HAPI much like express-graphql.

Move express, hapi and koa to dev-dependencies

I just realized that these should be dev-dependencies, not dependencies. Anyone who installs apollo-server will have one of them installed anyway. We just need them to run tests (and for typings).

Schema Descriptions

Hello guys, I'm trying to find a way to include schema descriptions (the ones that pop out in Graphiql)

I know the graphql-js way, but couldn't figure out how to do it in Apollo.

var PlanetType = new GraphQLObjectType({
  name: 'Planet',
  description: // <----------- this thing
`A large mass, planet or planetoid in the Star Wars Universe, at the time of
0 ABY.`,
  fields: () => { }
})

File uploads

Is there any interest in having apollo server support file uploads like express-graphql does? I'm not sure if file uploads should really go through graphql, but if it's a feature many people want to use, we might consider implementing it.

GraphQL 0.6.0 compatibility

Hey,

I've been using Apollo server for mocking the Graphene GraphQL schema in frontend (js).

I'm using @include and @skip directives for querying, which seemed were not added into the buildASTSchema until 0.6, so apollo-server doesn't recognize when you use it when querying.

For fixing this you can mimic what express-graphql is doing in it's peer dependencies and update the graphql version in package.json to 0.6.0

https://github.com/graphql/express-graphql/blob/master/package.json#L99

Trouble in initial set up.

Hey there, I'm a beginner and I'm having trouble setting up.

import express from 'express';
import { apolloServer } from 'apollo-server';

import Schema from './schema';
import Resolvers from './resolvers';

const GRAPHQL_PORT = 3000;

const app = express();

app.use('/graphql', apolloServer({
  graphiql: true, 
  pretty: true,
  schema: Schema,
  resolvers: Resolvers
}));

app.listen(GRAPHQL_PORT, () => console.log(
  `GraphQL Server is now running on http://localhost:${GRAPHQL_PORT}/graphql`
));

I've installed everything but I get this weird error:

app.use('/graphql', (0, _apolloServer.apolloServer)({
                                                   ^

TypeError: (0 , _apolloServer.apolloServer) is not a function
    at Object.<anonymous> (server.js:11:21)
    at Module._compile (module.js:541:32)
    at loader (/Users/Empyreal/WebProjects/knex-2/node_modules/babel-register/lib/node.js:158:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/Empyreal/WebProjects/knex-2/node_modules/babel-register/lib/node.js:168:7)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Function.Module.runMain (module.js:575:10)
    at /Users/Empyreal/WebProjects/knex-2/node_modules/babel-cli/lib/_babel-node.js:160:24
    at Object.<anonymous> (/Users/Empyreal/WebProjects/knex-2/node_modules/babel-cli/lib/_babel-node.js:161:7)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.runMain (module.js:575:10)

__parseLiteral (custom validation) not called when using mutation variables

Hi!

I've added a custom scalar for email, with validation method inside the __parseLiteral function. However, when I use variables, __parseLiteral is not being called and it skips my validation. The value is returned immediately.

This works, runs email validation:

mutation {
  createUser(email: "[email protected]", password: "password") {
    user {
      id
      email
    }
  }
}

This does not work, skips email validation:

mutation($email: Email!, $password: Password!) {
  createUser(email: $email, password: $password) {
    user {
      id
      email
    }
  }
}

Variables sent:

{
  "email": "[email protected]",
  "password": "password"
}

Email scalar type

import {GraphQLError} from 'graphql/error';

import {isEmail} from '../../../utils/validations';

export default {
  __parseValue: (value) => value.toLowerCase(),
  __serialize: (value) => value.toLowerCase(),
  __parseLiteral: ({value}) => {
    if (!isEmail(value)) {
      throw new GraphQLError('Email is not valid.');
    }

    return value.toLowerCase();
  }
};

Really appreciate if you could look into this, thank you. Let me know if you need any more details.

Test coverage

We should make sure all significant logic is covered by tests. Right now the line coverage is close to 100%, but it seems some features aren't tested.

Making context available in schema parts resolvers

Hi, currently the context is not available when resolving parts of the schema.
This is sometimes needed. Actually in my case quite often, but maybe I'm doing something wrong.

Example:

type Schedule {
    _id: String
    name: String
    achievements: [Achievement]
  }

type Achievement {
 ...
}

In this case, when I resolve schedules achievements I want to resolve them for the currently logged in user. That is, I need userId to obtain achievements for the given schedule, this ID is available in the context.

Is this actually the place to do this? If not, what would be your recommendation?

Design principles

We need a doc about design principles for the apollo server

  • What are the guiding principles
  • How is Apollo server it different from GraphQL-JS / express-graphql
  • What features should Apollo server have?

Can't get meteor query result in resolver

root schema and resolver:

const rootSchema = `
   type RootQuery {
    user: User    
   ...
    allFeedbacks: [Feedback]
   }

   schema {
    query: RootQuery
  }
`


RootQuery: {
...

    async allFeedbacks(root, args, context) {
      const allFeedbacks = DB.Feedback.find({patientId: {$exists: 1}}).fetch()
      return await allFeedbacks
    },
...
}

feedback.js

export const schema = `
  type Feedback {
    _id: String
    patient: User
    opinion: String
    reply: String
  }
`;

export const resolvers = {
  Feedback: {
    _id  : ({_id}) => _id,
    patient: async ({patientId}) => {
      return await Meteor.users.findOne({_id:patientId})
    },
    opinion: ({opinion}) => opinion,
    reply: ({reply}) => reply,
  }
};

query in graphiql:
{ allFeedbacks { patient { username } _id opinion reply } }

Got result:

{
"data": {
"allFeedbacks": [
{
"patient": null,
"_id": "nyNP9wh9D5qmZixbn",
"opinion": "tesst",
"reply": "testst"
},
{
"patient": null,
"_id": "WgSoCgTGhHeZasFGQ",
"opinion": "tesst",
"reply": "testst"
},

...
}

It's strange when i test , the resolver could console log PatientId, Meteor, Meteor.users, But can't get the fetched data. I guess the problem is on async, but where is the problem?

Had checked sample repos, followed their pattern but no luck.

The Apollo Server GraphiQL interface specifies endpoint as undefined

I've hit a roadblock setting up HapiJS with the ApolloStack.

the error when I post to /graphql

{
  "errors": [
    {
      "message": "Cannot read property 'definitions' of undefined"
    }
  ]
}

With graphiql, the chrome console reports

2016-08-14 20:08:09.269 http://localhost:8000/undefined? Failed to load resource: the server responded with a status of 404 (Not Found)
2016-08-14 20:08:09.312 http://localhost:8000/undefined? Failed to load resource: the server responded with a status of 404 (Not Found)

I must have missed something.

my config

'use strict'

const Path = require('path')
const Hapi = require('hapi')

const { ApolloHAPI, GraphiQLHAPI } = require('apollo-server')

const { host, port } = require('./configs')

const { apolloOptions, graphiQLOptions } = require('./options/apollo')

const server = new Hapi.Server({
  connections: {
    routes: {
      files: {
        relativeTo: Path.join(__dirname, 'statics')
      }
    },
    router: {
      stripTrailingSlash: true
    }
  }
})

server.connection({ host, port: process.env.PORT || port })

// Plugins
const plugins = [
  {
    register: new ApolloHAPI(),
    options: apolloOptions,
    routes: { prefix: '/graphql' }
  },
  {
    register: new GraphiQLHAPI(),
    options: graphiQLOptions,
    routes: { prefix: '/graphiql' }
  },

]

server.register([...plugins], err => {
  if (err) throw err

  server.start(err => {
    if (err) throw err
    server.log('info', `Server running at ${server.info.uri}`) // eslint-disable-line
  })
})

the options passed in

const myGraphQLSchema = require('../schemas')

exports.apolloOptions = {
  schema: myGraphQLSchema
}

exports.graphiQLOptions = {
  endpointUrl: '/graphql'
}

My Schema

const {
  GraphQLObjectType,
  GraphQLSchema,
  GraphQLString,
  GraphQLInt,
  GraphQLList,
  GraphQLFloat,
  GraphQLEnumType,
  GraphQLNonNull,
  GraphQLInterfaceType
} = require('graphql')

const TodoType = new GraphQLEnumType({
  name: 'TodoType',
  description: 'A Type of the todo',
  values: {
    HOME: { value: 'home' },
    PLAY: { value: 'play' },
    WORK: { value: 'work' }
  }
})

const Todo = new GraphQLObjectType({
  name: 'Todo',
  description: 'Represent the todos',
  fields: () => ({
    _id: { type: GraphQLString },
    title: { type: GraphQLString },
    importance: { type: GraphQLInt },
    completed: { type: GraphQLInt },
    type: { type: TodoType },
    date: { type: GraphQLFloat },
  })
})

const TodoModel = require('../models/todos')

const Query = new GraphQLObjectType({
  name: 'MySchemaQuery',
  description: "Root of the My Schema",
  fields: () => ({
    todos: {
      type: new GraphQLList(Todo),
      description: "List of todos",
      args: {
        id: { type: GraphQLString },
        active: { type: GraphQLInt },
        importance: { type: GraphQLInt },
        type: { type: GraphQLString },
      },
      resolve: (source, { id, active, importance, type }) => {
        if (id) {
          return TodoModel.getById(id)
        } else if (active) {
          return TodoModel.activeTodos(active)
        } else if (importance) {
          return TodoModel.ofImportance(importance)
        } else if (type) {
          return TodoModel.ofType(type)
        } else {
          return TodoModel.allTodos();
        }
      }
    },

    todo: {
      type: Todo,
      description: "A todo",
      args: {
        id: { type: new GraphQLNonNull(GraphQLString) }
      },
      resolve: (source, { id }) =>
        TodoModel.getById(id)
    },

    latestTodos: {
      type: Todo,
      description: "Latest 5 todos added",
      resolve: () =>
        TodoModel.orderBy('id')
                  .limit(10)
                  .max('_id')
                  .run()
                  .then(todos => todos)
      }
    })
})

const Mutation = new GraphQLObjectType({
  name: "MySchemaMutations",
  fields: {
    createTodo: {
      type: Todo,
      description: "Create a new todo",
      args: {
        title: { type: new GraphQLNonNull(GraphQLString) },
        importance: { type: GraphQLInt },
        type: { type: new GraphQLNonNull(TodoType) }
      },
      resolve: (source, todo) => TodoModel.saveTodo(todo)
    }
  }
})

const Schema = new GraphQLSchema({
  query: Query,
  mutation: Mutation
});

module.exports = Schema

apolloOptions.context type and default value

By default context is undefined and has a type to any.

attachConnectorsToContext from graphql-tools works only with an object typed context.
If context is undefined, it will raise an error for each requests.

So, we have to explicitely set context to an empty object to make it working :

server.use('/', bodyParser.json(), apolloExpress({
  schema: executableSchema,
  context: {},
}));

Maybe apolloOptions.context can have a default value setted to {} and be explicitely typed as Object.

Support for deferred/partial responses

At some point in the future, apolloServer should support sending multiple partial responses (over a websocket connection for example). This issue is to keep that in mind while we build the first version which will not have such a feature.

Afterware for express?

Hi guys,

I'm try to implement 304 response to If-None-Match (by etag) from client.
And I need to calculate etag from response body around here if I understand it right.

So seem like I need an afterware supported there at server side. so the question is

  • Can I expect afterware supported there?
  • Or do I need to PR for afterware?

IMHO etag and last-modified is a must have (you guy aim for speed right?) so it should implement internally and can be turn on and off like express did for static etag do tell me if you want me to PR for 304 response internally instead of afterware approach.

Thanks

async / await ... how to build with babel

Hi, I'm trying to build an NPM package that would provide some helper functions for meteor users. The issue is thta no matter how I build it from ES6/7 code, the async await functions always complain about fibers and they do not work.

What is the babel config that would work?
Here is my .bablerc

{
  "presets": ["es2015", "stage-0"],
  "plugins": [
    ["transform-runtime", {
      "polyfill": false,
      "regenerator": true
    }]
  ]
}

Proposal: Restify support

Restify has been a popular option to create API servers a while back. As of today, at Jolicloud, we're using restify since it was decided a while back it was the right tool for the job. It is now wildly used in our codebase and we can't really detach ourselves from it.

Currently, we managed to get express-graphql work in it, even in production, but we'd like to have a really supported implementation with Apollo Server.

Since v0.2 was released, I was wondering if you planned to integrate it or if I could contribute by adding it as well.

Thank you!

Benefits over express-graphql

Why would one want to use this module instead of express-graphql?
On a first look it seems it's basically the same.

Install fails at postinstall script 'typings install && npm dedupe'.

Hi there, jus tried to install through npm and this happened:

I had to install typings to fix it.

> [email protected] postinstall /Users/Empyreal/WebProjects/knex-2/node_modules/apollo-server
> typings install && npm dedupe

sh: typings: command not found
npm WARN enoent ENOENT: no such file or directory, open '/Users/Empyreal/WebProjects/knex-2/node_modules/db/package.json'
npm WARN [email protected] requires a peer of eslint@^2.9.0 but none was installed.
npm WARN [email protected] requires a peer of eslint-plugin-jsx-a11y@^1.2.0 but none was installed.
npm WARN [email protected] requires a peer of eslint@^2.9.0 but none was installed.
npm WARN [email protected] No repository field.
npm ERR! Darwin 15.0.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "i" "-S" "apollo-server"
npm ERR! node v6.3.1
npm ERR! npm  v3.10.3
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn

npm ERR! [email protected] postinstall: `typings install && npm dedupe`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the [email protected] postinstall script 'typings install && npm dedupe'.

Feature request: Providing an array of resolvers

It would be really great if we could provide an array of resolvers and have them merged. Found myself in a scenario where I wanted to load the regular resolvers, but if the server was started with a certain flag it would load another set of resolvers which would override parts of the regular ones.

Specifically it would be great on the server to be able to provide an array of resolvers like so:

resolvers: [regularResolvers, sandboxResolvers]

In my case I needed sandboxResolvers to overwrite any resolvers with the same name in regularResolvers if a certain flag was set at server startup.

I tried with Object.assign but it didn't work in some situations. I'm doing it with deepmerge NPM for now. Would really appreciate any advice on how to do this in the best way until it's actually implemented as I'm out of my depth somewhat.

connector[connectorName] is not a function

I'm getting a weird error in initial apollo server setup which seems to be swallowed by the GraphQL layer and it is frustrating because I don't see how I can track it down. I thought all I was doing was roughly copying the example while renaming things, but I must have miscopied something somewhere.

{ "data": { "getUsers": null }, "errors": [ { "message": "connectors[connectorName] is not a function", "locations": [ { "line": 2, "column": 3 } ] } ] }

Line 2, column 3 of what? It is definitely not within my own code. That error is not too helpful. What should I be doing to track this down?

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.