Recently, I’ve enjoyed using mood tracking apps as a quick and easy way to journal at any time of the day. My main issue is that every mood tracking app I try isn’t perfect for my use case. Because of this, I decided to develop my own mood tracking app.
For this app I decided to use AWS to host the app’s backend. Eventually, I learned about AWS Amplify and how easy it made connecting my app’s UI to a backend hosted in AWS.
For this article, I will walk through what I did to get my app working.
First you have to install and configure the Amplify CLI itself. I suggest you follow the official docs for this process.
Once we’ve configured the Amplify CLI we will create a new React project.
1 |
create-react-app moodtrack |
After creating the project we will go into our moodtrack directory and run the command
1 |
amplify init |
The CLI will ask us some basic questions about our app. For the first question select the name of the editor you use. When the CLI asks what type of app you’re building select JavaScript and select React as the framework. For the source directory, distribution directory, start command, and build command press enter to get the default value.
Now lets add authentication into our app by running the command
1 |
amplify add auth |
Press enter to use the default configuration. Now we will add a GraphQL API to our app using the command
1 |
amplify add api |
Select GraphQL as the API type and give it any name you’d like. Pick Cognito user pool as the authentication type (we created a Cogntio user pool in the previous step). Say no to having an annotated schema and answer yes to guided schema creation. Choose the first option for a “todo” app.
Create the resources in the cloud by using this command
1 |
amplify push |
Answer yes to all the questions it asks. Resources will be created in AWS and Amplify will generate code for all possible queries, mutations, and subscriptions.
If you look at amplfy/backend/api/moodtrack/schema.graphql you will notice the following schema was automatically generated by amplify.
1 |
type Todo <a href="http://twitter.com/model" target="_blank" rel="noreferrer noopener">@model</a> {<br> id: ID!<br> name: String!<br> description: String<br>} |
While this schema is perfect for a todo app, we need something different. Delete that schema and replace it with this one.
1 |
type MoodItem <a href="http://twitter.com/model" target="_blank" rel="noreferrer noopener">@model</a> <a href="http://twitter.com/auth" target="_blank" rel="noreferrer noopener">@auth</a>(rules: [{ allow: owner }]) {<br> id: ID!<br> date: String!<br> note: String!<br> mood: String<br>} |
The ‘auth(rules: [{ allow: owner}])’ line makes it so that a user can only see the ‘moods’ that they created.
Run amplify push again and allow it to generate new code for our new schema.
Now that all of our parts are in place we can integrate them. First we will add in authentication. To do this we will have to add the following packages to our app.
1 |
npm install --save aws-amplify aws-amplify-react |
We can implement authentication into our app using a higher order component. You can add the following 2 lines to your app.js file to implement authentication.
1 |
<em>import</em> { withAuthenticator }<em> from</em> "aws-amplify-react";<rest of code will be here><em>export default</em> withAuthenticator(App); |
Now what do we do with the queries and mutations that Amplify generated for us?
While I will not walk through every possibility, here is an example of a basic add mood form.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
import React, { Component } from "react"; import Amplify, { Auth, API, graphqlOperation } from "aws-amplify"; import awsmobile from "./aws-exports"; import { withAuthenticator } from "aws-amplify-react"; import * as queries from "./graphql/queries"; import * as mutations from "./graphql/mutations"; import styled from "styled-components"; Amplify.configure(awsmobile); var today = new Date(); var dd = today.getDate(); var mm = today.getMonth() + 1; //January is 0! var yyyy = today.getFullYear(); if (dd < 10) { dd = "0" + dd; } if (mm < 10) { mm = "0" + mm; } today = mm + "/" + dd + "/" + yyyy; class App extends Component { constructor(props) { super(props); this.state = { NewMoodTitle: "", NewMoodType: "" }; this.handleChange = this.handleChange.bind(this); } handleChange(value, name) { this.setState(state => { return (state[name] = value); }); } render() { return ( <div className="App"> <header className="App-header"> <div>add: </div> <input onChange={e => { this.handleChange(e.target.value, "NewMoodTitle"); }} value={this.state.NewMoodTitle} /> <input onChange={e => { this.handleChange(e.target.value, "NewMoodType"); }} value={this.state.NewMoodType} /> <button onClick={async () => { var moodDetails = { date: today, note: this.state.NewMoodTitle, mood: this.state.NewMoodType }; const newMood = await API.graphql( graphqlOperation(mutations.createMoodItem, { input: moodDetails }) ); console.log("newMood ", newMood); }} /> </header> </div> ); } } export default withAuthenticator(App); |
As you can see, AWS Amplify makes connecting all of these services together so easy that it feels like you just used a cheat code to skip the tedious parts of web development.
Thanks for reading this article. If you have any questions feel free to reach out to me on twitter.