A simpler interface to GraphQL
Install
- NPM -
npm install speako
Motivation
GraphQL normally requires a GraphQLSchema object passed along with each query
you give it to validate, interpret & execute. Typically this schema is constructed
by hand-crafting some verbose & noisy JavaScript.
See: starWarsSchema.js.
The equivalent schema in GraphQL Schema Language is much more concise:
enum Episode { NEWHOPE, EMPIRE, JEDI }
type Human {
id: ID!
name: String
friends: [Character]
appearsIn: [Episode]
homePlanet: String
}
type Droid {
id: ID!
name: String
friends: [Character]
appearsIn: [Episode]
primaryFunction: String
}
union Character = Human | Droid
Given a specification of a data model in GraphQL Schema Language, speako automatically
generates the GraphQLSchema instance that GraphQL requires and binds its resolve methods
to a specified set of functions for querying (i.e., selecting) and mutating (i.e., insert,
update and delete mutations).
Example
$ node --harmony-destructuring > var speako = require('speako'); > var gql = require('graphql'); > var _ = require('lodash'); > var labels = [ ... {'id': 1, 'name': 'Apple Records', 'founded': '1968'}, ... {'id': 2, 'name': 'Harvest Records', 'founded': '1969'}]; > var albums = [ ... {'id': 1, 'name': 'Dark Side Of The Moon', 'releaseDate': 'March 1, 1973', ... 'artist': 'Pink Floyd', 'label': labels[1]}, ... {'id': 2, 'name': 'The Beatles', 'releaseDate': 'November 22, 1968', ... 'artist': 'The Beatles', 'label': labels[0]}, ... {'id': 3, 'name': 'The Wall', 'releaseDate': 'August 1, 1982', ... 'artist': 'Pink Floyd', 'label': labels[1]}]; > var dataResolver = {"query": function (typename, predicate) { ... console.assert(typename == "Album"); ... var parsed = JSON.parse(predicate); ... if (_.isEqual(parsed, {"all": true})) return albums; ... else { ... var pairs = _.toPairs(parsed); ... var filters = pairs.map(function (p) { ... var [field, value] = p; ... if (typeof value === "object") { ... console.assert(field == "label"); ... return function(elem) { ... var innerKey = _.first(_.keys(value)); ... return elem[field][innerKey] == value[innerKey]; }; ... } ... return function(elem) { return elem[field] == value; }; ... }); ... return albums.filter(function(elem) { return filters.every(function(f) { return f(elem); }); }); ... } ... }, "create": function (typename, inputs) { ... inputs.id = albums.length + 1; ... albums.push(inputs); ... return inputs; ... }}; > var schema = speako.getSchema(dataResolver, ... "type Album { id: ID! name: String releaseDate: String artist: String }"); > var schema = ... speako.getSchema(dataResolver, ... ["type Label { id: ID! name: String founded: String album: Album } ", ... "type Album { id: ID! name: String releaseDate: String artist: String label: Label }"].join(" ")); > var printer = function(res) { console.log(JSON.stringify(res, null, 2)); }; > gql.graphql(schema, ... "{ Album(artist: \"Pink Floyd\", label: { name: \"Harvest Records\" }) { name artist releaseDate } }") .then(printer); { "data": { "Album": [ { "name": "Dark Side Of The Moon", "artist": "Pink Floyd", "releaseDate": "March 1, 1973" }, { "name": "The Wall", "artist": "Pink Floyd", "releaseDate": "August 1, 1982" } ] } } > gql.graphql(schema, "{ Album(artist: \"Pink Floyd\") { name artist releaseDate } }").then(printer); { "data": { "Album": [ { "name": "Dark Side Of The Moon", "artist": "Pink Floyd", "releaseDate": "March 1, 1973" }, { "name": "The Wall", "artist": "Pink Floyd", "releaseDate": "August 1, 1982" } ] } } > gql.graphql(schema, "{ Album(artist: \"Pink Floyd\", name: \"The Wall\") { name artist releaseDate } }").then(printer); { "data": { "Album": [ { "name": "The Wall", "artist": "Pink Floyd", "releaseDate": "August 1, 1982" } ] } } > gql.graphql(schema, "{ Album(id: 2) { name artist releaseDate } }").then(printer); { "data": { "Album": [ { "name": "The Beatles", "artist": "The Beatles", "releaseDate": "November 22, 1968" } ] } } > gql.graphql(schema, "{ Albums { name artist releaseDate } }").then(printer); { "data": { "Albums": [ { "name": "Dark Side Of The Moon", "artist": "Pink Floyd", "releaseDate": "March 1, 1973" }, { "name": "The Beatles", "artist": "The Beatles", "releaseDate": "November 22, 1968" }, { "name": "The Wall", "artist": "Pink Floyd", "releaseDate": "Auguest 1, 1982" } ] } } > gql.graphql(schema, "mutation m { createAlbum(name:\"The Division Bell\", releaseDate: \"March 28, 1994\", artist:\"Pink Floyd\") { id name } }").then(printer); { "data": { "createAlbum": { "id": "4", "name": "The Division Bell" } } }
Copyright (c) 2015 Jonathan L. Leonard