Real-time Collaborative Drawing with GraphQL & AWS AppSync
Nader Dabit
Posted on March 11, 2019
To see the code for this & to launch this project, click here to go to the GitHub repo.
I am putting together a couple of demos for my upcoming talks at React Day Norway & React India.
For these talks I'm demoing interesting use cases of GraphQL & GraphQL subscriptions. Many of the ideas I have focus on the real-time aspect of GraphQL subscriptions because it enables us to build real-time functionality quite easily.
I stumbled across a library called react-canvas-draw that looked pretty cool. What I liked about it was that not only was it a library that allowed for drawing, but it saves the strokes in an array & then allows you to paint them back in the same sequence in which they were created!
This seemed like a perfect use case for my application. The data structure for the lines stored for painting on the canvas looks something like this:
{
lines: [
{ points: [{ x: 132, y: 144 }, { x: 133, y: 145 }], "brushColor":"#FF6D00","brushRadius": 4 },
{ points: [{ x: 132, y: 144 }, { x: 133, y: 145 }], "brushColor":"#000","brushRadius": 4 }
],
width: "400px",
height: "400px"
}
The basic thought I had was finding out some way to extract this data & update it in a GraphQL api, then when updated trigger a subscription. React Canvas Draw has a few methods that make this pretty easy. In fact, they expose quite a few methods that allow for full control over painting the canvas. Let's have a look at a couple of them that I used:
- getSaveData - This method gives us the current canvas state
- loadSaveData - This methods allows us to write an entire data set to the canvas
- simulateDrawingLines - This method writes a single line to the canvas
Now that we know how we're going to interact with the canvas, how are we going to interact with the GraphQL API?
To begin with, I created a basic schema:
type Canvas {
id: ID!
clientId: String!
data: String!
}
The main thing we need to keep up with is the unique id
of the canvas as well as the canvas data which we store in a field called data
.
Using AWS AppSync, we can scaffold out the rest of the Schema as well as the data sources & resolvers by adding the @model
directive when used with the Amplify CLI & GraphQL Transform library:
type Canvas @model {
id: ID!
clientId: String!
data: String!
}
Steps to build this from scratch
So to get this up & running, I created a new React application:
npx create-react-app canvas-app
Next, I initialized a new amplify project & then added the API & schema
amplify init
amplify add api
# When prompted, I use the schema I referenced above
amplify push
Finally, I created Canvas.js to hold all of the main code for my application & used this file as the main file in my application.
I then created a new file called RCD.js that holds the react-canvas-draw
library. I referenced it locally just in case I needed to make updates, but also to have it locally to be able to easily experiment with the different methods available.
That's it! Using GraphQL subscriptions makes it really easy to get up & running with real-time applications. If you have any questions about this, feel free to ping me any time.
My Name is Nader Dabit. I am a Developer Advocate at Amazon Web Services working with projects like AWS AppSync and AWS Amplify. I specialize in cross-platform & cloud-enabled application development.
Posted on March 11, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.