Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add GraphQL Endpoint #86

Open
wants to merge 4 commits into
base: devlop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,26 @@ The SSE new and improved unified API.
---
## Development

### Prerequisites
You'll need to have Node 8 and [PostgreSQL](https://www.postgresql.org/download/) installed on your computer.
You'll need to create a PostgreSQL database named `node_api`.

If you're using macOS, [Postgres.app](https://postgresapp.com) and [Postico](https://eggerapps.at/postico) are friendly, easy-to-use tools for running PostgreSQL.

### Running the app
1. `npm install`
2. `mkdir keys`
3. `npm run keygen`
4. `npm run bootstrap -- --admin:firstName [YOUR NAME] --admin:lastName [YOUR LAST NAME] --admin:dce [YOUR DCE] --keygen --seed` - Migrates the database. If you specify the admin args, a membership will be created for that
user with all permissions. If you specify keygen, all keys will be regenerated. If you specify seed it will seed the database.
5. `npm start`

#### Additional Notes
1. `PORT="2222" npm start` - Run the server on a different port.

### Testing
Testing requires a PostgreSQL database named `node_api_test` to exist.

### API Reference
[Apiary Docs](http://docs.sse.apiary.io)

Expand Down Expand Up @@ -84,19 +104,3 @@ Only need to do this if you are working on scoreboard-related endpoints.
* You'll receive an email from Mailgun asking you to confirm that you want to receive test emails from this Mailgun account. Accept this request.
* Set the ENV variable `MAILGUN_DOMAIN` with the sandbox domain, and set the ENV variable `MAILGUN_SECRET` with the API key for this sandbox.
* When testing scoreboard-related endpoints (i.e. approving memberships), make sure the test user you're using has your email associated with it, so that you'll receive the test emails.

### Running the app
1. `npm install`
2. `npm run keygen`
3. `npm run bootstrap -- --admin:firstName [YOUR NAME] --admin:lastName [YOUR LAST NAME] --admin:dce [YOUR DCE] --keygen --seed` - Creates and migrates the database. If you specify the admin args, a membership will be created for that
user with all permissions. If you specify keygen, all keys will be regenerated.
If you specify seed it will seed the database.
4. `npm start`

### Additional Notes
1. `PORT="2222" npm start` - Run the server on a different port.

### Testing
Testing requires a PostgreSQL database named `node_api_test` to exist. This means you'll have to [install and run PostgreSQL](https://www.postgresql.org/download/) on your development computer.

If you're using macOS, [Postgres.app](https://postgresapp.com) and [Postico](https://eggerapps.at/postico) are friendly, easy-to-use tools for running PostgreSQL.
3 changes: 3 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ import nconf from './config';
import router from './routes';
import './models';
import './events';
import apollo from './graphql';

const app = express();

apollo.applyMiddleware({ app });

const env = nconf.get('NODE_ENV');
const apiConfig = nconf.get('api');
const apiPath = `/${apiConfig.prefix}/${apiConfig.version}`;
Expand Down
4 changes: 2 additions & 2 deletions config/database/configs/development.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"dialect": "sqlite",
"storage": "db/development.db"
"dialect": "postgres",
"database": "node_api"
}
13 changes: 13 additions & 0 deletions db/migrations/20190425200659-add-uuid-to-events.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export function up(queryInterface, Sequelize) {
return queryInterface.sequelize.query('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";')
.then(() => queryInterface.addColumn('events', 'uuid', {
type: Sequelize.UUID,
defaultValue: Sequelize.literal('uuid_generate_v4()'),
allowNull: false,
unique: true,
}));
}

export function down(queryInterface) {
return queryInterface.removeColumn('events', 'uuid');
}
16 changes: 16 additions & 0 deletions graphql/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { ApolloServer } from 'apollo-server-express';

import models from '../models';

import { typeDefs } from './schema';
import resolvers from './resolvers';

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

export default server;
30 changes: 30 additions & 0 deletions graphql/resolvers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { GraphQLDateTime } from 'graphql-iso-date';
import { fromGlobalId } from 'graphql-relay';

const resolvers = {
DateTime: GraphQLDateTime,
Committee: {
async isActive(committee, _, { models }) {
const numActiveOfficers = models.Officer
.scope({ method: ['active', new Date()] })
.count({ where: { committeeName: committee.name } });
return numActiveOfficers > 0;
},
},
Event: {
committee(event) {
return event.getCommittee();
},
},
Query: {
event(_, { id }, { models }) {
return models.Event.findOne({
where: {
uuid: fromGlobalId(id).id,
},
});
},
},
};

export default resolvers;
24 changes: 24 additions & 0 deletions graphql/schema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { gql } from 'apollo-server-express';

// eslint-disable-next-line import/prefer-default-export
export const typeDefs = gql`
scalar DateTime

type Committee {
name: String!
description: String
isActive: Boolean!
}

type Event {
name: String!
description: String
startDate: DateTime!
endDate: DateTime!
committee: Committee!
}

type Query {
event(id: ID!): Event
}
`;
12 changes: 12 additions & 0 deletions models/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,15 @@ User.hasMany(Headcount);
User.hasMany(Membership);
User.hasMany(Mentor);
User.hasMany(Officer);

const models = {
Committee,
Event,
Membership,
Officer,
Quote,
Tag,
User,
};

export default models;
Loading