by Gerard Sans |  @gerardsans

Not a basic offline first app using

GraphQL and

Amplify DataStore

Not a basic offline first app using

GraphQL and

Amplify DataStore

SANS

GERARD

Developer Advocate AWS

Developer Advocate AWS

International Speaker

Spoken at 152 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

🦄

🌩️

Update

Init

Add

Push

Amplify CLI

Categories

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!

$ vue add @vue/pwa

src/main.js (Updated)
> + import './registerServiceWorker'

src/registerServiceWorker.js (Added)
src/app.component.ts

Run PWA Vue CLI plugin

$ yarn build
src/app.component.ts

Test your PWA

└── dist
  ├── css
  │   └── app.<version>.css
  ├── img/icons
  │   ├── android-chrome-<size>.png
  │   └── ...
  ├── js
  │   ├── app.<version>.png
  │   └── ...
  ├── favicon.ico
  ├── index.html
  ├── manifest.json
  ├── precache-manifest.<version>.json
  ├── robots.txt
  └── service-worker.js
$ cd dist
/dist$ python -m SimpleHTTPServer 8887
// vue.config.js
const manifest = require('./public/manifest.json')
module.exports = {
  pwa: {
    name: manifest.short_name,
    themeColor: manifest.theme_color,
    msTileColor: manifest.background_color,
    appleMobileWebAppCapable: 'yes',
    appleMobileWebAppStatusBarStyle: 'black',
    workboxPluginMode: 'InjectManifest',
    workboxOptions: {
      swSrc: 'src/service-worker.js',
    }
src/app.component.ts

Add custom configuration (1/2)

// src/service-worker.js
workbox.core.setCacheNameDetails({ prefix: 'amplify-datastore' })

workbox.core.skipWaiting()
workbox.core.clientsClaim()

const cacheFiles = [{
 "revision": "e653ab4d124bf16b5232",
 "url": "https://aws-amplify.github.io/img/amplify.svg"
}]

self.__precacheManifest = cacheFiles.concat(self.__precacheManifest || [])
workbox.precaching.precacheAndRoute(self.__precacheManifest, {})
src/app.component.ts

Add custom configuration (2/2)

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 v-if="offline">You are offline.</div>

// App.vue
import { Hub } from 'aws-amplify';

export default {
  data() {
    return { offline: undefined };
  },
  created() {
    this.listener = Hub.listen('datastore', {payload:{event}} => {
      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-vue (solution)

amplify-datastore-chatty-vue (workshop)

Not a basic offline-first app using GraphQL and Amplify DataStore

By Gerard Sans

Not a basic offline-first app 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.

  • 1,934