The Intro
GraphQL is a new API standard that provides an efficient , flexible, powerful alternative for REST
GraphQL isn't tied to any specific database or storage engine and is instead backed by your existing code and data.
GraphQL is an open-source data query and manipulation language for APIs, and a runtime for fulfilling queries with existing data.
GraphQL was developed internally by Facebook in 2012 before being publicly released in 2015.
Since 2012, GraphQL's rise has followed the adoption timeline as set out by Lee Byron, GraphQL's creator, with accuracy.
On 7 November 2018, the GraphQL project was moved from Facebook to the newly-established GraphQL Foundation, hosted by the non-profit Linux Foundation.
Since reveal.js runs on the web, you can easily embed other web content. Try interacting with the page in the background.
GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data.
At its core, GraphQL enables declarative data fetching where a client can specify exactly what data it needs from an API.
Instead of multiple endpoints that return fixed data structures, a GraphQL server only exposes a single endpoint and responds with precisely the data a client asked for.
A GraphQL service is created by defining types and fields on those types, then providing functions for each field on each type.
GraphQL - A Query Language for APIs
Not Databases
(NF3)
📘 Books
id | name | authorId | movieId |
---|---|---|---|
1 | Book 1 | 11 | 111 |
2 | Book 2 | 22 | 222 |
3 | Book 3 | 33 | 333 |
👨🏻💻 Authors
id | name | age |
---|---|---|
11 | Alex | 33 |
22 | David | 44 |
33 | Mike | 55 |
⭐️ Stars
id | bookId | stars |
---|---|---|
1 | 2 | 4 |
2 | 1 | 5 |
3 | 2 | 7 |
🎥 Movies
id | title | year |
---|---|---|
111 | Episode I | 1999 |
222 | Episode II | 2002 |
333 | Episode III | 2005 |
⭐️⭐️⭐️⭐️⭐️
👨🏻💻 TERRY BROOKS American writer Terence Dean Brooks is an American writer of fantasy fiction. He writes mainly epic fantasy, and has also written two film novelizations. He has written 23 New York Times bestsellers during his writing career, and has sold over 21 million copies of his books in print. Wikipedia Born: January 8, 1944 (age 76 years), Sterling, Illinois, United States Spouse: Judine Brooks Education: Washington and Lee University School of Law ... Nominations: Locus Award for Best Fantasy Novel...
🎬 Episode I
REST
HTTP GET /books/2
output:
{
"data": {
"book": {
"name": "Book2",
"genre": "Sci-Fi",
"authorId": "2",
"movieId": "33"
"id" :2,
"meta": "43434r",
"type": "fdfe"
}
}
}
REST API
🧐
HTTP GET /books/2
output:
{
"data": {
"book": {
"name": "Book2",
"genre": "Sci-Fi",
"authorId: "2",
"movieId": "33"
}
}
}
REST API
🤔
HTTP GET /books/:id/authors/
output:
{
"author": {
"age": 44,
"name": "Mike",
"id": "5e5629fc4"
}
}
REST API
🤨
HTTP GET /books/:id/movies/
output:
"movie": {
"title": "Episode I",
"year": "2008",
"id": "58559"
}
REST API
🤨
HTTP GET /books/:id/stars/
output:
"stars": {
"stars": 5,
"id": "3",
"bookId": "5e562a384e98"
},
REST API
🤨
HTTP GET /books/:id
HTTP GET /books/:id/authors/
HTTP GET /books/:id/movies/
HTTP GET /books/:id/stars/
{
"data": {
"book": {
"name": "Book2",
"genre": "222",
"more": "not relevant fields",
"author": {
"age": 44,
"name": "Mike",
"id": "5e5629fc4e98b96691966c76",
"more": "not relevant fields"
},
"stars": {
"stars": 5,
"id": "3",
"bookId": "5e562a384e98b96691966c77",
"more": "not relevant fields"
},
"movie": {
"title": "Episode I",
"year": 2008,
"id": "58559",
"more": "not relevant fields"
}
}
}
}
With GraphQL we can retrieve all related data with one single query using only one exposed api
{
book(id: "2"){
name
genre
author{
age,
name
id
}
stars{
stars
id
bookId
}
movie{
title
year
id
}
}
}
{
"data": {
"book": {
"name": "Book2",
"genre": "222",
"author": {
"age": 44,
"name": "Mike",
"id": "5e5629fc4e98b96691966c76"
},
"stars": {
"stars": 5,
"id": "3",
"bookId": "5e562a384e98b96691966c77"
},
"movie": {
"title": "Episode I",
"year": 2008,
"id": "58559"
}
}
}
}
With dynamic fields selection, we just can solve the problem of over and under fetching
{
book(id: "2"){
name
author{
age
}
stars{
stars
}
movie{
title
}
}
}
{
"data": {
"book": {
"name": "Book2",
"author": {
"age": 44
},
"stars": {
"stars": 5
},
"movie": {
"title": "Episode I"
}
}
}
}
{
book(id: "2"){
name
genre
author{
age
name
}
stars{
stars
}
movie{
title
}
}
}
{
"data": {
"book": {
"name": "Book2",
"genre": "222",
"author": {
"name": "Mike",
"age": 44,
},
"stars": {
"stars": 5,
},
"movie": {
"title": "Episode I",
}
}
}
}
Rapidly changing requirements on a client side don't go well with the static REST
GraphQL was developed to cope with the needs for more flexibility and efficiency in client-server communication
With REST API we are dependent on UI and the Server structure.
Endpoints structured according to the client needs. So every change has a huge influence on a core server, product and UI
With GraphQL this problem just doesn't exist anymore.
With GraphQL we can use low level performance tuning and fields review regardless to the server
With GraphQL frontend and backend completely independent from each other
📘 Books
👨🏻💻 Authors
🎥 Movies
⭐️ Stars
the relations ?
query ?
Yes, we can !
GraphQL - A Query Language for APIs
Not Databases
Retrieve
Delete
Update
Insert
{
"data": {
"book": {
"name": "Book2",
"genre": "222",
"author": {
"age": 44,
"name": "Mike",
"id": "5e5629fc4e98b96691966c76"
},
"stars": {
"stars": 5,
"id": "3",
"bookId": "5e562a384e98b96691966c77"
},
"movie": {
"title": "Episode I",
"year": 2008,
"id": "58559"
}
}
}
}
mutation {
addStar(bookId:"5e562a774e98b96691966c78", stars:3) {
id
}}
mutation {
addBook(name: 'Episode II') {
id
}}
mutation {
deleteMovie(name: 'Episode II') {
id
}}
mutation {
updateAuthor(name: 'Mike') {
id
}}
type Author {
name: String!
age: Int!
}
GraphQL has its own type system that’s used to define the schema of an API. The syntax for writing schemas is called Schema Definition Language (SDL).
type Author {
name: String!
age: Int!
}
This type has two fields, they’re called `name` and `age` and are respectively of type String and Int.
The ! following the type means that this field is required.
type Book {
name: String!
authorId: Author!
}
It’s also possible to express relationships between types. In the example of a books application, a Book could be associated with the Author
GraphQL has a clear separation of structure and behavior. The structure of a GraphQL server is — as we just discussed — its schema, an abstract description of the server’s capabilities.
This structure comes to life with a concrete implementation that determines the server’s behavior. Key components for the implementation are so-called resolver functions.
Each field in a GraphQL schema is backed by a resolver.
Definding the type with JS
const graphql = require('graphql')
const { GraphQLObjectType, GraphQLID,
GraphQLList,GraphQLString,GraphQLInt } = graphql
const AuthorType = new GraphQLObjectType({
name: "Author",
fields: () => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
age: { type: GraphQLInt },
books: {
type: new GraphQLList(BookType),
resolve: (parent, args) => {
return Book.find({ authorId: parent.id }) // mongo db
}
}
})
})
Fetching Data with Queries
{
books {
name
genre
id
author{
name
age
id
}
}
}
{
"data": {
"books": [
{
"name": "Book1",
"genre": "1111",
"id": "5e56294a4e98b96691966c74",
"author": {
"name": "Alex",
"age": 39,
"id": "5e56255c62c9836008df46d7"
}
},
....
]
}
}
Queries with Arguments
{
book(id: "5e562...") {
name
genre
id
author{
name
age
id
}
}
}
{
"data": {
"name": "Book1",
"genre": "1111",
"id": "5e56294a4e98b96691966c74",
"author": {
"name": "Alex",
"age": 39,
"id": "5e56255c62c9836008df46d7"
}
}
So we need some way of making changes to the data that’s currently stored in the backend.
With GraphQL, these changes are made using mutations.
There generally are three kinds of mutations
Writing Data with Mutations
mutation {
createBook(name: "Book 10", genre: "Sci-Fi") {
name
id
}
updateBook(name: "Book 10", genre: "Sci-Fi") {
name
id
}
deleteBook(id: ...) {
name
id
}
}
{
"data": {
"name": "Book 10",
"id": "5e56294a4e98b96691966c74"
}
Another important requirement for many applications today is to have a realtime connection to the server in order to get immediately informed about important events. For this use case, GraphQL offers the concept of subscriptions.
When a client subscribes to an event, it will initiate and hold a steady connection to the server. Whenever that particular event then actually happens, the server pushes 🤓 the corresponding data to the client.
Unlike queries and mutations that follow a typical “request-response-cycle”, subscriptions represent a stream of data sent over to the client.
😎
subscription {
newBook {
name
genre
}
}
After a client sent this subscription to a server, a connection is opened between them. Then, whenever a new mutation is performed that creates a new Book, the server sends the information about this book over to the client
{
"newBook": {
"name": "Book 22",
"genre": "Sci-Fi"
}
}
Any Type of Technology
Any Type of DB
Any Structure
Any Location
Construct and send HTTP request (e.g. with fetch in Javascript)
Receive and parse server response store data locally (either simply in memory or persistent)
Display data in the UI