by Gerard Sans |  @gerardsans

Big time PWA

using GraphQL and

Amplify DataStore

Big time PWA

using GraphQL and

Amplify DataStore

SANS

GERARD

Developer Advocate AWS

Developer Advocate AWS

International Speaker

Spoken at 160 events in 37 countries

What is Offline first?

Icons made by Gregor Cresnar from www.flaticon.com is licensed by CC 3.0 BY
Icons made by Darius Dan from www.flaticon.com is licensed by CC 3.0 BY

Offline First for Web

Reliable

Storage

background Layer 1

Native-like Features

Great User Experience

Offline

Ready

Created by potrace 1.16, written by Peter Selinger 2001-2019

Progressive Web Apps

Reach

Capabilities

Native

Applications

PWA

Applications

Web/SPA

Applications

PWA Core Requirements

image/svg+xml

Web App

Manifest

Service

Worker

Security

(HTTPS)

Service Worker Online

index.html

Cache

Hosting

Service

Worker

app.js

app.js

app.js

logo.png

logo.png

logo.png

app.js

logo.png

app.js

logo.png

Service Worker Offline

index.html

Cache

Hosting

Service

Worker

OFFLINE

app.js

logo.png

app.js

logo.png

app.js

logo.png

app.js

logo.png

AWS AMPLIFY

Fullstack Serverless

🦄

🌩️

Web and Mobile support

preview

AWS Amplify

Amplify Framework

  • Open source
  • Categories based
  • Opinionated
  • Scape hatches

Developer Tools

  • Amplify CLI
  • Create & manage AWS Services
  • Multiple environments
  • Mocks & local testing
  • Plugins (video, docs, ttl)

amplify update
category

amplify
init

amplify
add
category

amplify
push

Amplify CLI development

AWS Amplify Console

  • Auto-deploy on commit
  • Seamless CD/CI, deploy globally, custom domains, branch-based, atomic, secured
  • Supports GitHub, Bitbucket, GitLab, CodeCommit
  • Drag&drop folder or zip

interactions

storage

notifications

auth

analytics

function

api

hosting

xr

transcribe

translate

polly

rekognition

comprehend

Chatty

Chatty App

AppSync

GraphQL

$ amplify init
$ amplify add auth
$ amplify add api
$ amplify push
src/app.component.ts

Amplify CLI commands

type Chatty @model {
  id: ID!
  user: String!
  message: String!
  createdAt: AWSDateTime
}
src/app.component.ts

Chatty GraphQL Schema

Icons made by Gregor Cresnar from www.flaticon.com is licensed by CC 3.0 BY
Icons made by Darius Dan from www.flaticon.com is licensed by CC 3.0 BY

Amplify DataStore Offline

Icons made by Gregor Cresnar from www.flaticon.com is licensed by CC 3.0 BY
Icons made by Darius Dan from www.flaticon.com is licensed by CC 3.0 BY

Amplify DataStore Online

import { DataStore } from "@aws-amplify/datastore";
import { Chatty } from "./models";

await DataStore.save(new Chatty({
  user: "gsans",
  message: "Hi everyone!👋",
  createdAt: new Date().toISOString()
}))
src/app.component.ts

Creating a Message

import { DataStore, Predicates } from "@aws-amplify/datastore";
import { Chatty } from "./models";

const msg = await DataStore.query(Chatty, Predicates.ALL);
src/app.component.ts

Querying data

Make it

a PWA!

$ ng add @angular/pwa

ngsw-config.json (added)
src/assets/icons/icon-*.png (added)
src/manifest.webmanifest (added)
angular.json (updated)
index.html (updated)
app.module.ts (updated)
src/app.component.ts

Run PWA plugin

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>AmplifyDatastore</title>
  <link rel="icon" type="image/x-icon" href="favicon.ico">
+  <link rel="manifest" href="manifest.webmanifest">
+  <meta name="theme-color" content="#1976d2">
</head>
<body>
  <app-root></app-root>
