Build a serverless Quiz in days with React and AWS Amplify DataStore
Tags: aws, serverless, amplify, react
Published: 2020-04-26 19:27:38

The covid-19 has a positive flipside! People are getting more creative and looking for other opportunities to connect with each other. I am an engineering lead responsible for IT strategy of a large bank. Suddenly, everyone in our teams had to work from home. Together with my colleague @gijsvdhoven we wanted to still bring fun to people and connect them. 

We had an idea to create an online pub quiz for than 150 people. Of course there are tools like Kahoot, but we also liked the idea and challenge that we build our own solution and use that. 

In three weeks during the evenings and weekends we have build a complete serverless quiz app. I can tell you (have played it a few times now with friends), it really brings fun in combination with Skype or Zoom. 

# Technology
We are using open source technology. We decided to use an Web app so that we don't add an extra limitation for users to first download an app from the stores. Maybe we add an app later as an option. 

### Front End - ReactJS
We are using React. We first have build it in Gatsby, but we noticed that this was an overkill, because React full-fill the job where we can use the lifecycle components and react hooks easily. 

### Back End - AWS Amplify 
With this framework you can very easy set up your backend and connect it to any front end framework. AWS Amplify has been developed for developers and is the glue between your front end applications and the most important services of AWS. 

We are using Graphql for the API's, DynamoDB to store the data, Cognito for the authentication, predictions to identify the language of the questions and AWS amplify hosting to deploy our content and serve to our customers. 

### AWS Amplify Datastore
Datastore is a service where the Amplify team worked very hard on the last years and has been launched during the last Re:Invent in 2019. 

> Amplify DataStore provides a programming model for leveraging shared and distributed data without writing additional code for offline and online scenarios, which makes working with distributed, cross-user data just as simple as working with local-only data. https://docs.amplify.aws/lib/datastore/getting-started/q/platform/js

We needed a solution for our quiz that in milliseconds receives data from multi clients and send data across to multi clients and this al comes together in a realtime dashboard for the quiz admin so that the quiz can be controlled. This is something that datastore is offering. 



# Architecture

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ukkl0jdxf1000h6fjnp6.jpg)

The content is served from AWS amplify to our customers. On the website users authenticate via **Cognito**, they receive a token. With this token it is possible to apply API requests. We have build the API's with **AppSync** (Graphql). With AppSync you define a schema and with that schema your **DynamoDB database**, API's and access control will be provisioned. We are using an API to **identify the language** of a question and save that to the database. 

# Features

We have build a game and admin area. In the admin area users can create a quiz, add questions to the quiz and library and run the quiz. We use predictions to identify the language and add that label to the question.  In the admin area you find the game code which you can send to all your users. 

The game area can be accessed with a name and game code. Then you see a start title. As soon as the admin starts the game the first questions will be send to all the clients and showed. Then users can respond with the right answer, and based on the time of the response the score will be send to the admin and all clients. This repeats till the quiz will be finished.  

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/j3v6p951bhpip8s59zi5.png)

# What we have learned? 

- Datastore is easy and fast to set up
- Add **DataStore.configure(awsConfig)** and **DataStore.observe...** to your app.js to init the Datastore
- Seamless and well performing syncing between clients and server
- A scalable solution where we don't need to configure anything separately for
- We struggled with relations, which are more used before datastore was launched. A relation (@connection) include other model data in the same request. With datastore you already have the data locally so you don't have to do an additional network request. We have skipped the @connection now and made a reference ID fields in the models to other models.
- Every data in the model is locally. Datastore is not supporting multi tenant, so you receive all the data from all quizes. When this will be heavily used this will give performance issues. The Amplify team is now working in supporting this, so we are looking forward for the next releases.
- AWS Amplify Datastore is using the HTML5 IndexedDB. It is not clear in  the docs if there are additional security measurements from Datastore on top of IndexedDB. 

# Open Sourcing

We are running the quiz on www.kwizz.guru and we are open sourcing this project. Our idea is that these kind of quizes and fun should be available to everyone. As long as the AWS bill will not be sky high, we are going to host this but it's free for everyone to host your own version on your own domain. 

It would be great if the the community can contribute to improve UX, the quality of code, add automated tests, docs and add new features.

Check our repository and please contribute: https://github.com/alowa-apps/kwizz

# What's next?
We are also working on creating a full swing Expo base app which you can use to authenticate with AWS Amplify and Cognito. We are adding default cypress test cases which will run in Expo web. Soon @gijsvdhoven will write a blog about this, but check it out already: https://github.com/alowa-apps/baseApp

If you have questions, let us know in the comments and we are looking forward for your feedback :)