Skip to main content

Architecture

Overview#

demo

Realtimely takes full advantage of the capabilities of AWS AppSync. The GraphQL endpoint generated by AppSync is connected by Apollo Client and the state is managed by React.

Backend#

DynamoDB#

DynamoDB is a key-value store scalable NoSQL database. There are HashKey and SortKey as keys of DynamoDB, and DB design is done so that this combination is unique. RealtimeCursor and OnlineUser have the following schema.

HashKeySortKey
URL#{URL}UserId#{UserId}

The actual values are entered in {URL} and {UserId}. For this key, the mouse cursor position (X, Y) and user information are saved as attributes. In other words, the latest data is always associated with this key and updated, so time-series data is not retained. This DB design is efficient and high performance because Realtimely's interest is always "now".

AppSync#

AppSync is a managed service for GraphQL servers. They have a feature to automatically generate GraphQL schema and resolver by connecting with DynamoDB table. Realtimely uses the automatically created schema and resolver with a little customization.

The following two resolvers are mainly used. (XXX is the table name)

  • createXXX
  • onCreateXXX

createXXX creates the resource and adds it to the DynamoDB table. The default resolver is implemented so that an error will occur if the same key exists, but it is customized and updated if the same key exists. Also, deleteTime is calculated from the current time.

onCreateXXX monitors the mutation of createXXX, and when this mutation is executed, the resource generated there is notified by Subscrition (Websocket). This allows you to deliver the created/updated data to the frontend.

Frontend#

Apollo Client#

It employs the Apollo Client to communicate with the AppSync endpoint.

React#

Realtimely manages state with React. Send the latest resource (for example, cursor position) with createXXX and receive the resource created with onCreateXXX. Received resources are managed in a list, and those that exceed the deleteTime are discarded to keep them up to date. By calling createXXX again within deleteTime, it will not disappear from the managed list. Conversely, for resources for which createXXX was not called within the deleteTime, it is determined that the user has already left the screen and will be invisible to other users.