Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
First, the advantage over RESTÂ services
Imaging you have a web app which manages a list of people. Each of them has a few friends. That becomes a âGraphâ which is a CS data-structure term for items linked together with directional or un-directional relations.
If that is for REST API design, I probably have to write quite a few ones like get-people-by-id and get-people-friends-count-by-id and get-people-friends-details-by-id
If you want to get all the data, you either have to make 3 calls to get all these info above or you combine all these 3 things at server end and return back everything no matter what the user asked for. This is what is called over fetching and under fetching
GraphQL solution looks much more elegant. For situation we just need People basic info without any details
query { People(id: 123){ name age }}
For situation we want more info
query { People(id: 123){ name age friendsCount friends{ name age } }}
Even better, we can deep dive to the friends relationship loop hole
query { People(id: 123){ name age friendsCount friends{ name age friends{ name age } } }}
GraphQL basic building blocks: Type, Query, Mutation and Subscription
Type is just like Object or Noun in our human languages. In the example above, People is just a type, it should look like this: (! means itâs required)
type People { id: ID! name: String! age: Int friendsCount: Int friends: [People]}
To describe a list, use the [] syntax just like javascript. Here are more details
Query examples are shown in the paragraph above, itâs just like a type of query language using description way.
Mutation is to update/change/remove/add data based on the types
mutation { addPeople(name: "John Doe" age:21) { id age name }}
Subscriptions are like the pub/sub way in messaging system. In most popular GraphQL server implementations, they are implemented using WebSocket and some solutions that support pub/sub like Redis etcWe can build a chatting app using GraphQL Subscriptions without knowing how itâs implemented under the hood using Websockets, very neat.
The following key points are very easy to overlook but very important
- Type, Query, Mutation and Subscription are defined in the Schema which is like your databaseâs create schema scripts.All of them starts with word `Type`
type Subscription { messageAdded(channelId: ID!): Message}type query{ allPeople: [People]}type mutation{ addPeople(name:String! age:Int): People}
2. In your app client or the client tools like GraphiQL or GraphQL Playground, use commands like query, mutation and subscription.In short, define them using type query type mutation and type subscription first then use them in client
Donât get confused by their client usage syntax and their schema definition syntax as I did before :)
subscription { messageAdded(channelId: 1) { id text }}
3. Query, Mutation and Subscription all can take parameters.It looks like this
query getPhotos($filter:PhotoFilter $page:DataPage $sort:DataSort) { allPhotos(filter:$filter paging:$page sorting:$sort){ ... }}
When I started, I though those addPeople(name:String age:Int) things are parameters, why do we need those $xxx things.Isnât it just like a man wearing double socks?
Actually those $.. things like the getPhotos commands above are for Client and the allPhotos ones are for Server.This does help me to understand the syntax and hope it makes sense to you too.allPhotos(âŠ) will be sent to the server so it can resolve the answer and send back the result.On the Client side (either App client code or GraphiQL tool), you can provide the parameter(input variables) like this below
Notice you can provide the variable in the left-bottom corner of the tool for the $input variable in the mutation statement above.That UserInput! is a Input Type, just another type which is for input variables definitions
4. All the parameter and type elements like the id, username, email, phone listed above are separated by space or new-line but not commas.
Pay attention to the query/mutation statement below, itâs a space, not comma
allPhotos(filter:$filter paging:$page sorting:$sort)
This is very easy to overlook especially the variables part showing above uses commas to separate individual variables
5. Listing all the entries for a type like the id, username, email, phone above can be tedious especially if you have to specify them again and again. So there comes a handy thing called Fragment
fragment userDetails on User { id username email phone ... ...}
Then whenever we need to get User, we can use the fragment
getUser(id: 123){ ...userDetails}
Itâs pretty much like the Javascript ES6 âŠÂ operator
6. Other interesting types.
Union Type is just a combination of different typesIf we have 2 types like StudyGroup and Workout, we can union them
union AgendaItem = StudyGroup | Workout
Then when we query this new type, we can use the special syntax to dynamically get related attributes.
query schedule { agenda { âŠon Workout { name reps } âŠon StudyGroup { name subject students } }}
Interface. itâs like fragment but fragment is for query and mutation, Interface is for type definitions. It just takes the common fields from different types so all those types can share common attributes
interface AgendaItem { name: String! start: DateTime! end: DateTime!}
type StudyGroup implements AgendaItem { name: String! start: DateTime! end: DateTime! participants: [User!]! topic: String!}
type Workout implements AgendaItem { name: String! start: DateTime! end: DateTime! reps: Int!}
GraphQL has a lot of terms and concepts, so here comes my quick reference which I wish I knew them when IÂ started.
For GraphQL server to work, we need to provide Schema and Resolvers
Schema is just all the Type, Query, Mutation and Subscription we talked above. Advanced types are like Enum, Scalar, List, Union, Fragment and Interface
Resolver is the implementation functions to retrieve data for the queries and mutations
For the client side, use query, mutation and subscription For the server side schema definition, use type query type mutation and type subscription
These can also take Variables as input, so you can group variables together to create InputType which is just variable collection definitionsRefer to the GraphiQL screenshot above, that UserInput! is a custom Input Type
The following is an example to use App client code to do similar mutation call like the GraphiQLÂ example
Notice the mutation statement and variables are sent separately just like the GraphiQL sample above.
import { request } from 'graphql-request'
var url = 'http://localhost:4000/graphql'
var mutation = ` mutation populate($count: Int!) { addFakeUsers(count:$count) { id name } }`
var variables = { count: 3 }
request(url, mutation, variables) .then(console.log) .catch(console.error)
It took me quite some time to get over that many terms and understand the nuance between the server definition and the client request syntax.
Hope you find all these helpful and use it to refresh the basic knowledge over time. Cheers and claps :)
GraphQL in 10 minutes. Thing I wish someone told me when I started was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.