Introduction to GraphQL and Hasura
whoami?
Agenda
- Introduction to GraphQL
- What is Hasura?
- Demo and live coding
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
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
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 inside in the queryย
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/tasks/
{
"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. API docs
REST API
Option #1
Docs are autogenerated
ย
ย
๐ Codegen tools are limited
Option #2
Developer manually create 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
}
Introduction to GraphQL summary
GET
POST
PUT
PATCH
DELETE
query
GET
GET
mutation
subscription
Introduction to Hasura
What is Hasura?
Open source โข GraphQL engine โข On Postgres
ย
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
ย
ย
App
Remote Schemas
ย
Unified GraphQL API
GraphQL Service
Event triggers
APIs
Background jobs
GraphQL mutations
Event queue
Microservices
Serverless functions
Actions
App
</>
Hasura in React application
Apollo
UI
GraphQL query
Fetching data
Sends data
Updates UI
Client processes data
Client normalises and stores data
Demo ๐โโ๏ธ๐โโ๏ธ
Setup
1. Install dependencies
yarn add apollo-client @apollo/react-hooks apollo-link-http \
graphql graphql-tag apollo-cache-inmemory
Setup
2. Create Apollo Client
import ApolloClient from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { HttpLink } from "apollo-link-http";
export const createApolloClient = () => {
return new ApolloClient({
link: new HttpLink({
uri: "https://<YOUR_GRAPHQL_SERVICE>/graphql",
}),
cache: new InMemoryCache(),
});
};
Setup
3. Add ApolloProvider
import { ApolloProvider } from "@apollo/react-hooks";
const App = () => {
const client = createApolloClient();
return (
<ApolloProvider client={client}>
{...}
</ApolloProvider>
)
}
Setup
4. TypeScript codegen
yarn add @graphql-codegen/cli @graphql-codegen/introspection \
@graphql-codegen/typescript @graphql-codegen/typescript-operations \
@graphql-codegen/typescript-react-apollo
Resources
1. GraphQL: https://graphql.org/learn/
2. Hasura: https://hasura.io/
3. Hasura tutorials: https://hasura.io/learn/
4. Apollo docs: https://www.apollographql.com/docs/
Introduction to GraphQL with Hasura
By Aleksandra Sikora
Introduction to GraphQL with Hasura
- 1,785