Skip to content
This repository has been archived by the owner on Sep 3, 2021. It is now read-only.

Commit

Permalink
@publish & @subscribe directives, nested @cypher mutation revision (#580
Browse files Browse the repository at this point in the history
)

* fixes relation directive direction argument

* adds pubsub config to middleware server

* fixes relation directive direction argument

exports pubsub to the apollo-server and apollo-server-express example servers to be used by augmentation config and custom subscription resolvers

* fixes relation directive direction argument

* adds abstract subscription handlers to augmentation config

* updates relation directive direction argument

* lockfile update

* adds .subscription to configuration key enum

* adds publish and subscribe directive definitions and helpers

* generates default subscription resolvers

* adds publish directive to generated mutations

* adds publish directive to generated relationship mutations

* generates default mutation subscriptions

* Update index.js

* moved

* moved

* revision of custom nested mutations

* updates relation directive direction argument

* adds schema for some new custom nested mutation tests

* updates relation directive direction argument

* Update augmentSchemaTest.test.js

* Update augmentSchemaTest.test.js

* Update cypherTest.test.js

* Update movies-schema.js

* Update directives.js

* Update resolvers.js

* Update augmentSchemaTest.test.js

* Update augmentSchemaTest.test.js

* fixes gateway subscription error

also trying to fix dependency merge conflict

* fixes misplaced branch that checks for event publisher function

* revision of setDefaultConfig

* augmentation test updates for changing default subscription config
  • Loading branch information
