Introduction to GraphQL and Hasura
whoami?
Agenda
- Introduction to GraphQL
- What is Hasura?
Introduction to GraphQL
1. Fetching data
REST API call
App
API
GET api/users
GET api/tasks/user_id=1
{
users: [
{
id: 1,
name: "Jon",
surename: "Doe"
}
]
}
GET api/tasks/user_id=1
{
tasks: [
{
name: "Learn GraphQL",
completed: false,
}
]
}
REST API call
App
API
GET api/users/user_id=1
GET api/tasks/user_id=1
GET api/tasks/user_id=1
GET api/users/details/user_id=1
GET api/tasks/details/task_id=1
Problem: four API calls
REST API call
GET api/users/user_id=1
GET api/tasks/user_id=1
GET api/user_info/user_id=1
GET api/users/details/user_id=1
GET api/tasks/details/task_id=1
Solution: new ednpoints
GET api/tasks_info/user_id=1
REST API call
Problem: different data on different views
example.com/user/1
example.com/users/summary
All users
Profile
pic
User data
More user data
REST API call
Solution: specify fields in API call
GET api/user_info/user_id=1&fileds=name&fileds=profile_pic
REST API call
Problem: we want only tasks in progress
example.com/tasks/in_progress
Tasks in progress
- Learn GraphQL
REST API call
Solution: add filter to query parameters
GET api/tasks_info/filter.status=in_progress
GraphQL API call
App
API
query {
users(id: 1) {
name
surename
}
}
{
"users": [
{
"name": "Jon",
"surename": "Doe",
}
]
}
query {
users(id: 1) {
name
surename
}
}
GraphQL API call
App
API
query {
users(id: 1) {
name
surename
tasks(user_id: 1) {
name
status
}
}
}
{
"users": [
{
"name": "Jon",
"surename": "Doe",
"tasks": [
{
"name": "Learn GraphQL",
"status": "in_progress"
}
]
}
]
}
GraphQL API call
App
API
query {
users(id: 1) {
name
surename
tasks(user_id: 1,
status: "completed") {
name
status
}
}
}
{
"users": [
{
"name": "Jon",
"surename": "Doe",
"tasks": []
}
]
}
Data models are a graph
User 1
Task 1
Task 2
Tag 1
Tag 2
Tag 3
query {
user(id: 1) {
...
tasks {
...
tags {
...
}
}
}
}
You control data you get
User 1
Task 1
Task 2
Tag 1
Tag 2
query {
user(id: 1) {
name
tasks {
name
status
tags {
id
}
}
}
}
name
surename
age
status
name
priority
name
priority
status
description
id
description
id
Tag 3
description
id
REST API
GraphQL API
API
App
GET users/
GET tasks/
GET tags/
API
App
POST graphql/
Body:
{ "query": "query { users {...} }" }
vs
2. Updating data
REST API
App
API
POST api/users/create
{
"name": "Jon"
}
Status 200
{
"id": 1
}
POST
PUT
PATCH
DELETE
GraphQL API
App
API
mutation {
insertTaks(payload: {...}) {
id
}
}
mutation {
insertTaks(payload: {...}) {
id
}
}
Status 200
{
"id": 1
}
3. Real-time API
App
API
REST API
Option #1
Polling
Option #2
Websockets
App
API
GraphQL API
subscribtion {
tasks {
id
status
}
}
ws://myapi.com/graphql
"tasks": [
{
"id": 1,
"status": "completed"
}
]
4. Passing parameters
REST API
GET api/users/user_id=1
let userId = user.id;
get(url, { user_id: userId })
GraphQL API
query {
users(id: 1) {
name
surename
}
}
string
How can we send arguments programatically?
GraphQL API
query {
users(id: 1) {
name
surename
}
}
string
How can we send arguments programatically?
const query = `query {
users(id: ${userId}) {
name
surename
}
}`
post(url, { query })
😕
GraphQL API
query {
users(id: 1) {
name
surename
}
}
string
How can we send arguments programatically?
const query = `query FetchUser($userId: string) {
users(id: ${userId}) {
name
surename
}
}`
post(url, { query, variables: { userId: user.id } })
5. API docs
REST API
Option #1
Docs are autogenerated
👎 Codegen tools are limited
Option #2
Developer manually creates docs
👎 Easy to get out-of-sync
GraphQL API
Schema is your documentation
User 1
Task 1
Task 2
Tag 1
Tag 2
name
surename
age
status
name
priority
name
priority
status
description
id
description
id
Tag 3
description
id
type User {
id: Int!
name: String!
surname: String
age: Int
}
type Task {
id: Int!
name: String!
status: String
priority: Number
}
type Tag {
id: String!
description: String
}
GraphQL API
Introspection API
{
__type(name: "users") {
name
fields {
name
type {
name
kind
inputFields {
name
}
}
}
}
}
{
"data": {
"__type": {
"name": "users",
"fields": [
{
"name": "id",
"type": {
"name": "String",
"inputFields": null,
"kind": "SCALAR"
},
},
{
"name": "name",
"type": {
"name": "String",
"inputFields": null,
"kind": "NON_NULL"
},
},
{
"name": "created_at",
"type": {
"inputFields": null,
"kind": "NON_NULL"
},
"description": null
},
}
}
Introduction to GraphQL summary
GET
POST
PUT
PATCH
DELETE
query
GET
GET
mutation
subscription
Introduction to Hasura
What is Hasura?
Open source • GraphQL engine
Realtime GraphQL Engine
GraphQL Queries Compiler
users {
name
posts {
title
content
tags {
name
}
}
}
SELECT
users.name
posts.title
posts.content
tags.name
FROM
users, posts, tags
WHERE
users.id = posts.author_id,
posts.id = tags.post_id
Authorization
Authentication
Webhook mode
App
Query req headers
</>
variables
eg. x-hasura-user-id
req headers
Webhook
Authentication
JWT mode
App
Auth
Service
JWT Hasura claims
Query, JWT
App
Remote Schemas
Unified GraphQL API
GraphQL Service
Data Triggers
APIs
Background jobs
GraphQL mutations
Event queue
Microservices
Serverless functions
Cron Triggers
Event queue
Microservices
Serverless functions
One-off Scheduled Triggers
Event queue
Microservices
Serverless functions
Actions
App
</>
GraphQL
query / mutation
POST endpoint
Actions
Multiple databases
App
- Postgres
- Yugabyte
- Timescale
- MS Server
- Big Query
Hasura Cloud
Takeaways
Introduction to GraphQL with Hasura v2
By Aleksandra Sikora
Introduction to GraphQL with Hasura v2
- 1,554