How to create a highly scalable serverless GraphQL data-driven app in minutes

Gerard Sans
Jul 1 · 8 min read

Introduction to AWS AppSync

AWS AppSync data-driven apps architecture overview

Setting up a new project with the Angular CLI

Creating a new GraphQL API

amplify add api
type Restaurant @model {
id: ID!
clientId: String
name: String!
description: String!
city: String!
}

Using your first GraphQL transform

Pushing your GraphQL API to the cloud

amplify push
amplify console api

Testing your new GraphQL API

mutation createRestaurant {
createRestaurant(input: {
name: "Nobu"
description: "Great Sushi"
city: "New York"
}) {
id name description city
}
}
query listRestaurants {
listRestaurants {
items {
id
name
description
city
}
}
}
query searchRestaurants {
listRestaurants(filter: {
city: {
contains: "New York"
}
}) {
items {
id
name
description
city
}
}
}

Building the AppSync client

Querying data with queries

import { API, graphqlOperation } from 'aws-amplify';
import { listRestaurants } from '../graphql/queries';
import { Restaurant } from './types/restaurant';
@Component({
template: `
<div>
<div *ngFor="let restaurant of restaurants">
{{ restaurant.name }}
</div>
</div>`
})
export class AppComponent implements OnInit {
restaurants: Array<Restaurant>;
async ngOnInit() {
var response = await API.graphql(graphqlOperation(listRestaurants))
this.restaurants = (response as any).data.listRestaurants.items;
}
}
listRestaurants(filter: ModelRestaurantFilterInput, limit: Int, nextToken: String): ModelRestaurantConnectiontype ModelRestaurantConnection {
items: [Restaurant]
nextToken: String
}

Creating data with mutations

import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { createRestaurant } from '../../graphql/mutations'
@Component(...)
export class HomeComponent implements OnInit {
public createForm: FormGroup;
constructor(private fb: FormBuilder) { }async ngOnInit() {
this.createForm = this.fb.group({
'name': ['', Validators.required],
'description': ['', Validators.required],
'city': ['', Validators.required]
});
var response = await API.graphql(graphqlOperation(listRestaurants));
this.restaurants = (response as any).data.listRestaurants.items;
}

public async onCreate(restaurant: any) {
try {
await API.graphql(graphqlOperation(createRestaurant, {
input: restaurant
}));

console.log('item created!');
this.restaurants = [restaurant, ...this.restaurants];
this.createForm.reset();
}
catch (e) {
console.log('error creating restaurant...', e);
}
}
}
type Mutation {
createRestaurant(input: CreateRestaurantInput!): Restaurant
}
input CreateRestaurantInput {
id: ID
clientId: String
name: String!
description: String!
city: String!
}

Adding real-time with subscriptions

import * as Observable from 'zen-observable';
import { onCreateRestaurant } from '../../graphql/subscriptions';
@Component(...)
export class HomeComponent implements OnInit {
ngOnInit() {
var subscription = API.graphql(
graphqlOperation(onCreateRestaurant)
) as Observable<object>;


subscription.subscribe({
next: (sourceData) => {
const newRestaurant = (sourceData as any).value.data.onCreateRestaurant
this.restaurants = [newRestaurant, ...this.restaurants];
}
});
}
}

Publishing your app via the AWS Amplify Console

git initgit remote add origin repo@repoofyourchoice.com:username/project-name.gitgit add .git commit -m 'initial commit'git push origin master
AWS Amplify Console deployment steps.

Cleaning up cloud services

amplify remove authamplify push

Conclusion


Thanks for reading!

Gerard Sans

Written by

Developer Advocate @AWSCloud | Just be AWSome | MC Speaker Trainer Community Leader | Views are my own | @fullstackcon @ReactiveConf @ngcruise @UphillConf UK ☂

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade