Bill Kidwell took us through his recent experiences creating a GraphQL API using AWS Appsync and AWS Amplify. He covered data model and data access patterns. And updating the GraphQL schema using Appsync’s custom annotations. The result was a DynamoDB backed GraphQL API. He even discussed more complex use cases too.
This was a great topic to share at KYJSUG
2. Hello!
I am Bill Kidwell
I have 22 years in the software industry
I have a graduate degree from UK with a Software
Engineering emphasis
I like to coach, mentor, and teach developers
2
3. Agenda
▫ Part I
▫ Define GraphQL
▫ Potential Advantages
▫ Part II
▫ Understand queries, mutations
▫ Understand schema and resolvers
▫ Part III
▫ AppSync and Amplify will make this easy
▫ Hand-On Example 3
5. The GraphQL Experience
5
Get predictable results
{
"project": {
"tagline": "A query language for APIs"
}
}
Describe your data
type Project {
name: String
tagline: String
contributors: [User]
}
Ask for what you want
{
project(name: "GraphQL") {
tagline
}
}
6. Rest API Request/Response
GET /api/user =>
user: {
firstName: “Billy”,
lastName: “Kidwell”,
gender: “male”,
createAt: “2019-08-27T18:04:31”,
updatedAt: “2019-08-27T18:04:31”,
posts: [ ]
}
You get what you get… (no overfetching)
GraphQL Query and response
user {
firstName
lastName
gender
}
=> user: {
firstName: “Billy”,
lastName: “Kidwell”,
gender: “male”
}
6
7. No Underfetching
REST
To populate the author object
/ps /author/<id>
/ps /author/<id>/courses
/ps /author/<id>/rating
/ps /author/<id>/topics
The GraphQL Query
{
author (id: 2100) {
name
courses {
title
}
rating
topics (last: 3) {
name
}
}
}
7
8. Strongly Typed Schema
▫ Eases validation, documentation
▫ Find errors earlier
▫ Serves as contract between client and server
▫ Frontend and backend teams can work
independently
▫ Enables a robust toolset
8
9. The Parts of GraphQL
Queries, Mutations, Schemas and Resolvers
11. Queries and
Fragments
Use fragments for reusable
parts.
Name your queries. They can
include parameters.
11
query first50Pokemons {
pokemons(first: 50) {
...pokemonInfo
}
}
fragment pokemonInfo on Pokemon{
name
number
classification
maxCP
maxHP
image
}
13. “
13
Resolvers provide the instructions for turning a GraphQL
operation (a query, mutation, or subscription) into data.
14. type Query {
greeting: String
students: [Student]
studentById(id:ID!): Student
}
14
A sample schema
type Student {
id: ID!
firstName: String
lastName: String
password: String
collegeId: String
}
15. A Sample Resolver
const db = require('./db')
const Query = {
//resolver function for greeting
greeting:() => {
return "hello from TutorialsPoint !!!"
},
15
//resolver function for students returns list
students:() => db.students.list(),
//resolver function for studentbyId
studentById:(root,args,context,info) => {
//args will contain parameter passed in query
return db.students.get(args.id);
}
}
module.exports = {Query}
20. 20
GraphQL Transform - @model
$ amplify add api # schema.graphql
type Post @model {
id: ID!
title: String!
}
21. Our process is easy
21
Implement Iteratively
Order them considering
simplicity and dependencies
(e.g. create before list, update or
delete)
Work through them iteratively.
Data Model
Start with a Data Model
Document Data Access Patterns
NoSQL databases require
special attention to data access
patterns. If you don’t know
what these are going to be, you
might want to go with a
relational database.
23. 23
For our Sample Blog, Consider
Create a Blog
List all Blogs
Add a Post to a Blog
Get all Posts for the Blog
Create a Comment on a Post
Get a Post and All Comments for the Blog