diff --git a/lib/configuration/hooks/router/index.js b/lib/configuration/hooks/router/index.js index eff22dd705..8d03e7fd50 100644 --- a/lib/configuration/hooks/router/index.js +++ b/lib/configuration/hooks/router/index.js @@ -95,6 +95,12 @@ module.exports = function (strapi) { yield strapi.middlewares.send(this, path.resolve(strapi.config.appPath, strapi.config.paths.static, 'admin', 'index.html')); }); + // Define GraphQL route with transformed Waterline models to GraphQL schema + strapi.router.get('/graphql', strapi.middlewares.graphql({ + schema: strapi.schemas, + pretty: true + })); + // Let the router use our routes and allowed methods. strapi.app.use(strapi.router.routes()); strapi.app.use(strapi.router.allowedMethods()); diff --git a/lib/configuration/hooks/waterline/index.js b/lib/configuration/hooks/waterline/index.js index f1677a9b1a..d4b02a7fa2 100644 --- a/lib/configuration/hooks/waterline/index.js +++ b/lib/configuration/hooks/waterline/index.js @@ -12,6 +12,7 @@ const spawn = require('child_process').spawnSync; const _ = require('lodash'); const async = require('async'); const Waterline = require('waterline'); +const WaterlineGraphQL = require('waterline-to-graphql'); // Local utilities. const helpers = require('./helpers/index'); @@ -178,6 +179,14 @@ module.exports = function (strapi) { association.nature = helpers.getAssociationType(model, association); }); }); + + // Create temporary object without associations collections + const collections = _.omit(_.clone(strapi.orm.collections), function (object, key) { + return key.indexOf('__') !== -1; + }); + + // Expose models as schemas for GraphQL. + strapi.schemas = WaterlineGraphQL.getGraphQLSchemaFrom(collections); } else { strapi.log.warn('Waterline ORM disabled!'); } diff --git a/lib/private/exposeGlobals.js b/lib/private/exposeGlobals.js index 2defee3b60..d3b19fd800 100755 --- a/lib/private/exposeGlobals.js +++ b/lib/private/exposeGlobals.js @@ -34,4 +34,23 @@ module.exports = function exposeGlobals() { if (self.config.globals.strapi !== false) { global.strapi = self; } + + if (self.config.globals.graphql !== false) { + global.graphql = require('graphql'); + + // Extend GraphQL framework + global.graphql.query = function * (query) { + const deferred = Promise.defer(); + + this.graphql(self.schemas, query) + .then(function (data) { + deferred.resolve(data); + }) + .catch(function (err) { + deferred.reject(err); + }); + + return deferred.promise; + }; + } }; diff --git a/package.json b/package.json index b8e43e9e12..26a7c7d38a 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "commander": "^2.8.1", "consolidate": "^0.13.1", "fs-extra": "^0.24.0", + "graphql": "^0.4.7", "include-all": "^0.1.6", "json-stringify-safe": "^5.0.1", "jsonwebtoken": "^5.4.0", @@ -48,6 +49,7 @@ "koa-compose": "^2.3.0", "koa-cors": "^0.0.16", "koa-favicon": "^1.2.0", + "koa-graphql": "^0.2.0", "koa-gzip": "^0.1.0", "koa-i18n": "^1.1.0", "koa-ip": "^0.1.0", @@ -87,6 +89,7 @@ "strapi-generate-users": "^1.1.0", "unzip2": "^0.2.5", "waterline": "^0.10.26", + "waterline-to-graphql": "0.0.2", "winston": "^1.0.2" }, "devDependencies": {