michaeldgraham authored Mar 7, 2021
1 parent beb00e6 commit 36a754a
Show file tree
Hide file tree
Showing 26 changed files with 5,324 additions and 4,611 deletions.
1 change: 1 addition & 0 deletions example/apollo-federation/services/accounts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const accountsSchema = buildFederatedSchema([
`,
{
isFederated: true
// subscription: false // default is false
}
),
resolvers: {
Expand Down
1 change: 1 addition & 0 deletions example/apollo-federation/services/inventory/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export const inventorySchema = buildFederatedSchema([
},
config: {
isFederated: true
// subscription: false, // default is false
// debug: true
}
})
Expand Down
3 changes: 2 additions & 1 deletion example/apollo-federation/services/products/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export const productsSchema = buildFederatedSchema([
}
`,
config: {
isFederated: true
isFederated: true,
subscription: false
// debug: true
}
})
Expand Down
3 changes: 2 additions & 1 deletion example/apollo-federation/services/reviews/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ export const reviewsSchema = buildFederatedSchema([
}
},
config: {
isFederated: true
isFederated: true,
subscription: false
// debug: true
}
})
Expand Down
22 changes: 11 additions & 11 deletions example/apollo-server/bookmarks.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ type Person {
_id: Long!
born: Int
name: String!
acted_in: [Movie] @relation(name: "ACTED_IN", direction: "OUT")
acted_in: [Movie] @relation(name: "ACTED_IN", direction: OUT)
ACTED_IN_rel: [ACTED_IN]
directed: [Movie] @relation(name: "DIRECTED", direction: "OUT")
produced: [Movie] @relation(name: "PRODUCED", direction: "OUT")
wrote: [Movie] @relation(name: "WROTE", direction: "OUT")
follows: [Person] @relation(name: "FOLLOWS", direction: "OUT")
reviewed: [Movie] @relation(name: "REVIEWED", direction: "OUT")
directed: [Movie] @relation(name: "DIRECTED", direction: OUT)
produced: [Movie] @relation(name: "PRODUCED", direction: OUT)
wrote: [Movie] @relation(name: "WROTE", direction: OUT)
follows: [Person] @relation(name: "FOLLOWS", direction: OUT)
reviewed: [Movie] @relation(name: "REVIEWED", direction: OUT)
REVIEWED_rel: [REVIEWED]
}
Expand All @@ -22,11 +22,11 @@ type Movie {
released: Int!
tagline: String
title: String!
persons_acted_in: [Person] @relation(name: "ACTED_IN", direction: "IN")
persons_directed: [Person] @relation(name: "DIRECTED", direction: "IN")
persons_produced: [Person] @relation(name: "PRODUCED", direction: "IN")
persons_wrote: [Person] @relation(name: "WROTE", direction: "IN")
persons_reviewed: [Person] @relation(name: "REVIEWED", direction: "IN")
persons_acted_in: [Person] @relation(name: "ACTED_IN", direction: IN)
persons_directed: [Person] @relation(name: "DIRECTED", direction: IN)
persons_produced: [Person] @relation(name: "PRODUCED", direction: IN)
persons_wrote: [Person] @relation(name: "WROTE", direction: IN)
persons_reviewed: [Person] @relation(name: "REVIEWED", direction: IN)
}
type ACTED_IN @relation(name: "ACTED_IN") {
Expand Down
40 changes: 36 additions & 4 deletions example/apollo-server/movies-middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,27 @@ import { ApolloServer } from 'apollo-server-express';
import express from 'express';
import bodyParser from 'body-parser';
import neo4j from 'neo4j-driver';
import { typeDefs, resolvers } from './movies-schema';
import { typeDefs, resolvers, pubsub } from './movies-schema';
import http from 'http';

const PORT = 3000;

const schema = makeAugmentedSchema({
typeDefs,
resolvers
resolvers,
config: {
subscription: {
publish: (event, key, data) => {
pubsub.publish(event, {
[key]: data
});
},
subscribe: events => {
return pubsub.asyncIterator(events);
},
exclude: ['User']
}
}
});

const driver = neo4j.driver(
Expand Down Expand Up @@ -35,10 +51,26 @@ const server = new ApolloServer({
context: ({ req }) => {
return {
driver,
req
req,
cypherParams: {
userId: 'user-id'
}
};
}
});

server.applyMiddleware({ app, path: '/' });
app.listen(3000, '0.0.0.0');

// See: https://www.apollographql.com/docs/apollo-server/data/subscriptions/#subscriptions-with-additional-middleware
const httpServer = http.createServer(app);
server.installSubscriptionHandlers(httpServer);

// ⚠️ Pay attention to the fact that we are calling `listen` on the http server variable, and not on `app`.
httpServer.listen(PORT, '0.0.0.0', () => {
console.log(
`🚀 Server ready at http://localhost:${PORT}${server.graphqlPath}`
);
console.log(
`🚀 Subscriptions ready at ws://localhost:${PORT}${server.subscriptionsPath}`
);
});
32 changes: 23 additions & 9 deletions example/apollo-server/movies-schema.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { neo4jgraphql } from '../../src/index';
import { PubSub } from 'apollo-server';

export const pubsub = new PubSub();

export const typeDefs = `
type Movie {
Expand All @@ -13,13 +16,13 @@ type Movie {
poster: String
imdbRating: Float
ratings: [Rated]
genres: [Genre] @relation(name: "IN_GENRE", direction: "OUT")
genres: [Genre] @relation(name: "IN_GENRE", direction: OUT)
similar(first: Int = 3, offset: Int = 0, limit: Int = 5): [Movie] @cypher(statement: "MATCH (this)--(:Genre)--(o:Movie) RETURN o LIMIT $limit")
mostSimilar: Movie @cypher(statement: "RETURN this")
degree: Int @cypher(statement: "RETURN SIZE((this)--())")
actors(first: Int = 3, offset: Int = 0): [Actor] @relation(name: "ACTED_IN", direction:"IN")
actors(first: Int = 3, offset: Int = 0): [Actor] @relation(name: "ACTED_IN", direction:IN)
avgStars: Float
filmedIn: State @relation(name: "FILMED_IN", direction: "OUT")
filmedIn: State @relation(name: "FILMED_IN", direction: OUT)
location: Point
locations: [Point]
scaleRating(scale: Int = 3): Float @cypher(statement: "RETURN $scale * this.imdbRating")
Expand All @@ -29,7 +32,7 @@ type Movie {
type Genre {
name: String
movies(first: Int = 3, offset: Int = 0): [Movie] @relation(name: "IN_GENRE", direction: "IN")
movies(first: Int = 3, offset: Int = 0): [Movie] @relation(name: "IN_GENRE", direction: IN)
highestRatedMovie: Movie @cypher(statement: "MATCH (m:Movie)-[:IN_GENRE]->(this) RETURN m ORDER BY m.imdbRating DESC LIMIT 1")
}
Expand All @@ -45,8 +48,8 @@ interface Person {
type Actor {
id: ID!
name: String
movies: [Movie] @relation(name: "ACTED_IN", direction: "OUT")
knows: [Person] @relation(name: "KNOWS", direction: "OUT")
movies: [Movie] @relation(name: "ACTED_IN", direction: OUT)
knows: [Person] @relation(name: "KNOWS", direction: OUT)
}
type User implements Person {
Expand Down Expand Up @@ -115,10 +118,10 @@ type NewCamera implements Camera {
type CameraMan implements Person {
userId: ID!
name: String
favoriteCamera: Camera @relation(name: "favoriteCamera", direction: "OUT")
favoriteCamera: Camera @relation(name: "favoriteCamera", direction: OUT)
heaviestCamera: [Camera] @cypher(statement: "MATCH (c: Camera)--(this) RETURN c ORDER BY c.weight DESC LIMIT 1")
cameras: [Camera!]! @relation(name: "cameras", direction: "OUT")
cameraBuddy: Person @relation(name: "cameraBuddy", direction: "OUT")
cameras: [Camera!]! @relation(name: "cameras", direction: OUT)
cameraBuddy: Person @relation(name: "cameraBuddy", direction: OUT)
}
union MovieSearch = Movie | Genre | Book | User | OldCamera
Expand All @@ -135,12 +138,23 @@ type Query {
}
type Mutation {
CustomWithPublish: String @publish(event: "customEventName") @cypher(statement: "RETURN 'hello world'")
CustomCamera: Camera @cypher(statement: "CREATE (newCamera:Camera:NewCamera {id: apoc.create.uuid(), type: 'macro'}) RETURN newCamera")
CustomCameras: [Camera] @cypher(statement: "CREATE (newCamera:Camera:NewCamera {id: apoc.create.uuid(), type: 'macro', features: ['selfie', 'zoom']}) CREATE (oldCamera:Camera:OldCamera {id: apoc.create.uuid(), type: 'floating', smell: 'rusty' }) RETURN [newCamera, oldCamera]")
}
type Subscription {
subscribeToCustomWithPublish: String @subscribe(to: "customEventName")
}
`;

export const resolvers = {
Subscription: {
// normally generated
subscribeToCustomWithPublish: {
subscribe: () => pubsub.asyncIterator(['customEventName'])
}
},
// root entry point to GraphQL service
Query: {
Movie(object, params, ctx, resolveInfo) {
Expand Down
8 changes: 4 additions & 4 deletions example/apollo-server/movies-typedefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ type Movie {
poster: String
imdbRating: Float
ratings: [Rated]
genres: [Genre] @relation(name: "IN_GENRE", direction: "OUT")
actors: [Actor] @relation(name: "ACTED_IN", direction: "IN")
genres: [Genre] @relation(name: "IN_GENRE", direction: OUT)
actors: [Actor] @relation(name: "ACTED_IN", direction: IN)
}
type Genre {
name: String
movies: [Movie] @relation(name: "IN_GENRE", direction: "IN")
movies: [Movie] @relation(name: "IN_GENRE", direction: IN)
}
type Actor {
id: ID!
name: String
movies: [Movie] @relation(name: "ACTED_IN", direction: "OUT")
movies: [Movie] @relation(name: "ACTED_IN", direction: OUT)
}
type User {
userId: ID!
Expand Down
16 changes: 14 additions & 2 deletions example/apollo-server/movies.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { augmentTypeDefs, augmentSchema } from '../../src/index';
import { ApolloServer, gql, makeExecutableSchema } from 'apollo-server';
import neo4j from 'neo4j-driver';
import { typeDefs, resolvers } from './movies-schema';
import { typeDefs, resolvers, pubsub } from './movies-schema';

const schema = makeExecutableSchema({
typeDefs: augmentTypeDefs(typeDefs),
Expand All @@ -12,7 +12,19 @@ const schema = makeExecutableSchema({
});

// Add auto-generated mutations
const augmentedSchema = augmentSchema(schema);
const augmentedSchema = augmentSchema(schema, {
subscription: {
publish: (event, key, data) => {
pubsub.publish(event, {
[key]: data
});
},
subscribe: events => {
return pubsub.asyncIterator(events);
},
exclude: ['User']
}
});

const driver = neo4j.driver(
process.env.NEO4J_URI || 'bolt://localhost:7687',
Expand Down
12 changes: 6 additions & 6 deletions example/apollo-server/multidatabase.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,28 @@ const typeDefs = `
type User {
name: String!
wrote: [Review] @relation(name: "WROTE", direction: "OUT")
wrote: [Review] @relation(name: "WROTE", direction: OUT)
}
type Review {
date: Date!
reviewId: String!
stars: Float!
text: String
reviews: [Business] @relation(name: "REVIEWS", direction: "OUT")
users: [User] @relation(name: "WROTE", direction: "IN")
reviews: [Business] @relation(name: "REVIEWS", direction: OUT)
users: [User] @relation(name: "WROTE", direction: IN)
}
type Category {
name: String!
business: [Business] @relation(name: "IN_CATEGORY", direction: "IN")
business: [Business] @relation(name: "IN_CATEGORY", direction: IN)
}
type Business {
address: String!
city: String!
location: Point!
name: String!
state: String!
in_category: [Category] @relation(name: "IN_CATEGORY", direction: "OUT")
reviews: [Review] @relation(name: "REVIEWS", direction: "IN")
in_category: [Category] @relation(name: "IN_CATEGORY", direction: OUT)
reviews: [Review] @relation(name: "REVIEWS", direction: IN)
}
`;

Expand Down
Loading

0 comments on commit 36a754a

Please sign in to comment.