This example demonstrates how to use subscriptions and the Graphcool event system.
The services contains is based on the data model (defined in types.graphql) for a simple blogging application:
type User @model {
id: ID! @isUnique
name: String!
articles: [Article!]! @relation(name: "UserArticles")
}
type Article @model {
id: ID! @isUnique
title: String!
author: User! @relation(name: "UserArticles")
}Whenever a new User is created in the database, a subscription is triggered that will automatically create an initial Article for the new User.
Read the last section of this README to learn how the different components fit together.
.
├── README.md
├── graphcool.yml
├── node_modules
├── package.json
├── src
│ ├── createFirstArticle.graphql
│ └── createFirstArticle.js
└── types.graphql
Read more about service configuration in the docs.
Clone the full graphcool repository and navigate to this directory or download only this example with the following command:
curl https://codeload.github.com/graphcool/graphcool/tar.gz/master | tar -xz --strip=2 graphcool-master/examples/subscriptions
cd subscriptionsNext, you need to create your GraphQL server using the Graphcool CLI.
If you haven't already, go ahead and install the CLI first:
npm install -g graphcoolYou can now deploy the Graphcool service that's defined in this directory. Before that, you need to install the node dependencies for the subscription function:
yarn install # install dependencies
graphcool deploy # deploy serviceNote: Whenever you make changes to files in this directory, you need to invoke
graphcool deployagain to make sure your changes get applied to the "remote" service.
That's it, you're now ready to send queries and mutations against your GraphQL API! 🎉
The easiest way to test the deployed service is by using a GraphQL Playground.
You can open a Playground with the following command:
graphcool playgroundIn the Playground, you can now send a query to retrieve all the User nodes, including the related Article nodes:
{
allUsers {
name
articles {
title
}
}
}As expected, the server only responds with an empty list of User nodes:
{
"data": {
"allUsers": []
}
}Now, you're going to create a new User node in the database. Since you also have a subscription configured (in graphcool.yml) which fires upon User.create-events, this operation will invoke the corresponding function (implemented in createFirstArticle.js):
mutation {
createUser(name: "Sarah") {
id
}
}After you've sent this mutation, you can go back and send the previous allUsers-query again. This time, the response will look like this:
{
"data": {
"allUsers": [{
"name": "Sarah",
"articles": [{
"title": "My name is Sarah, and this is my first article!"
}]
}]
}
}This example demonstrates how to use Graphcool's subscription functions. There's a single subscription configured inside the service definition file graphcool.yml.
The subscription query defined in createFirstArticle.graphql determines:
- when the corresponding
handlerfunction will be invoked (i.e. what kind of event you're actually subscribing to). - the input type for the
handlerfunction. All fields that are specified in the selection set of the subscription query will be carried by theeventthat's passed into thehandlerfunction.
Here's what the subscription query looks like:
subscription {
User(filter: {
mutation_in: [CREATED]
}) {
node {
id
name
}
}When the subscription gets deployed, it will wait for CREATED-events of the User type. Whenever that event occurs (triggered through a createUser-mutation), the corresponding handler function is invoked.
This is the implementation of the handler:
const { fromEvent } = require('graphcool-lib')
module.exports = event => {
// Retrieve payload from event
const { id, name } = event.data.User.node
// Create Graphcool API (based on https://github.com/graphcool/graphql-request)
const graphcool = fromEvent(event)
const api = graphcool.api('simple/v1') // `api` has a connection to your service's API
// Create variables for mutation
const title = `My name is ${name}, and this is my first article!`
const variables = { authorId: id title }
// Create mutation
const createArticleMutation = `
mutation ($title: String!, $authorId: ID!) {
createArticle(title: $title, authorId: $authorId) {
id
}
}
`
// Send mutation with variables
return api.request(createArticleMutation, variables)
}