In this post I will give a brief introduction to graphQL.Please go thoroughly with the introduction shared in a short and concise manner below as in the next post we will have a look at actually implementing a server using graphQL in Java.
What is GraphQL?
GraphQL is a new API standard which provides more powerful and flexible alternative to REST.
It
- Enables declarative data fetching (Client can tell exactly what fields to fetch).
- Exposes a single endpoint and responds to queries unlike REST
- It solves below problems :
underfetching: An endpoint doesn't return sufficient information; need to send multiple requests to server
overfetching: Downloading unnecessary data
Let's say you have an entity called product with attributes productId, productname ,price,productSeller
- No need to adjust api if product requirement or design changes
- Fields which are not required by client also easily visible and can be removed if not used
- Graphql has its own type system used to define the schema of an API. Syntax of writing schema is called SDL (schema definition language)
Example:
type Person { type Post {
name:String! title:String!
age:Int! }
}
- You can define relations as below
example for one to many relation
type Person { type Post {
name:String! title:String!
age:Int! author:Person!
posts: [Post!]! }
}
- Fetching data with queries
In below query "allPersons" refer to the root of the query rest is payload of the query
example query 1:
{
allPersons{
name
}
}
example response:
{
"allpersons" [
{ "name" : "foo"},
. { "name" : "bar"}
]
}
eg query 2:
{
allPersons(last:2){
name
}
}
eg query 3:
{
allPersons{
name
posts {
title
}
}
}
- Writing data with mutations
There are 3 types of mutations for creating ,updating ,deleting data
Mutations follow the syntactical structure as query but they need to start with mutation keyword
Example:
mutation {
createPerson(name: "Foo", age: 45) {
name
age
}
}
Sample Server response
{
"createPerson": {
"name" : "foo",
"age" : 45
}
}
Mutation also has a root field ; createPerson is the root field here
- ID is also a data type in graphQL
type Person {
id : ID!
name:String!
age:Int!
posts: [Post!]!
}
Id is uniquely generated by server itself
- Realtime updates with Subscriptions
One requirement of many applications is to stay connected with server to get realtime updates of
important events.
When a client registers with server for a Subscription it is updated in real Realtime
example:
subscription {
newPerson {
name
age
}
}
If some client creates a newPerson , server pushes the event to subscribed clients
- GraphQL schema
1 Schema defines capabilities of an api
2 Represents contract between client and Server
3 Simply a collection of graphQL types with special root types that defines entry point of the API ; these root types are query,mutations,subscription types
Please find a complete schema below for this example:
- Reusability with fragments
Let’s assume we have the following type:
type User {
name: String!
age: Int!
email: String!
street: String!
zipcode: String!
city: String!
}
We can define below fragment:
fragment addressDetails on User {
name
street
zipcode
city
}
now we can use it here like this:
{
allUsers {
... addressDetails
}
}
- Aliases : This will produce an error in graphQL server:
{
User(id: "1") {
name
}
User(id: "2") {
name
}
}
solution is using aliases:
{
first: User(id: "1") {
name
}
second: User(id: "2") {
name
}
}
Response:
{
"first": {
"name": "Alice"
},
"second": {
"name": "Sarah"
}
}
enum Weekday {
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
}
Union types can be used to express that a type should be either of a collection of other types.
They are best understood by means of an example. Let’s consider the following types:
type Adult {
name: String!
work: String!
}
type Child {
name: String!
school: String!
}
Now, we could define a Person type to be the union of Adult and Child:
union Person = Adult | Child
This brings up a different problem: In a GraphQL query where we ask to retrieve information about a Child but only have a Person type to work with, how do we know whether we can actually access this field?
The answer to this is called conditional fragments:
{
allPersons {
name # works for `Adult` and `Child`
... on Child {
school
}
... on Adult {
work
}
}
}
- Schemas
You define schema as below
type Link {
url: String!
description: String!
}
type Query {
allLinks: [Link]
}
schema {
query: Query
}
In the next post we will follow up with the actual java implementation of a server with graphQL
Some important Links:
https://blog.apollographql.com/the-concepts-of-graphql-bc68bd819be3
Comments
Post a Comment