├── .babelrc ├── .gitignore ├── README.md ├── package.json ├── server.js └── src ├── resolvers.js └── schema.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "passPerPreset": true, 3 | "presets": [ 4 | "es2015", 5 | "stage-0" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | yarn.lock 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GraphQL-Express 2 | An simple Express Server implemented using GraphQL and Apollo. 3 | This repo is attached to a series of articles with detailed explanations of the implementations: 4 | 5 | Part 1: [Implementing GraphQL using APollo on an Express Server](https://scotch.io/tutorials/implementing-graphql-using-apollo-on-an-express-server) - Use the `master` branch. 6 | 7 | Part 2: [Creating GraphQL Subscriptions in Express](https://scotch.io/bar-talk/creating-graphql-subscriptions-in-express) - Use the `subscriptions` branch. 8 | 9 | The repo is also linked to another [GraphQL-React-Apollo](https://github.com/kimobrian/GraphQL-React-Apollo) with front end implementations ing React using Apollo with corresponding articles. 10 | ## Setup and Installation. 11 | 12 | > Note: Configure the port on the client code to match the CORs origin on this [line](https://github.com/kimobrian/GraphQL-Express/blob/f0ba47db3ae95c5b5f586f2870fa3e2c7cdb61cf/server.js#L13). 13 | 14 | ```sh 15 | git clone git@github.com:kimobrian/GraphQL-Express.git #for SSH 16 | 17 | git clone https://github.com/kimobrian/GraphQL-Express.git #for HTTPS 18 | 19 | cd GraphQL-Express 20 | 21 | npm i #Alternatively yarn 22 | 23 | npm start #Alternatively yarn start 24 | 25 | ``` 26 | 27 | For any issues with nodemon, install it globally. 28 | 29 | ```sh 30 | npm install nodemon -g # Alternatively yarn global add nodemon 31 | 32 | ``` 33 | 34 | Navigate to [localhost](http://localhost:7700/graphiql) to experiment with different queries. 35 | 36 | You can explore [npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) to avoid global installation of modules. 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tutorial-server", 3 | "version": "1.0.0", 4 | "description": "A simple GraphQL server", 5 | "main": "server.js", 6 | "scripts": { 7 | "start": "nodemon ./server.js --exec babel-node -e js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "babel-cli": "^6.24.0", 14 | "babel-preset-es2015": "^6.24.0", 15 | "babel-preset-stage-0": "^6.22.0", 16 | "nodemon": "^1.11.0" 17 | }, 18 | "dependencies": { 19 | "body-parser": "^1.17.1", 20 | "cors": "^2.8.3", 21 | "express": "^4.15.2", 22 | "graphql": "^0.9.1", 23 | "graphql-server-express": "^0.6.0", 24 | "graphql-tools": "^0.10.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import cors from 'cors'; 3 | import { 4 | graphqlExpress, 5 | graphiqlExpress, 6 | } from 'graphql-server-express'; 7 | import bodyParser from 'body-parser'; 8 | 9 | import { schema } from './src/schema'; 10 | 11 | const PORT = 7700; 12 | const server = express(); 13 | server.use('*', cors({ origin: 'http://localhost:7800' })); 14 | 15 | server.use('/graphql', bodyParser.json(), graphqlExpress({ 16 | schema 17 | })); 18 | 19 | server.use('/graphiql', graphiqlExpress({ 20 | endpointURL: '/graphql' 21 | })); 22 | 23 | server.listen(PORT, () => 24 | console.log(`GraphQL Server is now running on http://localhost:${PORT}`) 25 | ); 26 | -------------------------------------------------------------------------------- /src/resolvers.js: -------------------------------------------------------------------------------- 1 | const channels = [{ 2 | id: 1, 3 | name: 'soccer', 4 | }, { 5 | id: 2, 6 | name: 'baseball', 7 | }]; 8 | 9 | let nextId = 3; 10 | 11 | export const resolvers = { 12 | Query: { 13 | channels: () => { 14 | return channels; 15 | }, 16 | channel: (root, { id }) => { 17 | return channels.find(channel => channel.id == id); 18 | }, 19 | }, 20 | Mutation: { 21 | addChannel: (root, args) => { 22 | const newChannel = { id: nextId++, name: args.name }; 23 | channels.push(newChannel); 24 | return newChannel; 25 | }, 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /src/schema.js: -------------------------------------------------------------------------------- 1 | import { 2 | makeExecutableSchema, 3 | } from 'graphql-tools'; 4 | 5 | import { resolvers } from './resolvers'; 6 | 7 | const typeDefs = ` 8 | type Channel { 9 | id: ID! # "!" denotes a required field 10 | name: String 11 | messages: [Message]! 12 | } 13 | 14 | type Message { 15 | id: ID! 16 | text: String 17 | } 18 | # This type specifies the entry points into our API. In this case 19 | # there is only one - "channels" - which returns a list of channels. 20 | type Query { 21 | channels: [Channel] # "[]" means this is a list of channels 22 | channel(id: ID!): Channel 23 | } 24 | 25 | # The mutation root type, used to define all mutations. 26 | type Mutation { 27 | # A mutation to add a new channel to the list of channels 28 | addChannel(name: String!): Channel 29 | } 30 | `; 31 | 32 | const schema = makeExecutableSchema({ typeDefs, resolvers }); 33 | export { schema }; 34 | --------------------------------------------------------------------------------