+  <noscript>Please enable JavaScript.</noscript>
</body>
</html>
src/app.component.ts

index.html


import { ServiceWorkerModule } from '@angular/service-worker';
import { env } from '../environments/environment';

@NgModule({
  imports: [
    ServiceWorkerModule.register('ngsw-worker.js', { 
      enabled: env.production 
    })
  ],
})
export class AppModule { }
src/app.component.ts

app.module.ts

$ ng build --prod
src/app.component.ts

Test your PWA

└── dist
  ├── assets/icons
  ├── favicon.ico
  ├── index.html
  ├── manifest.webmanifest
  ├── safety-worker.js
  ├── ngsw.json
  └── ngsw-worker.js
$ npm i -g http-server 
$ http-server dist/amplify-datastore -o
{
  "index": "/index.html",
  "assetGroups": [ 
     { 
       "name": "app",
     }, 
     { 
       "name": "assets", 
     }
  ]
}
src/app.component.ts

ngsw-config.json

{
 "name": "app", 
 "installMode": "prefetch", // prefetch | lazy
 "resources": {
   "files": [ 
     "/favicon.ico", 
     "/index.html", 
     "/manifest.webmanifest", 
     "/*.css", 
     "/*.js"
   ],
   "urls": [ 
     "https://aws-amplify.github.io/images/Logos/Amplify-Logo-White.svg"
   ]
 } 
}
src/app.component.ts

ngsw-config.json (assetGroup: app)

{
  "name": "assets", 
  "installMode": "lazy", 
  "updateMode": "prefetch",
  "resources": {
    "files": [ 
      "/assets/**", 
      "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
    ]
  }
}
src/app.component.ts

ngsw-config.json (assetGroup: assets)

Chatty

PWA

Web, Mobile and Desktop

Icons made by Gregor Cresnar from www.flaticon.com is licensed by CC 3.0 BY
Icons made by Darius Dan from www.flaticon.com is licensed by CC 3.0 BY

Add to home screen

Icons made by Gregor Cresnar from www.flaticon.com is licensed by CC 3.0 BY
Icons made by Darius Dan from www.flaticon.com is licensed by CC 3.0 BY

Passes Lighthouse Test

99% Offline-ready

  • Survives offline reload
  • Stores messages while offline
  • Shares messages when back online
  • User doesn't know if App is offline
// <div *ngIf="offline">You are offline.</div>
// app.component.ts
@Component(...)
export class AppComponent implements OnInit {
  offline : boolean = false;
  ngOnInit() {
    // Registering datastore hub
    Hub.listen('datastore', message => {
      const { event, data } = message.payload;
      if (event === 'networkStatus') {
        this.offline = !data.active;
      }
    })
  }
}
src/app.component.ts

Improve Offline UX

Icons made by Gregor Cresnar from www.flaticon.com is licensed by CC 3.0 BY
Icons made by Darius Dan from www.flaticon.com is licensed by CC 3.0 BY
  • Faster (pre-cached)
  • Online/Offline
  • Full screen app
  • Browser/Mobile/Desktop
  • Web/Native-like features
  • Slower
  • Online
  • Tab in browser
  • Browser
  • Web features

Web/SPA    vs    PWA

Try it!

amplify-datastore-chatty-pwa-angular

amplify-datastore-chatty-angular (workshop)

Big time PWA using GraphQL and Amplify DataStore

By Gerard Sans

Big time PWA using GraphQL and Amplify DataStore

Offline-first apps need to support: intermittent connectivity, transition seamlessly between online and offline states, reliable CRUD on-device data, data synchronisation and data conflict resolution to enable real-time collaboration. Amplify DataStore is an on device persistent repository for interacting with local data and able to automatically synchronize via GraphQL. Using Amplify DataStore will allow us to implement offline-first while using a simple programming model.

  • 2,422