by Gerard Sans | @gerardsans
Offline-first
made easy with GraphQL and
Amplify DataStore
Offline-first
made easy with GraphQL and
Amplify DataStore
SANS
GERARD
Developer Advocate AWS
Developer Advocate AWS
International Speaker
Spoken at 151 events in 37 countries
What is Offline first?
Offline First for Web
Reliable
Storage
Native-like Features
Great User Experience
Offline
Ready
Progressive Web Apps
Native
Applications
PWA
Applications
Web/SPA
Applications
Reach
Capabilities
PWA Core Requirements
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
Amplify DataStore Offline
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
Add to home screen
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
- 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)
Offline-first made easy with GraphQL and Amplify DataStore
By Gerard Sans
Offline-first made easy with 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,630